Concerto编译框架解析

Concerto编译框架解析

第一章 概述

ConcertoTI-TDA4系列芯片RTOS编译环境中的一套基于Makefile的编译框架。它很好的支持多平台,多目标架构,多编译器编译。非常适合异构芯片的复杂工程编译,但整套concerto编译系统嵌套层次比较深,变量较多,不易理解。

熟悉一个工程的最快途径,是阅读其MakefileCmakeConcerto的复杂性就成为研究TI-SDK的一座大山,笔者在开发过程中也倍感痛苦,遂对其进行逐级分析,撰文记录。


第二章 Concerto简介

2.1 特性

  • 多平台支持
  • 多目标架构
  • 多编译器编译
  • 适合异构芯片的多平台编译

2.2 参考资料

经检索,发现TI所使用的Concerto框架在github上有开源项目,其原始项目地址如下:

https://github.com/emrainey/Concerto

TI版本的Concerto适配其异构处理器平台,也进行了开源,开源地址为:

ssh://$USER@gitorious.design.ti.com:build-systems/concerto.git

二者的先后顺序和开发关系已不好追溯,但基本框架基本没有区别。

其SDK文档中也对Concerto框架有介绍,文章标题为:“Understanding concerto makefile system”,google即可搜到

2.3 TI-Concerto框架结构

├── README
├── combo.mak
├── combo_filters.mak
├── compilers
│   ├── arp32.mak
│   ├── cgt6x.mak
│   ├── cgt7x.mak
│   ├── cl.mak
│   ├── gcc.mak
│   ├── gcc_linux.mak
│   ├── gcc_linux_arm.mak
│   ├── gcc_sysbios_arm.mak
│   ├── gcc_windows.mak
│   ├── nvcc_linux.mak
│   ├── qnx_arm.mak
│   ├── tiarmcgt.mak
│   └── tiarmcgt_llvm.mak
├── definitions.mak
├── finale.mak
├── machine.mak
├── os.mak
├── prelude.mak
├── rules.mak
├── shell.mak
└── target.mak

第三章 Concerto用法

  • 获取Concerto源码
  • 在工程中新建顶层Makefile
  • Makefile中需要包含以下元素
    • CONCERTO_ROOT ?= …/concerto

      CONCERTO_ROOT指定concerto的路径

    • DIRECTORIES

      DIRECTORIES指定需要搜索的源代码路径

    • BUILD_TARGET := $(abspath .)/target.mak

      跟顶层Makefile同一层级的target.mak文件,其中描述工程的特定需求
      如:根据目标平台不同,指定不同的头文件路径和库路径

    • include $(CONCERTO_ROOT)/rules.mak

      必须包含的子Make,执行make后实际依赖rules.mak生成编译目标及完成编译

  • 如果需要增加新的子模块
    • 在顶层Makefile中添加子模块搜索路径
    • 在子模块源代码路径增加concerto.mk

第四章 concerto.mk示例

_MODULE=<可选 模块名称>
include $(PRELUDE)
TARGET=<模块目标文件的名称>
TARGETTYPE=<exe|library|dsmo|prebuilt|jar>
CSOURCES=<模块的所有C源文件>
CPPSOURCES=<模块的所有C++源文件>
ASSEMBLY=<模块的所有汇编源文件>
KCSOURCES=<内核代码.k源文件>
IDIRS+=<头文件路径>
DEFS+=<宏定义>
STATIC_LIBS=<编译系统中的静态库>
SHARED_LIBS=<编译系统中的动态库>
SYS_STATIC_LIBS=<自定义静态库>
SYS_SHARED_LIBS=<自定义动态库>
LINKER_FILES=<链接脚本>
PREBUILT=<需要拷贝到目标产物路径的二进制文件,仅在TARGETTYPE是prebuilt时适用>
include $(FINALE)

上述内容不是每个都必要的,可以根据需要进行删减,下面展示一个最简单的concerto.mk:

include $(PRELUDE)
TARGET=mytest
TARGETTYPE=exe
SYS_STATIC_LIBS+=some_system_lib
CSOURCES=main.c
include $(FINALE)

第五章 Concerto关键变量和宏

