Makefile

参考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

上述代码处理的逻辑:

  1. 查找board目录下扩展名为px4board的文件:find boards -maxdepth 3 -mindepth 3 -name '*.px4board' -print
  2. 去掉目录名board:sed -e 's|boards\/||'
  3. 去掉扩展名px4board:sed -e 's|\.px4board||'
  4. 将‘/’替换为‘_’:sed -e 's|\/|_|g'
  5. 排序 : 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容