参考make语法
默认目标
all: px4_sitl_default
目标的生成
可以操作的目标很多,以px4平台为例:
boards/px4/raspberrypi/default.px4board
boards/px4/fmu-v6u/bootloader.px4board
boards/px4/fmu-v6u/default.px4board
boards/px4/fmu-v4pro/test.px4board
boards/px4/fmu-v4pro/default.px4board
boards/px4/io-v2/default.px4board
boards/px4/fmu-v3/test.px4board
boards/px4/fmu-v3/default.px4board
boards/px4/fmu-v5/uavcanv0periph.px4board
boards/px4/fmu-v5/rtps.px4board
boards/px4/fmu-v5/cryptotest.px4board
boards/px4/fmu-v5/cyphal.px4board
boards/px4/fmu-v5/test.px4board
boards/px4/fmu-v5/stackcheck.px4board
boards/px4/fmu-v5/protected.px4board
boards/px4/fmu-v5/default.px4board
boards/px4/fmu-v5/lto.px4board
boards/px4/fmu-v5/debug.px4board
boards/px4/fmu-v2/multicopter.px4board
boards/px4/fmu-v2/rover.px4board
boards/px4/fmu-v2/fixedwing.px4board
boards/px4/fmu-v2/default.px4board
boards/px4/fmu-v2/lto.px4board
boards/px4/fmu-v4/rtps.px4board
boards/px4/fmu-v4/test.px4board
boards/px4/fmu-v4/default.px4board
boards/px4/fmu-v6x/bootloader.px4board
boards/px4/fmu-v6x/default.px4board
boards/px4/fmu-v5x/rtps.px4board
boards/px4/fmu-v5x/test.px4board
boards/px4/fmu-v5x/default.px4board
boards/px4/sitl/rtps.px4board
boards/px4/sitl/test.px4board
boards/px4/sitl/replay.px4board
boards/px4/sitl/nolockstep.px4board
boards/px4/sitl/default.px4board
boards/px4/fmu-v6c/bootloader.px4board
boards/px4/fmu-v6c/default.px4board
通过代码
$(shell find boards -maxdepth 3 -mindepth 3 -name '*.px4board' -print | sed -e 's|boards\/||' | sed -e 's|\.px4board||' | sed -e 's|\/|_|g' | sort)
处理,得到
px4_raspberrypi_default
px4_fmu-v6u_bootloader
px4_fmu-v6u_default
px4_fmu-v4pro_test
px4_fmu-v4pro_default
px4_io-v2_default
px4_fmu-v3_test
px4_fmu-v3_default
px4_fmu-v5_uavcanv0periph
px4_fmu-v5_rtps
px4_fmu-v5_cryptotest
px4_fmu-v5_cyphal
px4_fmu-v5_test
px4_fmu-v5_stackcheck
px4_fmu-v5_protected
px4_fmu-v5_default
px4_fmu-v5_lto
px4_fmu-v5_debug
px4_fmu-v2_multicopter
px4_fmu-v2_rover
px4_fmu-v2_fixedwing
px4_fmu-v2_default
px4_fmu-v2_lto
px4_fmu-v4_rtps
px4_fmu-v4_test
px4_fmu-v4_default
px4_fmu-v6x_bootloader
px4_fmu-v6x_default
px4_fmu-v5x_rtps
px4_fmu-v5x_test
px4_fmu-v5x_default
px4_sitl_rtps
px4_sitl_test
px4_sitl_replay
px4_sitl_nolockstep
px4_sitl_default
px4_fmu-v6c_bootloader
px4_fmu-v6c_default
上述代码处理的逻辑:
- 查找board目录下扩展名为px4board的文件:
find boards -maxdepth 3 -mindepth 3 -name '*.px4board' -print
。 - 去掉目录名board:
sed -e 's|boards\/||'
- 去掉扩展名px4board:
sed -e 's|\.px4board||'
- 将‘/’替换为‘_’:
sed -e 's|\/|_|g'
- 排序 :
sort
最终形成上述结果。
然后存储在变量ALL_CONFIG_TARGET
中,并生成目标:
231 $(ALL_CONFIG_TARGETS):
232 @$(call cmake-build,$@$(BUILD_DIR_SUFFIX))
至此,make target
的target生成完毕。
进一步处理了一下
235 CONFIG_TARGETS_DEFAULT := $(patsubst %_default,%,$(filter %_default,$(ALL_CONFIG_TARGETS)))
236 $(CONFIG_TARGETS_DEFAULT):
237 @$(call cmake-build,$@_default$(BUILD_DIR_SUFFIX))
将ALL_CONFIG_TARGETS
过滤了一下,只保留包含default的结果,又生成一组target。
这一步的意义在于,如果输入 make px4_fmu_v2
,就会默认匹配到 make px4_fmu_v2_default
规则上。
目标如何编译
231 $(ALL_CONFIG_TARGETS):
232 @$(call cmake-build,$@$(BUILD_DIR_SUFFIX))
236 $(CONFIG_TARGETS_DEFAULT):
237 @$(call cmake-build,$@_default$(BUILD_DIR_SUFFIX))
例如:make px4_fmu-v2_default,就会调用 cmake-build, px4_fmu-v2_default。
180 # Functions
181 # --------------------------------------------------------------------
182 # describe how to build a cmake config
183 define cmake-build
184 $(eval override CMAKE_ARGS += -DCONFIG=$(1))
185 @$(eval BUILD_DIR = "$(SRC_DIR)/build/$(1)")
186 @# check if the desired cmake configuration matches the cache then CMAKE_CACHE_CHECK stays empty
187 @$(call cmake-cache-check)
188 @# make sure to start from scratch when switching from GNU Make to Ninja
189 @if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ -e $(BUILD_DIR)/Makefile ]; then rm -rf $(BUILD_DIR); fi
190 @# make sure to start from scratch if ninja build file is missing
191 @if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ ! -f $(BUILD_DIR)/build.ninja ]; then rm -rf $(BUILD_DIR); fi
192 @# only excplicitly configure the first build, if cache file already exists the makefile will rerun cmake automatically if necessary
193 @if [ ! -e $(BUILD_DIR)/CMakeCache.txt ] || [ $(CMAKE_CACHE_CHECK) ]; then \
194 mkdir -p $(BUILD_DIR) \
195 && cd $(BUILD_DIR) \
196 && cmake "$(SRC_DIR)" -G"$(PX4_CMAKE_GENERATOR)" $(CMAKE_ARGS) \
197 || (rm -rf $(BUILD_DIR)); \
198 fi
199 @# run the build for the specified target
200 @cmake --build $(BUILD_DIR) -- $(PX4_MAKE_ARGS) $(ARGS)
201 endef
202
203 # check if the options we want to build with in CMAKE_ARGS match the ones which are already configured in the cache inside BUILD_DIR
204 define cmake-cache-check
205 @# change to build folder which fails if it doesn't exist and CACHED_CMAKE_OPTIONS stays empty
206 @# fetch all previously configured and cached options from the build folder and transform them into the OPTION=VALUE format without type (e.g. :BOOL)
207 @$(eval CACHED_CMAKE_OPTIONS = $(shell cd $(BUILD_DIR) 2>/dev/null && cmake -L 2>/dev/null | sed -n 's|\([^[:blank:]]*\):[^[:blank:]]*\(=[^[:blank:]]*\)|\1\2|gp' ))
208 @# transform the options in CMAKE_ARGS into the OPTION=VALUE format without -D
209 @$(eval DESIRED_CMAKE_OPTIONS = $(shell echo $(CMAKE_ARGS) | sed -n 's|-D\([^[:blank:]]*=[^[:blank:]]*\)|\1|gp' ))
210 @# find each currently desired option in the already cached ones making sure the complete configured string value is the same
211 @$(eval VERIFIED_CMAKE_OPTIONS = $(foreach option,$(DESIRED_CMAKE_OPTIONS),$(strip $(findstring $(option)$(space),$(CACHED_CMAKE_OPTIONS)))))
212 @# if the complete list of desired options is found in the list of verified options we don't need to reconfigure and CMAKE_CACHE_CHECK stays empty
213 @$(eval CMAKE_CACHE_CHECK = $(if $(findstring $(DESIRED_CMAKE_OPTIONS),$(VERIFIED_CMAKE_OPTIONS)),,y))
214 endef
关键逻辑
BUILD_DIR = "$(SRC_DIR)/build/$(1)"
mkdir -p $(BUILD_DIR) && cd $(BUILD_DIR) && cmake "$(SRC_DIR)" -G"$(PX4_CMAKE_GENERATOR)" $(CMAKE_ARGS)
cmake --build $(BUILD_DIR) -- $(PX4_MAKE_ARGS) $(ARGS)
即 ```cmake -G 然后 cmake --build。
CMAKE_ARGS += -DCONFIG=$(1) 这里将Makefile中选中的配置,传递给CMake去处理,比如px4_fmu-v2_default
。