如果读者仅关注Concerto的使用,第五章及其之后的内容不用关注,前四章已经足够,本章主要对Concerto编译框架中的一些关键变量和宏进行一些介绍,避免读者在阅读源码时一头雾水。

5.1 TARGET_COMBOS

TARGET_COMBOS是定义在顶层Makefile中的变量,Concerto通过TARGET_COMBOS,产生多个平台的Makefile目标,从而做到一份代码,编译多平台产物。

TARGET_COMBOS是一个目标组合列表,它的每一个元素都是由平台、目标系统、目标架构、核心数量、编译类型、目标编译器组合起来的字符串,例如:J784S4:FREERTOS:R5F:3:release:TIARMCGT_LLVM可以作为TARGET_COMBOS的其中一个元素。

通过用户自定义的组合,Concerto才知道同一份代码需要在哪些平台中编译,用户需要在顶层Makefile中将多个COMBO加入列表,Concerto遍历TARGET_COMBOS列表,生成不同编译组合的Makefiel目标,才能满足同一份代码多平台架构的编译需求。

5.2 DIRECTORIES

DIRECTORIES是定义在顶层Makefile中的变量,该变量存储了需要检索的源代码路径,Concerto会对顶层MakefileDIRECTORIES变量中的所有路径进行递归搜索,找到所有concerto.mak文件,参与最终的编译。

5.3 _MODULE

_MODULE是最小编译模块的名称,在concerto.mak中定义,不定义的话,默认使用concerto.mak文件的路径,如:xxx/yyy/zzz/concerto.mak定义了一个需要编译的模块,则模块的名称会被Concerto生成为: xxx.yyy.zzz.J784S4.FREERTOS.R5F.release

Concerto会根据TARGET_COMBO中的编译器类型,选择不同编译器的子Makefile,生成不同模块的编译命令和参数选项

例如:

xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_BIN
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_BINS
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_BUILD
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_BUILD_LIB
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_CFLAGS
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_CLEAN
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_COPT
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_DEFINES
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_DEPEND
xxx.yyy.zzz.J784S4.FREERTOS.R5F.release_IDIRS

5.4 lowercase和uppercase

这两个宏定义在rules.mak中,作用是将字符串转为小写或大写,内容如下:

# rules.mak
lowercase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
uppercase = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1))))))))))))))))))))))))))

用法如下:

# rules.mak
xxxx = $(call lowercase,$(yyyy))
xxxx = $(call uppercase,$(yyyy))

5.5 rwildcard

rwildcard宏也定义在rules.mak中,作用是递归搜索所有指定目录的特定文件,入参有两个,第一个参数是目录,第二个参数是需要检索的文件,Concerto就是使用这个宏来寻找所有concerto.mk的。

其内容如下:

# rules.mak
rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))

用法如下:

# rules.mak
SUBMAKEFILE := concerto.mak
# 递归找出DIRECTORIES变量的目录列表中所有的concerto.mak文件路径
TARGET_MAKEFILES := $(filter %/$(SUBMAKEFILE),$(sort $(foreach d,$(DIRECTORIES),$(strip $(call rwildcard,$(d)/,*.mak)))))

5.6 MAKE_OUT和TARGET_LIB_OUT

MAKE_OUT和TARGET_LIB_OUT宏定义在rules.mak中,在combo.mak中使用,主要作用是拼接出产物路径,拼接规则是工程根路径/out/平台名称/CPU名称/系统名称/和编译类型,例如:vision_apps/out/J784S4/R5F/FREERTOS/release。其定义如下:

# rules.mak
MAKE_OUT = $(1)/$(BUILD_OUTPUT)/$(TARGET_PLATFORM)/$(TARGET_CPU)/$(TARGET_OS)/$(TARGET_BUILD)
TARGET_LIB_OUT = $(1)/$(BUILD_LIBS)/$(TARGET_PLATFORM)/$(TARGET_CPU)/$(TARGET_OS)/$(TARGET_BUILD)

用法如下:

# combo.mak
TARGET_OUT := $(call MAKE_OUT,$(HOST_ROOT))
CONCERTO_TARGET_LIB_OUTS += $(call TARGET_LIB_OUT,$(HOST_ROOT))

5.7 FILTER_COMBO和FILTER_OUT_COMBO

