(Embedded real-time operating system rtos nuttx 7.1 makefile)
See the Source: http://blog.csdn.net/zhumaill/article/details/24400441
1 Overview
NuttX is compiled by Makefile. The Makefile file describes the compilation and linking rules of the entire NuttX project, and tells make what files to compile, how to compile, and under what conditions. NuttX does not use automated compilation tools such as Autoconf, Automake, CMake, and SCons. Its Makefile files are completely compiled manually, which is easier to read than the compilation files used by automated compilation tools, it is easier to understand the software compilation process. The answer is: try to make things simple in one way, but the results make things more complex.
2. Makefile file structure
- Nuttx/Makefile: the top-level Makefile file. The content is very simple. According to the host environment, the conditions include Makefile. unix or Makefile. win.
- Nuttx/Makefile. unix: Makefile in Linux.
- Nuttx/Makefile. win: Makefile in Windows.
- Nuttx/Make. defs: copied from nuttx/config/<board>/<target configuration>/Make. defs.
- Makefile, Make. defs, and Make. dep in subdirectories of different levels.
3. Makefile file inclusion tree
(The top-level directory is nuttx)
'| <--. Config | <--. config | <-- tools/Config. mk | <-- Makefile. unix-| Makefile-| <--. config | <-- Make. defs-| <-- tools/Config. mk | <-- arch/arm/src/armv7-m/Toolchain. defs | <-- Makefile. win-(omitted)
As you can see, the. config file generated in the "nuttx Configuration System" is included in the Makefile file.
Makefile, Make. defs, and Make. dep in subdirectories are not included through include, but called when the make command in Makefile is executed.
4 build goals and option 4.1 Build goals:
The following is an overview of the Build targets available in the top-level Makefile file:
All
The default target is to build the NuttX executable file in the selected output format.
Clean
Removes derived object files, static library files, executable files, and temporary files, but retains the configuration and context files and directories. The Make. dep file is also retained.
Distclean
In addition to "clean", it also includes removing all configuration and context files. The essence is to restore the directory structure to its original, unconfigured state.
4.2 Internal Affairs targets of applications
The APPDIR variable references the user application directory. For example, the app/directory contained in NuttX. However, this is not considered a part of NuttX and can be replaced by a different application directory. In most cases, the application directory is seen in the Makefile script as any other build directory. However, for convenience, the following goals are included to support the housekeeping function in the user application directory built from the NuttX directory.
Pai_clean
Only clean the user application directory.
Pai_distclean
Only perform the distclean operation on the user application directory. The apps/. config file is retained, so it is not completely distclean, but it is more than configuration reset.
Export
The export target will package the NuttX library and header file to the output package. Note: (1) perform some extensions on the KERNEL build. (2) The logic in tools/mkexport. sh only supports GCC. For example, it is explicitly assumed that the static library generator is "ar ".
Download
This is an assistant target. It will re-build and download it to the target system, just one step. The operation of this target relies entirely on the implementation of the DOWNLOAD command in the user Make. defs file. If the DOWNLOAD command is not defined, it will generate an error.
4.3 internal objectives
The following goals are used internally by the make logic, but can be called from the command line under certain conditions if necessary.
Depend
Create a dependency and generate the Make. dep file and. depend file. (Note: currently, dependency building is not supported in Cygwin with Windows Local tool chain)
Context
Call the context target every time the target is built to ensure that the NuttX is correctly configured. The basic configuration steps include creating the config. h and version. h header files in the include/nuttx directory, and creating a symbolic link to the configuration directory.
Clean_context
This is part of the distclean target. It removes all header files and symbolic links created by the context target.
4.4 build options
Of course, the value of any make variable can be overwritten by the command line. However, there is a special variable assignment option that may be very useful to you:
V = 1
This is the detailed level sign generated. If you specify V = 1 on the command line, you will see the exact command used during the build. It may be useful when you add new boards or track compilation errors and warnings.
5. all target dependency tree
'| <-- Pass1dep-| <---------------------------------------- signature | <-- pass1deps-| <-- tools/mkdeps $ (HOSTEXEEXT) | empty -- empty | <-- $ (USERLIBS) (empty when building a plane) | <-- pass2dep-| <--------------------------------------- | <--- pass2deps-| <-- tools/mkdeps $ (HOSTEXEEXT) | <-- $ (NUTTXLIBS) (configuration-related) <-- messages | certificate ------------------------------------- certificate | <-- lib/libsched $ (LIBEXT) <-- sched/libsched $ (LIBEXT) <-------- | <-- lib/libc $ (LIBEXT) <-- libc/libc $ (LIBEXT) <----------------- | <-- lib/libmm $ (LIBEXT) <-- mm/libmm $ (LIBEXT) <--------------- | all <-- $ (BIN) -| <-- lib/libarch $ (LIBEXT) <-- $ (ARCH_SRC)/libarch $ (LIBEXT) <---- | <-- lib/libcxx $ (LIBEXT) <-- libxx/libcxx $ (LIBEXT) <------------ | <-- lib/libapps $ (LIBEXT) <-- $ (APPDIR)/libapps $ (LIBEXT) <------ | <-- lib/libnet $ (LIBEXT) <-- net/libnet $ (LIBEXT) <-------------- | <-- lib/libfs $ (LIBEXT) <-- fs/libfs $ (LIBEXT) <----------------- | <-- lib/libdrivers $ (LIBEXT) <-- drivers/libdrivers $ (LIBEXT) <-- | <-- lib/libbinfmt $ (LIBEXT) <-- binfmt/libbinfmt $ (LIBEXT) <----- | certificate --------- certificate | certificate -------- certificate | <-- pass1 <-- certificate | <-- pass2 <------ signature | certificate ----------------------------------------------------------------------------- signature | <-- check_context | <-- include/nuttx/config. h-| <-- $ (TOPDIR )/. config | <-- tools/mkconfig $ (HOSTEXEEXT) | <-- include/nuttx/version. h-| <-- $ (TOPDIR )/. version | <-- tools/mkversion $ (HOSTEXEEXT) | <-- context-| <-- include/math. h <-- include/nuttx/math. h | <-- include/float. h <-- include/nuttx/float. h | <-- include/stdarg. h <-- include/nuttx/stdarg. h | <-- include/arch <-Make. defs | <-- include/arch/board-| <-- include/arch <-- Make. defs | <-- Make. defs | <-- dirlinks-| <-- include/arch/chip-| <-- include/arch <-- Make. defs | <-- Make. defs | <-- $ (ARCH_SRC)/board <-- Make. defs | <-- $ (ARCH_SRC)/chip <-- Make. defs | <-- include/apps <-- Make. defs
6. all goals: 6.1 context goals in the compilation process
Because the all target is the default target, execute the make command without parameters to compile the all target. First, compile the context target. config file generation config. h. Many C files contain config. h To get the user configuration. Note that two soft links to the directory are used below:
$ (ARCH_SRC)/board:
Link the directory nuttx/configs/shenzhou/src to the directory nuttx/arch/arm/src/board.
$ (ARCH_SRC)/chip:
Link the directory of nuttx/arch/arm/src/stm32 to the directory of nuttx/arch/arm/src/chip.
However, because make context has been executed once when buildroot is installed, and executing make clean will not delete the files generated by the context target, this step does not do anything.
6.2 pass1dep target
pass1dep: context tools/mkdeps$(HOSTEXEEXT) $(Q) for dir in $(USERDEPDIRS) ; do \ $(MAKE) -C $$dir TOPDIR="$(TOPDIR)" depend ; \ done
Flat Construction refers to compiling NuttX into a single binary file. All components built are in the same address space and all components can access all other components. When constructing a plane, $ (USERDEPDIRS) is empty, and it does nothing.
6.3 $ (USERLIBS) Target
$ (USERLIBS) is empty when a plane is built, and it does nothing. In this way, the entire pass1deps target is completed.
6.4 pass2dep target
pass2dep: context tools/mkdeps$(HOSTEXEEXT) $(Q) for dir in $(KERNDEPDIRS) ; do \ $(MAKE) -C $$dir TOPDIR="$(TOPDIR)" EXTRADEFINES=$(KDEFINE) depend; \ done
Generate the Make. dep and. depend files under subdirectories of all levels based on the value of the $ (KERNDEPDIRS) variable.
The subdirectories that generate the Make. dep and. depend files under the nuttx directory include:
- Nuttx/arch/arm/src
- Nuttx/binfmt
- Nuttx/configs/shenzhou/src
- Nuttx/drivers
- Nuttx/fs
- Nuttx/libc
- Nuttx/libxx
- Nuttx/mm
- Nuttx/net
- Nuttx/sched
6.5 $ (NUTTXLIBS) Target
Next, compile $ (NUTTXLIBS) in the pass2deps target. This is a multi-objective. The specific objectives vary according to the configuration. It generates multiple static library files. 10 static library files are generated here:
- Nuttx/lib/libapps.
- Nuttx/lib/libarch.
- Nuttx/lib/libbinfmt.
- Nuttx/lib/libc.
- Nuttx/lib/libcxx.
- Nuttx/lib/libdrivers.
- Nuttx/lib/libfs.
- Nuttx/lib/libmm.
- Nuttx/lib/libnet.
- Nuttx/lib/libsched.
The following uses libarch. a as an example to examine the compilation process of the static library.
$(ARCH_SRC)/libarch$(LIBEXT): context $(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" libarch$(LIBEXT)
Where: $ (ARCH_SRC) = nuttx/arch/arm/src, $ (LIBEXT) =.. Instead of the variable name, it is the value in the variable. Line 2nd means to switch to the directory "nuttx/arch/arm/src" first, then run the make command, pass the parameter TOPDIR, and compile the target "libarch. a. Here, make calls the Makefile in the directory nuttx/arch/arm/src and compiles the target in the Makefile. First define BIN = libarch $ (LIBEXT) in nuttx/arch/arm/src/Makefile, and then:
$(BIN) $(KBIN): $(OBJS) $(call ARCHIVE, $@, $(OBJS))
Among them: OBJS =$ (AOBJS) $ (COBJS), while
AOBJS =$ (ASRCS:. S =$ (OBJEXT ))
ASRCS = $ (CHIP_ASRCS) $ (CMN_ASRCS)
COBJS =$ (CSRCS:. c =$ (OBJEXT ))
CSRCS = $ (CHIP_CSRCS) $ (CMN_CSRCS)
Nuttx/arch/arm/src/Makefile contains nuttx/arch/arm/src/chip/Make. defs, four variables: CHIP_ASRCS, CMN_ASRCS, CHIP_CSRCS, and CMN_CSRCS are all stored in nuttx/arch/arm/src/chip/Make. as defined in defs, the variable values after multiple assignments are as follows:
CHIP_ASRCS = (null)
CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S vfork. S
When = stm32_allocateheap.c stm32_start.c when there are too _ gpio.c when _ flash.c when there are too many _ lowputc.c when _ spi.c when there are too _tim.c when there are too many _ pmstop.c when there are too many _ eth.c when _ rtc.c
CMN_CSRCS = up_assert.c up_blocktask.c) When up_exit.c up_initialize.c up_initialstate.c when up_svcall.c when
Here we can find out which source files are compiled and which ones are not compiled.
Command $ (call ARCHIVE, $ @, $ (OBJS) to package static library libarch..
Now return to nuttx/Makefile. unix:
lib/libarch$(LIBEXT): $(ARCH_SRC)/libarch$(LIBEXT) $(Q) install $(ARCH_SRC)/libarch$(LIBEXT) lib/libarch$(LIBEXT)
Here, install is a Linux Command, which is equivalent to copying libarch. a to the directory of nuttx/lib.
6.6 pass1 target
pass1: pass1depsifeq ($(CONFIG_BUILD_2PASS),y) $(Q) if [ -z "$(CONFIG_PASS1_BUILDIR)" ]; then \ echo "ERROR: CONFIG_PASS1_BUILDIR not defined"; \ exit 1; \ fi $(Q) if [ ! -d "$(CONFIG_PASS1_BUILDIR)" ]; then \ echo "ERROR: CONFIG_PASS1_BUILDIR does not exist"; \ exit 1; \ fi $(Q) if [ ! -f "$(CONFIG_PASS1_BUILDIR)/Makefile" ]; then \ echo "ERROR: No Makefile in CONFIG_PASS1_BUILDIR"; \ exit 1; \ fi $(Q) $(MAKE) -C $(CONFIG_PASS1_BUILDIR) TOPDIR="$(TOPDIR)" LINKLIBS="$(LINKLIBS)" USERLIBS="$(USERLIBS)" "$(CONFIG_PASS1_TARGET)"endif
Do not do anything when building a plane.
6.7 pass2 target
Finally, compile pass2
pass2: pass2deps $(Q) $(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" EXTRA_OBJS="$(EXTRA_OBJS)" LINKLIBS="$(LINKLIBS)" EXTRADEFINES=$(KDEFINE) $(BIN) $(Q) if [ -w /tftpboot ] ; then \ cp -f $(BIN) /tftpboot/$(BIN).${CONFIG_ARCH}; \ fiifeq ($(CONFIG_RRLOAD_BINARY),y) @echo "MK: $(BIN).rr" $(Q) $(TOPDIR)/tools/mkimage.sh --Prefix $(CROSSDEV) $(BIN) $(BIN).rr $(Q) if [ -w /tftpboot ] ; then \ cp -f $(BIN).rr /tftpboot/$(BIN).rr.$(CONFIG_ARCH); \ fiendififeq ($(CONFIG_INTELHEX_BINARY),y) @echo "CP: $(BIN).hex" $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex $(BIN) $(BIN).hexendififeq ($(CONFIG_MOTOROLA_SREC),y) @echo "CP: $(BIN).srec" $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O srec $(BIN) $(BIN).srecendififeq ($(CONFIG_RAW_BINARY),y) @echo "CP: $(BIN).bin" $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary $(BIN) $(BIN).binendif @echo "DUMP: $(BIN).out" $(Q) $(OBJDUMP) -x $(BIN) > $(HOME)/$(BIN).out @echo "DUMP: $(BIN).S" $(Q) $(OBJDUMP) -d -j .text -j .init_section -j .ARM.exidx -j .data -j .bss $(BIN) > $(HOME)/$(BIN).S cp -f $(BIN) $(BIN).hex $(BIN).bin $(HOME)
Link the static library to an executable file in elf format and convert it to a file in other formats such as. hex and. bin. I added the last five lines to generate the symbolic file and disassembly file, and copy some final files to the Linux user's home directory. It is implemented by the following lines in the "Install script for NuttX:
if !(grep -q ' @echo "DUMP: $(BIN).out"' Makefile.unix); then sed -i '/pass2:/,/^$/{ /^$/i\ @echo "DUMP: $(BIN).out" /^$/i\ $(Q) $(OBJDUMP) -x $(BIN) > $(HOME)/$(BIN).out /^$/i\ @echo "DUMP: $(BIN).S" /^$/i\ $(Q) $(OBJDUMP) -d -j .text -j .init_section -j .ARM.exidx -j .data -j .bss $(BIN) > $(HOME)/$(BIN).S /^$/i\ cp -f $(BIN) $(BIN).hex $(BIN).bin $(HOME) }' Makefile.unixfi
7. nuttx/Make. defs File
The nuttx/Make. defs file is a Makefile segment, which is copied from nuttx/config/<board>/<target configuration>/Make. defs. It is implemented by the following lines in the "Install script for NuttX:
Echo "nuttx configuration" cd $ BASEDIR/$ TOPDIR/nuttx/tools./configure. sh $ TARGETCONFIG
This Makefile snippet provides architecture and tool-specific build options. It will be included by all other Makefile files during build (once installed ). The makefile segment should be defined as follows:
- Tools: CC, LD, AR, NM, OBJCOPY, and OBJDUMP
- Tool options: CFLAGS and LDFLAGS
When the Makefile snippet is running, it will be passed to the TOPDIR directory of the build root directory. The Makefile segment should include:
$ (TOPDIR)/. config: configuration of Nuttx
$ (TOPDIR)/tools/Config. mk: general definition
The definitions in the nuttx/Make. defs file may depend on some settings in the. config file. For example, if CONFIG_DEBUG = y, CFLAGS is most likely different.
The tools/Config. mk file contains additional definitions that may be overwritten by the schema-specific Make. defs file when necessary:
COMPILE, ASSEMBLE, ARCHIVE, CLEAN, and MKDEP macros