啰嗦:越会一件事情,就会忘了不会一件事情的感觉。前段时间在微信上看到这句话,深以为然,这就是为什么很多时候懂的人觉得自己讲的很清楚了,但是不懂的人却觉得并没有讲的清楚明了,简单易懂。以下把自己学习理解的过程记录下来,欢迎大神指点。
1.PX4的makefile当中用到的Makefile语法
本小节给出Makefile文件中使用到部分语法的简单说明,如果想要完全理解、读懂、甚至编写Makefile,需要仔细阅读《GNU Makefile 中文手册》。
:= --直接式变量展开,引用的变量或者函数都会被其定义值替换,如果:= 右端为空,可能是赋值了一个空格;
= 及 define --递归式变量展开,在引用处只是文本替换,在使用时才会展开;
$ --取变量值操作,可以嵌套使用,例如$($(X))。同时可以用于调用内嵌函数:$(FCTION ARGUMENTS);
?= --条件赋值,只有变量尚未被赋值的情况下,才能将?=后边的值赋给变量;
patsubst --模式替换,引用格式:$(patsubst A,B,(VAR)), VAR表示变量,下同,例如:$(patsubst %.c %.o, a.c,b.c);
wildcard --通用符,引用格式如:$(wildcard *.c),当前路径下的所有.c结尾的文件;
+= --追加赋值,VAR定义时给一个基本值,+=就在原来的变量基础上增加一 个赋值,注意不是覆盖;
% --模式字符,例如:%.c 表示后缀为.c模式的文件;
ifeq、ifneq --条件判断关键字;
ifdef、ifndef --条件判断关键字;
// + --命令行前使用+,表示;
subset --字符串替换,例如:$(subst,e,E,feet),结果为:fEEt;
filter --过滤函数,例如:$(filter %.c %.s, $(VAR)),返回VAR中所有后缀为.c,.s的文件;
sort --将字符串升序排列,并去掉重复单词;
word --取单词函数,$(word 1, text),取text的第1个单词;
wordlist --取字符串函数,$(word 1,5, text)表示取text的第1个到第5个单词字串;
words --统计字符串中单词数目;
firstword --取字符串的第一个单词,lastword同理取最后一个单词;
dir --取目录,包含指定文件的路径目录;
basename --取前缀函数,例如 $(basename src/foo.c),返回值为src/foo;
foreach --循环执行;
call --实现用户自定义函数的引用,$(call 函数,参数1,参数2,...);
@echo --在界面上输出build信息;
eval --比较复杂,没看懂,构造一个依赖关系链,其主要功能是根据参 数关系、结构,对它们进行替换展开;
shell --大致功能是将shell的参数放入shell环境中执行并返回结果;
error --$(error TEXT...),返回错误信息并退出执行;
MAKECMDGOALS
-(用户输入的)命令行参数;
$@ -表示规则的目标文件名,一般与改符号上文中的文件相对应,例如前边出现.C,可能默认就是对应的.O文件
2.PX4的makefile编译过程分析
本次编译过程基于Windows下的PX4Toolchain中的PX4 Console模式,方法参考PX4开发手册或网上教程,输入的指令为:
以下是对Makefile原文注解:
- ############################################################################
- #
- # Copyright (c) 2015 - 2017 PX4 Development Team. All rights reserved.
- #
- #部分版权、使用等的申明,此处删去
- #
- ############################################################################
- # Enforce the presence of the GIT repository
- #
- # We depend on our submodules, so we have to prevent attempts to
- # compile without it being present.
- # 强制性保证GIT repository存在,由于于PX4依赖于其子模块,
- # 所以必须防止在缺少子模块的情况下编译,从而有了此处的强制检查
- # $(wildcard .git)用来获取工作路径下所有后缀为.git的文件,执行GIT检查
- # ifeq...endif为条件判断
- ifeq ($(wildcard .git),)
- $(error YOU HAVE TO USE GIT TO DOWNLOAD THIS REPOSITORY. ABORTING.)
- endif
- # Help
- # --------------------------------------------------------------------
- # Don't be afraid of this makefile, it is just passing
- # arguments to cmake to allow us to keep the wiki pages etc.
- # that describe how to build the px4 firmware
- # the same even when using cmake instead of make.
- # 这个Makefile主要是讲怎么传递参数,怎么编译px4固件,同时使用make和cmake是一样的
- # Example usage:三种使用方法示例
- #
- # make px4fmu-v2_default (builds)
- # make px4fmu-v2_default upload (builds and uploads)
- # make px4fmu-v2_default test (builds and tests)
- #
- # This tells cmake to build the nuttx px4fmu-v2 default config in the
- # directory build/nuttx_px4fmu-v2_default and then call make
- # in that directory with the target upload.
- # 以上的命令告诉cmake使用build/nuttx_px4fmu-v2_default的默认配置来build nuttx
- # px4fmu,然后调用该路径下的make来上传target(编译好的文件)
- # 明确设置默认的build目标,编译目标为all,编译规则为posix_sitl_default,如果make不指定编译
- # 目标就会编译默认目标,此处输出的编译目标是px4fmu-v2_default
- all: posix_sitl_default # (默认build就是这个)
- # Parsing 解析
- # --------------------------------------------------------------------
- # assume 1st argument passed is the main target, the
- # rest are arguments to pass to the makefile generated
- # by cmake in the subdirectory
- # 假设第传递的第一个参数是主目标,余下的参数是传输给子路径下的cmake产生的makefile的
- # MAKECMDGOALS 就是输出的命令行参数px4fmu-v2_default
- # FIRST_ARG 变量值就是px4fmu
- FIRST_ARG := $(firstword$(MAKECMDGOALS))
- # ARGS的变量值就是default
- ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
- #如果j为赋值,就将j赋值为4
- j ?= 4
- # ninja赋值给NINJA_BIN,ninja貌似是一套编译工具,在此处没有用到
- NINJA_BIN := ninja
- ifndef NO_NINJA_BUILD
- NINJA_BUILD := $(shell $(NINJA_BIN) --version 2>/dev/null)
- ifndef NINJA_BUILD
- NINJA_BIN:=ninja-build
- NINJA_BUILD := $(shell $(NINJA_BIN) --version 2>/dev/null)
- endif
- endif
- ifdef NINJA_BUILD
- PX4_CMAKE_GENERATOR := Ninja
- PX4_MAKE := $(NINJA_BIN)
- ifdef VERBOSE
- PX4_MAKE_ARGS := -v
- else
- PX4_MAKE_ARGS :=
- endif
- else
- #SYSTEMROOT C:\windows
- ifdef SYSTEMROOT
- # Windows 在windows系统下
- PX4_CMAKE_GENERATOR := "MSYS\ Makefiles"
- #在其余系统下,主要是Linux
- else
- PX4_CMAKE_GENERATOR := "Unix\ Makefiles"
- endif
- #$(MAKE) 其实就是make命令
- PX4_MAKE = $(MAKE)
- #设置编译参数 -j4 --no-print-directory:同一时刻可同时允许执行4行命令,
- #禁止所有关于目录信息的打印
- PX4_MAKE_ARGS = -j$(j) --no-print-directory
- endif
- #firmware所在的文件夹,我的是:/f/px4/firmware
- SRC_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
- # check if replay env variable is set & set build dir accordingly
- # 检查是否定义relay环境变量,并更改build目录的后缀:BUILD_DIR_SUFFIX
- ifdef replay
- BUILD_DIR_SUFFIX := _replay
- else
- BUILD_DIR_SUFFIX :=
- endif
- # additional config parameters passed to cmake
- # 添加额外的配置参数
- ifdef EXTERNAL_MODULES_LOCATION
- CMAKE_ARGS += -DEXTERNAL_MODULES_LOCATION:STRING=$(EXTERNAL_MODULES_LOCATION)
- endif
- ifdef PX4_CMAKE_BUILD_TYPE
- CMAKE_ARGS += -DCMAKE_BUILD_TYPE=${PX4_CMAKE_BUILD_TYPE}
- endif
- # Functions 函数
- # --------------------------------------------------------------------
- # 描述如何build一个cmake配置文件, 定义了cmke-build命令规则
- define cmake-build
- +@$(eval BUILD_DIR =$(SRC_DIR)/build/$@$(BUILD_DIR_SUFFIX))
- +@if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ -e $(BUILD_DIR)/Makefile ]; then rm -rf $(BUILD_DIR); fi
- #以下命令是就是创建build文件夹,用cmake进行编译,然后再删除build文件夹
- #本次编译就是走这个流程,注意这里的cmake编译的应该是CMakelist.txt文件,不是直接的.cmake文件
- #$(2)应该是第二个参数,也就是传递的CMakelist.txt的路径,$(1)应该是传递的编译目标的名称,本次是nuttx_px4fmu-v2_default
- +@if [ ! -e $(BUILD_DIR)/CMakeCache.txt ]; then mkdir -p $(BUILD_DIR) && cd $(BUILD_DIR) && cmake $(2) -G"$(PX4_CMAKE_GENERATOR)" $(CMAKE_ARGS) -DCONFIG=$(1) || (rm -rf $(BUILD_DIR)); fi
- +@(cd $(BUILD_DIR) && $(PX4_MAKE) $(PX4_MAKE_ARGS) $(ARGS))
- endef
- COLOR_BLUE = \033[0;34m
- NO_COLOR = \033[m
- define colorecho
- +@echo "${COLOR_BLUE}${1} ${NO_COLOR}"
- endef
- # Get a list of all config targets cmake/configs/*.cmake
- # 获得所有cmake/configs/下所有的cmake目标文件,
- # 本次编译的nuttx_px4fmu-v2_defualt就是从这里获得
- ALL_CONFIG_TARGETS :=$(basename $(shell find "$(SRC_DIR)/cmake/configs" -maxdepth 1 ! -name '*_common*' ! -name '*_sdflight_*' -name '*.cmake' -print | sed -e 's:^.*/::' | sort))
- # Strip off leading nuttx_
- # 去掉NUTTX_前缀并返回,这样NUTTX_CONFIG_TARGETS就是包含了所有关于NUTTX配置的一个组
- NUTTX_CONFIG_TARGETS := $(patsubst nuttx_%,%,$(filter nuttx_%,$(ALL_CONFIG_TARGETS)))
- # ADD CONFIGS HERE 在此添加配置
- # --------------------------------------------------------------------
- # Do not put any spaces between function arguments.
- # All targets. 所有的目标
- # $(ALL_CONFIG_TARGETS)指代了所有的编译目标,
- # 每个目标都执行$(call cmake-build,$@,$(SRC_DIR))这个命令行
- # 这是一种简便的书写模式
- $(ALL_CONFIG_TARGETS):
- $(call cmake-build,$@,$(SRC_DIR))
- # Abbreviated config targets.
- # nuttx_ is left off by default; provide a rule to allow that. 只和nuttx相关的目标
- # $(NUTTX_CONFIG_TARGETS):指代了所有的编译目标,在本次就是px4fmu-v2_default
- # 每个目标都执行$(call cmake-build,$@,$(SRC_DIR))这个命令行,等价于
- # $(call cmake-build,nuttx_px4fmu-v2_default,/f/px4/firmware),本次编译就是由此处进入到对
- # nuttx_px4fmu-v2_default的编译
- $(NUTTX_CONFIG_TARGETS):
- $(call cmake-build,nuttx_$@,$(SRC_DIR))
- #######################################################################################
- #
- #从此往后的就是一些伪目标,对本次编译来讲不重要,这些伪目标的作用有:
- #1. 如clean执行清除任务,并不生成可执行目标,这种为目标的主要作用是执行命令
- #2. 为了同时创建多个可执行目标,将一个为目标例如all作为终极目标,同时将
- # 其依赖多伪目标
- #
- #######################################################################################
- all_nuttx_targets: $(NUTTX_CONFIG_TARGETS)
- posix: posix_sitl_default
- broadcast: posix_sitl_broadcast
- # All targets with just dependencies but no recipe must either be marked as phony (or have the special @: as recipe).
- # 通过.PHONY将其冒号后的目标申明为伪目标,主要为了防止一些意外情况
- .PHONY: all posix broadcast all_nuttx_targets
- # Multi- config targets. 多目标(板)配置
- eagle_default: posix_eagle_default qurt_eagle_default
- eagle_rtps: posix_eagle_rtps qurt_eagle_default
- eagle_legacy_default: posix_eagle_legacy qurt_eagle_legacy
- excelsior_default: posix_excelsior_default qurt_excelsior_default
- excelsior_rtps: posix_excelsior_rtps qurt_excelsior_default
- excelsior_legacy_default: posix_excelsior_legacy qurt_excelsior_legacy
- .PHONY: eagle_default eagle_rtps eagle_legacy_default
- .PHONY: excelsior_default excelsior_rtps excelsior_legacy_default
- # Other targets
- # --------------------------------------------------------------------
- .PHONY: qgc_firmware px4fmu_firmware misc_qgc_extra_firmware alt_firmware check_rtps
- # QGroundControl flashable NuttX firmware
- qgc_firmware: px4fmu_firmware misc_qgc_extra_firmware
- # px4fmu NuttX firmware
- px4fmu_firmware: \
- check_px4io-v2_default \
- check_px4fmu-v2_default \
- check_px4fmu-v3_default \
- check_px4fmu-v4_default \
- check_px4fmu-v4pro_default \
- check_px4fmu-v5_default \
- sizes
- misc_qgc_extra_firmware: \
- check_aerocore2_default \
- check_aerofc-v1_default \
- check_auav-x21_default \
- check_crazyflie_default \
- check_mindpx-v2_default \
- check_px4fmu-v2_lpe \
- check_tap-v1_default \
- sizes
- # Other NuttX firmware
- alt_firmware: \
- check_nxphlite-v3_default \
- check_px4-same70xplained-v1_default \
- check_px4-stm32f4discovery_default \
- check_px4cannode-v1_default \
- check_px4esc-v1_default \
- check_px4nucleoF767ZI-v1_default \
- check_s2740vc-v1_default \
- sizes
- # builds with RTPS
- check_rtps: \
- check_px4fmu-v3_rtps \
- check_px4fmu-v4_rtps \
- check_px4fmu-v4pro_rtps \
- check_posix_sitl_rtps \
- sizes
- .PHONY: sizes check quick_check check_rtps uorb_graphs
- sizes:
- @-find build -name *.elf -type f | xargs size 2> /dev/null || :
- # All default targets that don't require a special build environment
- check: check_posix_sitl_default px4fmu_firmware misc_qgc_extra_firmware alt_firmware tests check_format
- # quick_check builds a single nuttx and posix target, runs testing, and checks the style
- quick_check: check_posix_sitl_default check_px4fmu-v4pro_default tests check_format
- check_%:
- @echo
- $(call colorecho,"Building" $(subst check_,,$@))
- @$(MAKE) --no-print-directory $(subst check_,,$@)
- @echo
- uorb_graphs:
- @./Tools/uorb_graph/create_from_startupscript.sh
- @./Tools/uorb_graph/create.py --src-path src --exclude-path src/examples --file Tools/uorb_graph/graph_full
- @$(MAKE) --no-print-directory px4fmu-v2_default uorb_graph
- @$(MAKE) --no-print-directory px4fmu-v4_default uorb_graph
- @$(MAKE) --no-print-directory posix_sitl_default uorb_graph
- .PHONY: coverity_scan
- coverity_scan: posix_sitl_default
- # Documentation
- # --------------------------------------------------------------------
- .PHONY: parameters_metadata airframe_metadata module_documentation px4_metadata
- parameters_metadata:
- @python $(SRC_DIR)/src/modules/systemlib/param/px_process_params.py -s `find $(SRC_DIR)/src -maxdepth 4 -type d` --inject-xml $(SRC_DIR)/src/modules/systemlib/param/parameters_injected.xml --markdown
- @python $(SRC_DIR)/src/modules/systemlib/param/px_process_params.py -s `find $(SRC_DIR)/src -maxdepth 4 -type d` --inject-xml $(SRC_DIR)/src/modules/systemlib/param/parameters_injected.xml --xml
- airframe_metadata:
- @python $(SRC_DIR)/Tools/px_process_airframes.py -v -a $(SRC_DIR)/ROMFS/px4fmu_common/init.d --markdown
- @python $(SRC_DIR)/Tools/px_process_airframes.py -v -a $(SRC_DIR)/ROMFS/px4fmu_common/init.d --xml
- module_documentation:
- @python $(SRC_DIR)/Tools/px_process_module_doc.py -v --markdown $(SRC_DIR)/modules --src-path $(SRC_DIR)/src
- px4_metadata: parameters_metadata airframe_metadata module_documentation
- # Astyle
- # --------------------------------------------------------------------
- .PHONY: check_format format
- check_format:
- $(call colorecho,"Checking formatting with astyle")
- @$(SRC_DIR)/Tools/astyle/check_code_style_all.sh
- @cd $(SRC_DIR) &&git diff --check
- format:
- $(call colorecho,"Formatting with astyle")
- @$(SRC_DIR)/Tools/astyle/check_code_style_all.sh --fix
- # Testing
- # --------------------------------------------------------------------
- .PHONY: tests tests_coverage tests_mission tests_offboard rostest
- tests:
- @$(MAKE) --no-print-directory posix_sitl_default test_results \
- ASAN_OPTIONS="color=always:check_initialization_order=1:detect_stack_use_after_return=1" \
- UBSAN_OPTIONS="color=always"
- tests_coverage:
- @$(MAKE) clean
- @$(MAKE) --no-print-directory posix_sitl_default PX4_CMAKE_BUILD_TYPE=Coverage
- @$(MAKE) --no-print-directory posix_sitl_default sitl_gazebo PX4_CMAKE_BUILD_TYPE=Coverage
- @$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_missions.test
- @$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_attctl.test
- @$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_posctl.test
- @$(MAKE) --no-print-directory posix_sitl_default test_coverage_genhtml PX4_CMAKE_BUILD_TYPE=Coverage
- @echo "Open $(SRC_DIR)/build/posix_sitl_default/coverage-html/index.html to see coverage"
- rostest: posix_sitl_default
- @$(MAKE) --no-print-directory posix_sitl_default sitl_gazebo
- tests_mission: rostest
- @$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_missions.test
- tests_offboard: rostest
- @$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_attctl.test
- @$(SRC_DIR)/test/rostest_px4_run.sh mavros_posix_tests_offboard_posctl.test
- # static analyzers (scan-build, clang-tidy, cppcheck)
- # --------------------------------------------------------------------
- .PHONY: scan-build posix_sitl_default-clang clang-tidy clang-tidy-fix clang-tidy-quiet cppcheck check_stack
- scan-build:
- @export CCC_CC=clang
- @export CCC_CXX=clang++
- @rm -rf $(SRC_DIR)/build/posix_sitl_default-scan-build
- @rm -rf $(SRC_DIR)/build/scan-build/report_latest
- @mkdir -p $(SRC_DIR)/build/posix_sitl_default-scan-build
- @cd $(SRC_DIR)/build/posix_sitl_default-scan-build && scan-build cmake $(SRC_DIR) -GNinja -DCONFIG=posix_sitl_default
- @scan-build -o $(SRC_DIR)/build/scan-build cmake --build $(SRC_DIR)/build/posix_sitl_default-scan-build
- @find $(SRC_DIR)/build/scan-build -maxdepth 1 -mindepth 1 -type d -exec cp -r "{}" $(SRC_DIR)/build/scan-build/report_latest \;
- posix_sitl_default-clang:
- @mkdir -p $(SRC_DIR)/build/posix_sitl_default-clang
- @cd $(SRC_DIR)/build/posix_sitl_default-clang && cmake $(SRC_DIR) $(CMAKE_ARGS) -G"$(PX4_CMAKE_GENERATOR)" -DCONFIG=posix_sitl_default -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
- @$(PX4_MAKE) -C $(SRC_DIR)/build/posix_sitl_default-clang
- clang-tidy: posix_sitl_default-clang
- @cd $(SRC_DIR)/build/posix_sitl_default-clang && $(SRC_DIR)/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j) -p .
- # to automatically fix a single check at a time, eg modernize-redundant-void-arg
- # % run-clang-tidy-4.0.py -fix -j4 -checks=-\*,modernize-redundant-void-arg -p .
- clang-tidy-fix: posix_sitl_default-clang
- @cd $(SRC_DIR)/build/posix_sitl_default-clang && $(SRC_DIR)/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j) -fix -p .
- # modified version of run-clang-tidy.py to return error codes and only output relevant results
- clang-tidy-quiet: posix_sitl_default-clang
- @cd $(SRC_DIR)/build/posix_sitl_default-clang && $(SRC_DIR)/Tools/run-clang-tidy.py -header-filter=".*\.hpp" -j$(j) -p .
- # TODO: Fix cppcheck errors then try --enable=warning,performance,portability,style,unusedFunction or --enable=all
- cppcheck: posix_sitl_default
- @mkdir -p $(SRC_DIR)/build/cppcheck
- @cppcheck -i$(SRC_DIR)/src/examples --enable=performance --std=c++11 --std=c99 --std=posix --project=$(SRC_DIR)/build/posix_sitl_default/compile_commands.json --xml-version=2 2> $(SRC_DIR)/build/cppcheck/cppcheck-result.xml > /dev/null
- @cppcheck-htmlreport --source-encoding=ascii --file=$(SRC_DIR)/build/cppcheck/cppcheck-result.xml --report-dir=$(SRC_DIR)/build/cppcheck --source-dir=$(SRC_DIR)/src/
- check_stack: px4fmu-v4pro_default
- @echo "Checking worst case stack usage with checkstack.pl ..."
- @echo " "
- @echo "Top 10:"
- @cd $(SRC_DIR)/build/px4fmu-v4pro_default && mkdir -p stack_usage && arm-none-eabi-objdump -d nuttx_px4fmu-v4pro_default.elf | $(SRC_DIR)/Tools/stack_usage/checkstack.pl arm 0 > stack_usage/checkstack_output.txt 2> stack_usage/checkstack_errors.txt
- @head -n 10 $(SRC_DIR)/build/px4fmu-v4pro_default/stack_usage/checkstack_output.txt | c++filt
- @echo " "
- @echo "Symbols with 'main', 'thread' or 'task':"
- @cat $(SRC_DIR)/build/px4fmu-v4pro_default/stack_usage/checkstack_output.txt | c++filt | grep -E 'thread|main|task'
- # Cleanup
- # --------------------------------------------------------------------
- .PHONY: clean submodulesclean submodulesupdate gazeboclean distclean
- clean:
- @rm -rf $(SRC_DIR)/build
- submodulesclean:
- @git submodule foreach --quiet --recursive git clean -ff -x -d
- @git submodule update --quiet --init --recursive --force || true
- @git submodule sync --recursive
- @git submodule update --init --recursive --force
- submodulesupdate:
- @git submodule update --quiet --init --recursive || true
- @git submodule sync --recursive
- @git submodule update --init --recursive
- gazeboclean:
- @rm -rf ~/.gazebo/*
- distclean: gazeboclean
- @git submodule deinit -f .
- @git clean -ff -x -d -e ".project" -e ".cproject" -e ".idea" -e ".settings" -e ".vscode"
- # --------------------------------------------------------------------
- # All other targets are handled by PX4_MAKE. Add a rule here to avoid printing an error.
- %:
- $(if $(filter $(FIRST_ARG),$@), \
- $(error"$@ cannot be the first argument. Use '$(MAKE) help|list_config_targets' to get a list of all possible [configuration] targets."),@#)
- #help:
- # @echo
- # @echo "Type 'make ' and hit the tab key twice to see a list of the available"
- # @echo "build configurations."
- # @echo
- empty :=
- space := $(empty) $(empty)
- # Print a list of non-config targets (based on http://stackoverflow.com/a/26339924/1487069)
- help:
- @echo "Usage: $(MAKE) <target>"
- @echo "Where <target> is one of:"
- @echo
- @echo "Or, $(MAKE) <config_target> [<make_target(s)>]"
- @echo "Use '$(MAKE) list_config_targets' for a list of configuration targets."
- @echo "$()"
- # Print a list of all config targets.
- list_config_targets:
- @for targ in $(patsubst nuttx_%,[nuttx_]%,$(ALL_CONFIG_TARGETS));do echo $$targ;done
在默认的Makefile添加以下函数,可以将Makefile中变量值打印出来,更加清晰的查看Makefile的配置和运行过程:
- .PHONY:VARValue
- VARValue:
- @echo "$(MAKEFILE_LIST)"
- @echo "$(MAKECMDGOALS)"
- @echo "$(SRC_DIR)"
- @echo "$(PX4_MAKE)"
- @echo "$(PX4_CMAKE_GENERATOR)"
- @echo "$(SYSTEMROOT)"
- @echo "$(PX4_MAKE_ARGS)"
- @echo "$(ALL_CONFIG_TARGETS)"
- @echo "$(NUTTX_CONFIG_TARGETS)"
结果为:
接下来应该是编译:F:\px4\Firmware\CMakeLists.txt文件
——Eidted By RobotBrain.M LESS BUT BETTER.