FILTER_COMBO和FILTER_OUT_COMBO定义在rules.mak中,用于combo_filters.mak,主要作用是筛选编译目标。

其定义如下:

# rules.mak
FILTER_COMBO = $(foreach combo,$(TARGET_COMBOS),$(if $(filter $(1),$(subst :, ,$(combo))),$(combo)))
FILTER_OUT_COMBO = $(foreach combo,$(TARGET_COMBOS),$(if $(filter $(1),$(subst :, ,$(combo))), ,$(combo)))

用法如下:

# combo_filters.mak
# 筛选出包含特定编译关键字的目标COMBO
TARGET_COMBOS := $(call FILTER_COMBO,LINUX SYSBIOS QNX FREERTOS SAFERTOS)
# 找出编译器路径未定义的目标COMBO
REMOVE_ROOTS := $(foreach root,$(COMPILER_ROOTS),$(if $(filter $(origin $(root)),undefined),$(root)))
# 筛除编译器路径未定义的目标COMBO
TARGET_COMBOS := $(call FILTER_OUT_COMBO,$(foreach root,$(REMOVE_ROOTS),$(subst _ROOT,,$(root))))

用法请参考前文的concerto.mak内容解析

5.8 遍历TARGET_COMBOS中的所有目标组合

# rules.mak
define CONCERTO_BUILD
include $(CONCERTO_ROOT)/combo.mak
endef
include $(CONCERTO_ROOT)/combo_filters.mak
# 遍历所有TARGET_COMBOS
$(foreach TARGET_COMBO,$(TARGET_COMBOS),$(eval $(call CONCERTO_BUILD)))

5.9 包含所有concerto.mak

前文中已使用rwildcard递归搜索出所有concerto.mak,并保存在TARGET_MAKEFILES变量中,并且TARGET_COMBOS被遍历包含了combo.mak,此时,TARGET_MAKEFILES中的所有concerto.mak在combo.mak中被包含展开,用法如下:

# combo.mak
include $(TARGET_MAKEFILES)

5.10 PRELUDE和FINALE

如前文所述,PRELUDE和FINALE变量被每个concerto.mak包含,但其是在rules.mak中定义的,定义如下:

# rules.mak
PRELUDE := $(CONCERTO_ROOT)/prelude.mak
FINALE  := $(CONCERTO_ROOT)/finale.mak

5.11 PRELUDE-模块预处理

prelude.mak中将模块路径转换为模块名称是通过文本替换实现的,‘/‘转换为’.’,在其后拼接平台和目标COMBO信息,并存入前文的**_MODULE**变量,原始代码如下:

# prelude.mak
# 使用字符替换将模块路径转为目标名称
_MODDIR := $(subst $(EXTERNAL_SOURCE_PATH_PREFIX),,$(_MODPATH))
_MODDIR := $(subst \,/,$(_MODDIR))
_MODDIR := $(subst :,,$(_MODDIR))
_MODDIR := $(subst /,.,$(_MODDIR))
# 在目标后补充目标COMBO信息,最终得到的_MODULE形如:xxx.yyy.zzz.J784S4.FREERTOS.R5F.release
_MODULE := $(_MODULE).$(TARGET_PLATFORM).$(TARGET_OS).$(TARGET_CPU).$(TARGET_BUILD)

5.12 FINALE-模块后处理

finale.mak中主要根据COMBO信息,包含不同编译器的子Makefile,然后调用编译器子Makefile中的变量,进行编译,此处展示exe目标类型的编译:

# finale.mak
......
include $(CONCERTO_ROOT)/compilers/tiarmcgt.mak
......
$(eval $(call $(_MODULE)_BUILD_EXE))
$(eval $(call $(_MODULE)_INSTALL))
$(eval $(call $(_MODULE)_BUILD))
$(eval $(call $(_MODULE)_UNINSTALL))

5.13 编译器子Makefile

由于Concerto编译框架支持众多处理器平台和目标架构,因此它在compilers目录下存放了众多编译器相关子Makefile,其作用是为每个子模块生成编译和链接命令及参数。此处以R5F核编译使用的tiarmcgt.mak为例摘取部分进行展示:

