Last active
March 14, 2020 21:31
-
-
Save je-so/5614757 to your computer and use it in GitHub Desktop.
Generic Makefile For C Projects. Supports different building modes (Debug and Release preconfigured).
Supports building mode specific configurations.
C source code dependencies are computed automatically by the compiler and included into the makefile.
All object files are put under directory $(TargetDir)/$(buildmode)/$(Project)/.
Makefile suppor…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generic Makefile (c) 2013 Jörg Seebohn | |
# Version 1.0 | |
# Use it at your own risk ! | |
# This Makefile depends on GNU make. | |
# The clean command uses "@echo rm -rf $(TargetDir)" | |
# remove the echo if you know that $(TargetDir) is set to a valid value. | |
# The target test builds the project in Release mode and starts it. | |
# Adapt project specific part to your own project. | |
# Adapt compiler specific part to your own compiler. | |
# Compiler gcc is preconfigured. | |
# Mode specific values are added after the mode agnostic values. | |
# The generated binary is stored as $(TargetDir)/$(Project)_$(buildmode) | |
# except for the Release binary. It is named $(TargetDir)/$(Project). | |
# You can change the location by changing macro TargetFilename. | |
# The object files are stored in directory $(TargetDir)/$(buildmode)/$(Project) | |
# You can change the location by changing ObjectFilename | |
# Variable "Modes" contains the list of build modes. Add your own mode with "Modes += mymode" if you like and add | |
# additional compiler and linker flags with "CFlags_mymode := " and "LFlags_mymode := ". | |
######################### | |
# Project Specific Part # | |
######################### | |
Project := your_project_name | |
Modes := Debug Release | |
# Directory where target binary is created and object files | |
TargetDir := bin | |
# Search Path For Include Files (InclPaths is included before mode specific InclPaths_MODE) | |
InclPaths := . | |
InclPaths_Debug := | |
InclPaths_Release := | |
# Defined values used by C preprocessor (Defines is included before mode specific Defines_MODE) | |
Defines := CONFIG_UNITTEST=1 | |
Defines_Debug := DEBUG | |
Defines_Release := RELEASE | |
# List of Library Names (Libs is included before mode specific Libs_MODE) | |
Libs := | |
Libs_Debug := | |
Libs_Release := | |
# Search Paths for Libraries (LibPaths is included before mode specific LibPaths_MODE) | |
LibPaths := | |
LibPaths_Debug := | |
LibPaths_Release := | |
# Compiler specific flags (CFlags is included before mode specific CFlags_MODE) | |
CFlags := -std=c99 -pedantic -Wall -Wextra -Wconversion -Wshadow -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wformat-nonliteral -Wformat-y2k | |
CFlags_Debug := -g | |
CFlags_Release := -O2 | |
# Linker specific flags (LFlags is included before mode specific LFlags_MODE) | |
LFlags := | |
LFlags_Debug := -g | |
LFlags_Release := -O2 | |
# Add Your Source file here | |
# Use $(wildcard dir/*.c) if you want to include files from directory 'dir' | |
Src := src/test.c | |
Src += src/cmsg.c | |
########################## | |
# Compiler Specific Part # | |
########################## | |
IncPathFlag := -I | |
DefineFlag := -D | |
LibraryFlag := -l | |
LibPathFlag := -L | |
# -MMD flag let gcc generate a dependency file "objectfilename.d" in addition to the object file "objectfilename.o" | |
CC := gcc -MMD | |
LD := gcc | |
######################### | |
# Generic Template Part # | |
######################### | |
all: $(Modes) | |
clean: | |
@echo clean: $(Project) | |
@echo rm -rf $(TargetDir) | |
test: Release | |
$(call TargetFilename,Release) | |
$(Modes:%=clean_%): | |
@echo rm -rf $(TargetDir)/$(subst clean_,,$@)/$(Project)/ | |
$(Modes:%=init_%): | |
@mkdir -p $(TargetDir)/$(subst init_,,$@)/$(Project) | |
define TargetFilename | |
$(TargetDir)/$(Project)$(subst _Release,,_$(1)) | |
endef | |
define ObjectFilename | |
$(TargetDir)/$(1)/$(Project)/$(subst /,!,$(2)).o | |
endef | |
define CompileObject | |
$(call ObjectFilename,$(1),$(2)): $(2) | |
@echo cc: '$$<' | |
@$$(CC_$(1)) -c -o '$$@' '$$<' | |
endef | |
define TargetTemplate | |
CC_$(1) := $(CC) $(Defines:%=$(DefineFlag)%) $$(Defines_$(1):%=$(DefineFlag)%) $(InclPaths:%=$(IncPathFlag)%) $$(InclPaths_$(1):%=$(IncPathFlag)%) $(CFlags) $$(CFlags_$(1)) | |
Objects_$(1) := $(foreach file,$(Src),$(call ObjectFilename,$(1),$(file))) | |
$(1): init_$(1) $(call TargetFilename,$(1)) | |
$(call TargetFilename,$(1)): $$(Objects_$(1)) | |
@echo ld: '$$@' | |
@$(LD) $(LFlags) $$(LFlags_$(1)) -o '$$@' $$(^:%='%') $(LibPaths:%=$(LibPathFlag)%) $$(LibPaths_$(1):%=$(LibPathFlag)%) $(Libs:%=$(LibraryFlag)%) $$(Libs_$(1):%=$(LibraryFlag)%) | |
$(foreach file,$(Src),$(eval $(call CompileObject,$(1),$(file)))) | |
# Include compiler generated dependency files | |
-include $$(Objects_$(1):.o=.d) | |
endef | |
$(foreach mode,$(Modes),$(eval $(call TargetTemplate,$(mode)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment