]> granicus.if.org Git - esp-idf/blob - make/project.mk
Initial public version
[esp-idf] / make / project.mk
1 #
2 # Main Project Makefile
3 # This Makefile is included directly from the user project Makefile in order to call the Makefiles of all the
4 #   components (in a separate make process) to build all the libraries, then links them together
5 #   into the final file. If so, PWD is the project dir (we assume).
6 #
7
8 #
9 # This Makefile requires the environment variable SDK_PATH to be set to the directory where this
10 # Makefile is located.
11 #
12
13 .PHONY: build-components menuconfig all build clean
14 all: project
15
16 # disable built-in make rules, makes debugging saner
17 MAKEFLAGS +=-rR
18
19 # Figure out PROJECT_PATH if not set, check for unacceptable Makefile entry points
20 ifeq ("$(PROJECT_PATH)","")
21 #The path to the project: we assume the Makefile including this file resides
22 #in the root of that directory.
23 PROJECT_PATH := $(abspath $(dir $(firstword $(MAKEFILE_LIST))))
24 export PROJECT_PATH
25
26 #The directory where we put all objects/libraries/binaries. The project Makefile can
27 #configure this if needed.
28 BUILD_DIR_BASE ?= $(PROJECT_PATH)/build
29
30 #Component directories. These directories are searched for components.
31 #The project Makefile can override these component dirs, or define extra component directories.
32 COMPONENT_DIRS ?= $(PROJECT_PATH)/components $(EXTRA_COMPONENT_DIRS) $(SDK_PATH)/components
33 export COMPONENT_DIRS
34
35 #The project Makefile can define a list of components, but if it does not do this we just take
36 #all available components in the component dirs.
37 ifeq ("$(COMPONENTS)","")
38 #Find all component names. The component names are the same as the
39 #directories they're in, so /bla/components/mycomponent/ -> mycomponent. We later use
40 #the COMPONENT_DIRS bit to find back the component path.
41 COMPONENTS := $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/*))
42 COMPONENTS := $(sort $(foreach comp,$(COMPONENTS),$(lastword $(subst /, ,$(comp)))))
43 endif
44 export COMPONENTS
45
46 #Sources default to only "main"
47 SRCDIRS ?= main
48
49 #Here, we resolve and add all the components and source paths into absolute paths.
50 #If a component exists in multiple COMPONENT_DIRS, we take the first match.
51 #WARNING: These directories paths must be generated WITHOUT a trailing / so we
52 #can use $(notdir x) to get the component name.
53 COMPONENT_PATHS := $(foreach comp,$(COMPONENTS),$(firstword $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/$(comp)))))
54 COMPONENT_PATHS += $(abspath $(SRCDIRS))
55
56 #A component is buildable if it has a Makefile; we assume that a 'make -C $(component dir) build' results in a
57 #lib$(componentname).a. 
58 COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/Makefile),$(cp)))
59
60 # Assemble global list of include dirs (COMPONENT_INCLUDES), and
61 # LDFLAGS args (COMPONENT_LDFLAGS) supplied by each component.
62 #
63 # Also add any inter-component dependencies for each component.
64
65 # Extract a variable from a child make process
66 #
67 # $(1) - path to directory to invoke make in
68 # $(2) - name of variable to print via the getvariable target (passed in GET_VARIABLE)
69 #
70 # needs 'sed' processing of stdout because make sometimes echoes other stuff on stdout,
71 # even if asked not to.
72 #
73 # Debugging this? Replace $(shell with $(error and you'll see the full command as-run.
74 define GetVariable
75 $(shell "$(MAKE)" -s --no-print-directory -C $(1) get_variable COMPONENT_INCLUDES=dummy COMPONENT_LDFLAGS=dummy PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) | sed -En "s/^$(2)=(.+)/\1/p" )
76 endef
77
78 ifeq ("$(COMPONENT_INCLUDES)","")
79 COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(addprefix $(comp)/, \
80         $(call GetVariable,$(comp),COMPONENT_ADD_INCLUDEDIRS))))
81 endif
82
83 #Also add project include path, for sdk includes
84 COMPONENT_INCLUDES += $(PROJECT_PATH)/build/include/
85 export COMPONENT_INCLUDES
86
87 #COMPONENT_LDFLAGS has a list of all flags that are needed to link the components together. It's collected
88 #in the same way as COMPONENT_INCLUDES is.
89 ifeq ("$(COMPONENT_LDFLAGS)","")
90 COMPONENT_LDFLAGS := $(foreach comp,$(COMPONENT_PATHS_BUILDABLE), \
91         $(call GetVariable,$(comp),COMPONENT_ADD_LDFLAGS))
92 export COMPONENT_LDFLAGS
93 endif
94
95 # Generate component dependency targets from dependencies lists
96 # each component gains a target of its own <name>-build with dependencies
97 # of the names of any other components (-build) that need building first
98 #
99 # the actual targets (that invoke submakes) are generated below by
100 # GenerateComponentTarget macro.
101 define GenerateComponentDependencies
102 # $(1) = component path
103 .PHONY: $$(notdir $(1))
104 $$(notdir $(1))-build: $(addsuffix -build,$(call GetVariable,$(1),COMPONENT_DEPENDS))
105 endef
106 $(foreach comp,$(COMPONENT_PATHS_BUILDABLE), $(eval $(call GenerateComponentDependencies,$(comp))))
107
108 #Make sure submakes can also use this.
109 export PROJECT_PATH
110
111 #Include functionality common to both project & component
112 -include $(SDK_PATH)/make/common.mk
113
114 #Set host compiler and binutils
115 HOSTCC := $(CC)
116 HOSTLD := $(LD)
117 HOSTAR := $(AR)
118 HOSTOBJCOPY := $(OBJCOPY)
119
120 #Set target compiler. Defaults to whatever the user has
121 #configured as prefix + yer olde gcc commands
122 CC := $(call dequote,$(CONFIG_TOOLPREFIX))gcc
123 CXX := $(call dequote,$(CONFIG_TOOLPREFIX))c++
124 LD := $(call dequote,$(CONFIG_TOOLPREFIX))ld
125 AR := $(call dequote,$(CONFIG_TOOLPREFIX))ar
126 OBJCOPY := $(call dequote,$(CONFIG_TOOLPREFIX))objcopy
127 export CC CXX LD AR OBJCOPY
128
129 PYTHON=$(call dequote,$(CONFIG_PYTHON))
130
131 PROJECT_ELF:=$(BUILD_DIR_BASE)/$(PROJECT_NAME).elf
132 PROJECT_BIN:=$(PROJECT_ELF:.elf=.bin)
133
134 # Include any Makefile.projbuild file letting components add
135 # configuration at the project level
136 define includeProjBuildMakefile
137 COMPONENT_PATH := $(1)
138 -include $(1)/Makefile.projbuild
139 endef
140 $(foreach componentpath,$(COMPONENT_PATHS),$(eval $(call includeProjBuildMakefile,$(componentpath))))
141
142 # ELF depends on the -build target of every component
143 $(PROJECT_ELF): $(addsuffix -build,$(notdir $(COMPONENT_PATHS_BUILDABLE)))
144         $(vecho) LD $(notdir $@)
145         $(Q) $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(patsubst %.elf,%.map,$@)
146
147 # Generation of $(PROJECT_BIN) from $(PROJECT_ELF) is added by the esptool
148 # component's Makefile.projbuild
149
150 project: $(PROJECT_BIN)
151         @echo "App built. Default flash app command is:"
152         @echo $(PROJECT_FLASH_COMMAND) # PROJECT_FLASH_COMMAND is set in esptool_py's Makefile.projbuild
153
154 $(BUILD_DIR_BASE):
155         mkdir -p $(BUILD_DIR_BASE)
156
157 define GenerateComponentTarget
158 # $(1) - path to component dir
159 # $(2) - target to generate (build, clean)
160 # $(3) - optional dependencies to add
161 .PHONY: $(notdir $(1))-$(2)
162 $(notdir $(1))-$(2): $(3) | $(BUILD_DIR_BASE)/$(notdir $(1))
163         @+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/Makefile COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2)
164 endef
165
166 define GenerateComponentBuildDirTarget
167 # $(1) - path to component dir
168 $(BUILD_DIR_BASE)/$(notdir $(1)):
169         @mkdir -p $(BUILD_DIR_BASE)/$(notdir $(1))
170 endef
171
172 $(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentBuildDirTarget,$(component))))
173
174 $(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTarget,$(component),build,$(PROJECT_PATH)/build/include/sdkconfig.h)))
175 $(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTarget,$(component),clean)))
176
177 include $(SDK_PATH)/make/project_config.mk
178
179 clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(EXTRA_CLEAN_TARGETS)
180         $(vecho) RM $(PROJECT_ELF)
181         $(Q) rm -f $(PROJECT_ELF)
182         $(Q) rm -rf $(PROJECT_PATH)/build/include/config $(PROJECT_PATH)/build/include/sdkconfig.h
183
184 endif
185