# tiarmcgt_llvm.mak
# 定义编译命令变量
CC=$(TIARMCGT_LLVM_ROOT)/bin/tiarmclang
CP=$(TIARMCGT_LLVM_ROOT)/bin/tiarmclang
AS=$(TIARMCGT_LLVM_ROOT)/bin/tiarmclang
AR=$(TIARMCGT_LLVM_ROOT)/bin/tiarmar
LD=$(TIARMCGT_LLVM_ROOT)/bin/tiarmclang
STRIP=$(TIARMCGT_LLVM_ROOT)/bin/tiarmstrip

# 为每个模块生成唯一的编译命令变量和参数
$(_MODULE)_OUT  := $(BIN_PRE)$($(_MODULE)_TARGET)$(BIN_EXT)
$(_MODULE)_BIN  := $($(_MODULE)_TDIR)/$($(_MODULE)_OUT)
$(_MODULE)_STRIP  := $($(_MODULE)_TDIR)/$(BIN_PRE)$($(_MODULE)_TARGET)$(STRIP_EXT)$(BIN_EXT)
$(_MODULE)_STATIC_LIBS := $(foreach lib,$(STATIC_LIBS),$($(_MODULE)_TDIR)/$(LIB_PRE)$(lib).$(LIB_EXT))
$(_MODULE)_STATIC_LIBS += $(foreach lib,$(SYS_STATIC_LIBS),$($(_MODULE)_TDIR)/$(LIB_PRE)$(lib).$(LIB_EXT))
$(_MODULE)_IDIRS += $(TIARMCGT_LLVM_ROOT)/include
$(_MODULE)_LDIRS += $(TIARMCGT_LLVM_ROOT)/lib
$(_MODULE)_COPT := $(CFLAGS)
$(_MODULE)_LOPT := $(LDFLAGS)
$(_MODULE)_COPT += $(SUPRESS_WARNINGS_FLAG)

第六章 调用层级

前文已经将Concerto编译框架的用法以及关键变量和宏进行了拆分说明,本章使用结构化的调用说明,将前文的知识串联起来,便于读者了解Concerto的调用层级关系。

- Makefile <顶层Makefile>
  - include $(CONCERTO_ROOT)/rules.mak
  - include $(CONCERTO_ROOT)/os.mak
  - include $(CONCERTO_ROOT)/machine.mak
  - include $(CONCERTO_ROOT)/shell.mak
  - include $(CONCERTO_ROOT)/combo_filters.mak
  - include $(CONCERTO_ROOT)/combo.mak  \<forreach\>
    - include $(BUILD_TARGET)  \<BUILD_TARGET在顶层Makefile中定义\>
    - include concerto.mak  \<all\>
      - include $(CONCERTO_ROOT)/prelude.mak
        - include $(CONCERTO_ROOT)/definitions.mak  \<包含众多查找源文件的宏定义\>
      - include $(CONCERTO_ROOT)/finale.mak
        - include $(CONCERTO_ROOT)/compilers/tiarmcgt.mak
          - 生成$(_MODULE)_BUILD
          - 生成$(_MODULE)_LINK_LIB
          - 生成$(_MODULE)_LINK_EXE
          - ......

第七章 总结

Concerto编译框架,其最终目标为相同代码,不同平台和架构下的编译,编译前,在顶层Makefile中指定所有需要参与编译的目录在DIRECTORIES变量中,Concerto递归查找目录中的concerto.mak,concerto.mak中约束了当前模块使用于哪些平台和目标。

总的来说,Concerto先根据TARGET_COMBOSDIRECTORIES,进行初步筛选,假设所有模块都需要编译,在concerto.mak中,精细控制子模块参与哪些平台的编译链接,及其产物形式。

本质上,Concerto编译框架其实是为用户,生成了一个大型Makefile,其中每个编译目标,不仅跟源代码位置相关,还与目标平台、处理器、操作系统关联,确保了每个目标的唯一性。

第八章 Concerto原始README

CONCERTO README

What is it?

Concerto is a simple single-pass, non-recursive, full dependency-managed Makefile system.

How it works

Concerto looks for sub-makefiles called concerto.mak in the directories (and their corresponding subdirectories) specified by the DIRECTORIES variable. It will “include” each module’s concerto.mak file into the overall build and resolve all build related macros associated with that module. In this way, it is “single pass” in that all concerto.mak makefiles are read once. The Concerto Build System makefiles like the prelude.mak and finale.mak (and submakefiles therein) are read once per module. These are used to define the make-target macros needed to establish the full depedency tree of the entire build system.

Build System Files
  • definitions.mak - useful macros for finding source files
  • rules.mak - internal top level file. Include this in your Makefile.
  • os.mak - determines host os
  • machine.mak - determines host cpu
  • target.mak - determines target variables and build system include paths, variables. This can be replaced (see above).
  • scm.mak - tries to extract SCM version information (SVN/GIT)
  • prelude.mak and finale.mak - generates non-recursive build system macros and variables per module.
  • compilers/* - Compiler specific files
  • os/* - OS specific installing/removing rules
  • tools/* - tools specific rules.
  • components/* - contains rules to build with components that do not work well with standard package management tools like pkg-config
  • shell.mak - Contains shell macros per OS.
  • combo.mak and combo_filters.mak - contains rules to simulatenously build on multiple compilers.
  • packages.mak - contains package management rules per OS.
How to use it
  • Download or copy the concerto folder to somewhere on your build system from git clone https://github.com/emrainey/Concerto
  • Create a Makefile at the top of you project consisting of the following:

Top Level Makefile per project

    # Path to concerto install or use environment variable
    CONCERTO_ROOT ?= ../concerto
    # [OPTIONAL] if DIRECTORIES is not specified concerto assumes "source"
    DIRECTORIES  := src docs
    # [OPTIONAL] BUILD_TARGET is used to reflect specific needs of your build system.
    # if not specified concerto's default target.mak is used instead
    BUILD_TARGET := $(abspath .)/target.mak
    # [REQUIRED] This calls concerto
    include $(CONCERTO_ROOT)/rules.mak

How to auto-download if Concerto is not present

    # Path to concerto install or use environment variable
    CONCERTO_ROOT ?= ../concerto
    # [OPTIONAL] check to see if the path really exists to CONCERTO_ROOT, if it does not, execute a shell command to pull it down with git
    $(if $(realpath $(CONCERTO_ROOT)),,$(call $($(shell git clone http://github.com/emrainey/Concerto $(CONCERTO_ROOT)))))
    ...
    # This calls concerto
    include $(CONCERTO_ROOT)/rules.mak
What’s in the concerto.mak

concerto.mak files can contain the following (although it is normally shorter):

    _MODULE=<optional module name>
    include $(PRELUDE)
    TARGET=<name of the object created>
    TARGETTYPE=<exe|library|dsmo|prebuilt|jar>
    CSOURCES=<list of C files>
    CPPSOURCES=<list of C++ files>
    ASSEMBLY=<list of .S Files>
    KCSOURCES=<list of KernelC .k files>
    IDIRS+=<include directories>
    DEFS+=<defines>
    STATIC_LIBS=<static libraries within the build system>
    SHARED_LIBS=<shared libraries within the build system>
    SYS_STATIC_LIBS=<static libraries outside the build system>
    SYS_SHARED_LIBS=<shared libraries outside the build system>
    LINKER_FILES=<list of linker files within the build system>
    PREBUILT=<It specifies a single resource to be copied into the target output, only used with the prebuilt TARGETTYPE>
    include $(FINALE)

A typical concerto.mak is shorter:

    include $(PRELUDE)
    TARGET=mytest
    TARGETTYPE=exe
    SYS_STATIC_LIBS+=some_system_lib
    CSOURCES=main.c
    include $(FINALE)
Internal Variables

The following variables and macros are available for use in a concerto.mak file.

  • _MODULE - the name of the module (if not defined, the containing folder name will be used).
  • TARGET - the name of the component to build. Prefixes and postfixes will be added by the build system, do not add them yourself.
  • TARGETTYPE - possible values are:
  • exe - binary executable
  • library - static library
  • dsmo - dynamic shared library
  • prebuilt - a prebuilt binary
  • jar - a Java jar file
  • doxygen - A doxygen build
  • deb - A debian package (control file is required)
  • SYS_SHARED_LIBS - dynamic libraries for which no dependencies are generated (which implies that they are outside the build system).
  • SYS_STATIC_LIBS - static libraries for which no dependencies are generated (which implies that they are outside the build system).
  • SHARED_LIBS - dynamic libraries for which dependencies are generated (which implies that they are inside the build system).
  • STATIC_LIBS - static libraries for which dependencies are generated (which implies that they are inside the build system).
  • ASSEMBLY - S files which must be in the same folder.
  • CSOURCES - C files which must be in the same folder.
  • CPPSOURCES - C++ files which must be in the same folder.
  • JSOURCES - Java files for Jar targets
  • IDIRS - include directories
  • LDIRS - library link paths
  • DEFS - #defines to pass to the compiler
Useful Macros
    # list of files with extension .ext in "dir" and any sub-directory of "dir"
    $(call all-type-files-in,<ext>,<dir>)
    # list of files with extension .ext that exist inside this module (including any sub-directories)
    $(call all-type-files,<ext>)
    # list of c files c that exist inside this module (including any sub-directories)
    $(call all-c-files)
    # list of c files c that exist in dir (including any sub-directories). dir is relative to the module directory
    $(call all-c-files-in,<dir>)

See definitions.mak and shell.mak for other supported file extensions.

External Variables

The preceding variables can be set in the command shell and make will import them.

  • NO_OPTIMIZE=1 - disables optimization in the compiler. The target build will be built follow normal debugging flags on this platform.
  • CHECK_MISRA=1 - it enables misra compliance checking however it is compiler dependant
  • KEEP_ASM=1 - it keeps generated assembly listings however it is compiler dependant
  • KEEP_VCC=1 - keep generated VCOP-C code however this is for ARP32/VCOP compiler only
  • BUILD_DEBUG=1 - turns on explicit build output from each command
  • TARGET_PLATFORM - indicates the platform to build for (assumes ‘PC’ if not set).
  • TARGET_OS = LINUX or Windows_NT or DARWIN or QNX
  • TARGET_CPU = ARM or X86 or X86_64 or c64t or c67x
  • TARGET_BUILD = debug or release or production - used to generate debuggable components, optimized components or finale builds.
  • HOST_OS = LINUX or Windows_NT
  • HOST_CPU = X86 or X86_64
  • HOST_PLATFORM = PC (ususally)
Supported Platforms and Targets

Host Environments:

  • LINUX
  • DARWIN
  • WINDOWS (NT or later)
  • CYGWIN

Target Environments:

  • LINUX
  • DARWIN
  • WINDOWS (NT or later)
  • CYGWIN
  • QNX

Target CPUs:

  • ARM
  • X86
  • X86_64
  • TI DSPs
Windows Builds

When building on Windows, you need to install MinGW to get the GNU Make for Windows. Add the path to MinGW’s bin/ folder to your PATH variable. You may want to rename or copy it from mingw32-make.exe to make.exe.

Available Build System Targets

Concerto provides the following useful rules:

make scrub This will delete the build output directory
make targets Lists all targets defined by concerto.mak files
make <target> This will build the specified target and any of its dependencies
make <target>_clean Cleans out the specified target
make clean Cleans out all build artifacts for all targets
make vars Outputs the module variables as concerto thinks they are. Useful for debugging.

Build System Layout

The typical folder layout (the default configuration) is:

project_folder/

  • Makefile
  • include/
  • source/any depth of folders/concerto.mak
  • out/ ( T A R G E T P L A T F O R M ) / (TARGET_PLATFORM)/ (TARGETPLATFORM)/(TARGET_CPU)/ ( T A R G E T O S ) / (TARGET_OS)/ (TARGETOS)/(TARGET_BUILD)/components
Multiproject Builds

For multiproject builds the layout is just all project_folder folders as peers within a parent folder which will have the out folder as a child. The Makefile for a multiproject build simply notes the subdirs of the build.

    DIRECTORIES := someproject/source someproject/docs
    DIRECTORIES += otherproject/source otherproject/docs

Concerto has to be careful to make sure no _MODULES are named the same in these two projects, so it alters the _MODULE name to guarentee uniqueness (otherwise you would have two components share the same output folder for intermediate objects and you may be compiler/linker collisions and very odd behavior).

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值