PX4 CMakeLists.txt 文件剖析

2023-05-16

PX4 CMakeLists.txt 文件剖析

前面对于 PX4Makefile 已经做了比较详细的分析, 见这里, 这里进一步对 PX4CMakeLists.txt 文件结构进行进一步的分析.

1 CMake 简述

CMake 是一个 DSL( Domain Specific Language), 主要用来辅助对代码的编译配置和管理, 其具有跨平台, 可维护性较好的特点, 目前在 C++ 项目中得到了普遍应用. 下面是对 CMAKE的简单介绍,如需了解更多,请参考 CMake Documentation和Modern CMake等文档及教程。
CMake 中包含了针对编译配置的特殊函数和变量定义, 语法类C, 包括了控制语句, 模块导入语句, 字符串处理行数等较为通用的功能.
CMake 工作流程
CMake 中的文件结构按功能大致可以分为, Directories, Script 和 Module. 其中 Module 可以通过include 命令导入, include 命令会在 CMAKE_MODULE_PATH 下寻找指定的模块. 下表列出了一些出现频率较高的指令

CMake 指令列表指令说明
cmake_minimum_requiredcmake 的最小的版本
set(variable value… [PARENT_SCOPE])设置变量variable的值value, [PARENT_SCOPE] 可选表示变量的作用域
list(APPEND list element…)把 element 附加到 list 中
list(GET list index variable)从 list 中获取给定index的值放到变量中
include(file/module)导入file或 module 并执行
file(GLOB_RECURSE variable RELATIVE path expression)生成匹配expression的相对于 path 的文件列表
message(STATUS string)向终端输出string
set_property(GLOBAL PROPERTY name value)设置全局属性 name 的值为 value
option(variable help_string [value])设置variable 的值
add_subdirectory(directory)添加一个需要 build的子文件夹
include_directories(directory)把目录directory添加到可以被cmake include 的文件的搜索路径中
link_directories(directory)把目录directory 添加到连接器的搜索路径中
add_custom_target(Name COMMAND COMMENT USES_TERMINAL)添加一个没有输出的并且总会被编译的目标, COMMAND 为一些待执行的命令, USES_TERMINAL 代表是否可以直接获取到终端

2 CMakeLists.txt 文件剖析

cmake_minimum_required(VERSION 3.2 FATAL_ERROR) 

首先是说明需要的 CMake 最小的版本

 set(PX4_SOURCE_DIR "\${CMAKE_CURRENT_SOURCE_DIR}")
 set(PX4_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")

第一句设置PX4_SOURCE_DIR 的值为 ${CMAKE_CURRENT_SOURCE_DIR}, 该值是一个CMAKE内置变量, 表示的是当前的正在处理的 CMakeLists.txt 所在文件夹的路径, CMake 中还有另一个变量 CMAKE_SOURCE_DIR 表示的是当前编译项目的入口 CMakeLists.txt 所在的文件夹路径. 第二句设置 PX4_BINARY_DIR 的值为 ${CMAKE_CURRENT_BINARY_DIR} 路径, 该值表示的是当前编译的二进制文件夹的位置.

 list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/cmake)

${PX4_SOURCE_DIR}/cmake 添加到模块的搜索路径中. 这个文件夹对应着 /path/to/Firmware/cmake, 文件夹下有一些模块

cmake_hexagon         gtest                       px4_add_module.cmake              px4_metadata.cmake
configs               px4_add_board.cmake         px4_base.cmake                    sanitizers.cmake
coverage.cmake        px4_add_common_flags.cmake  px4_git.cmake
cygwin_cygpath.cmake  px4_add_library.cmake       px4_make_uavcan_bootloader.cmake

导入 px4_git 模块, 其中定义了px4_ add_git_submodule 模块, 主要用来更新模块.

 execute_process(
       COMMAND git describe --always --tags
       OUTPUT_VARIABLE PX4_GIT_TAG
       OUTPUT_STRIP_TRAILING_WHITESPACE
       WORKING_DIRECTORY ${PX4_SOURCE_DIR)
       )

获取到当前版本号放到 PX4_GIT_TAG 变量中.

define_property(GLOBAL PROPERTY PX4_MODULE_LIBRARIES
                 BRIEF_DOCS "PX4 module libs"
                 FULL_DOCS "List of all PX4 module libraries"                 )

define_property(GLOBAL PROPERTY PX4_MODULE_PATHS
                 BRIEF_DOCS "PX4 module paths"
                 FULL_DOCS "List of paths to all PX4 modules"
                 )

定义了两个值为空的全局属性 PX4_MODULE_LIBRARIESPX4_MODULE_PATHS , 其中PX4_MODULE_LIBRARIES 为所有 PX4 的模块库的列表, PX4_MODULE_PATHS 为所有 PX4 模块的路径.

 set(CONFIG "px4_sitl_default" CACHE STRING "desired configuration")

设置 CONFIG 的值为px4_sitl_default, 这个值在执行make targets_default 是会被设置成targets_default

 include(px4_add_module)
 set(config_module_list)
 set(config_df_driver_list)

px4_add_module.cmake 中定义了 px4_add_module 函数用来添加对不同平台的一些编译选项. 同时 unsetconfig_module_listconfig_df_driver_list.

#  look for in tree board config that matches CONFIG input
if(NOT PX4_CONFIG_FILE)
    file(GLOB_RECURSE board_configs
        RELATIVE "${PX4_SOURCE_DIR}/boards"
        "boards/*.cmake"
        )

    set(PX4_CONFIGS ${board_configs} CACHE STRING "PX4 board configs" FORCE)

    foreach(filename ${board_configs})
        # parse input CONFIG into components to match with existing in tree configs
        #  the platform prefix (eg nuttx_) is historical, and removed if present
        string(REPLACE ".cmake" "" filename_stripped ${filename})
        string(REPLACE "/" ";" config ${filename_stripped})
        list(LENGTH config config_len)

        if(${config_len} EQUAL 3)


            list(GET config 0 vendor)
            list(GET config 1 model)
            list(GET config 2 label)

            set(board "${vendor}${model}")

            # <VENDOR>_<MODEL>_<LABEL> (eg px4_fmu-v2_default)
            # <VENDOR>_<MODEL>_default (eg px4_fmu-v2) # allow skipping label if "default"
            if ((${CONFIG} MATCHES "${vendor}_${model}_${label}") OR # match full vendor, model, label
                ((${label} STREQUAL "default") AND (${CONFIG} STREQUAL "${vendor}_${model}")) # default label can be omitted
            )
                set(PX4_CONFIG_FILE "${PX4_SOURCE_DIR}/boards/${filename}" CACHE FILEPATH "path to PX4 CONFIG file" FORCE)
                break()
            endif()

            # <BOARD>_<LABEL> (eg px4_fmu-v2_default)
            # <BOARD>_default (eg px4_fmu-v2) # allow skipping label if "default"
            if ((${CONFIG} MATCHES "${board}_${label}") OR # match full board, label
                ((${label} STREQUAL "default") AND (${CONFIG} STREQUAL "${board}")) # default label can be omitted
            )
                set(PX4_CONFIG_FILE "${PX4_SOURCE_DIR}/boards/${filename}" CACHE FILEPATH "path to PX4 CONFIG file" FORCE)
                break()
            endif()


            # LEGACY form
            # <OS>_<BOARD>_<LABEL> (eg nuttx_px4_fmu-v2_default)
            string(REGEX REPLACE "^nuttx_|^posix_|^qurt_" "" config_no_os ${CONFIG}) # ignore OS prefix

            if ((${config_no_os} MATCHES "${board}_${label}"))
                set(PX4_CONFIG_FILE "${PX4_SOURCE_DIR}/boards/${filename}" CACHE FILEPATH "path to PX4 CONFIG file" FORCE)
                break()
            endif()


            # LEGACY form special case to ease board layout transition (2018-11-18)
            #  match board with model and label only: eg sitl_default -> px4_sitl_default
            if ((${config_no_os} MATCHES "${model}_${label}"))
                set(PX4_CONFIG_FILE "${PX4_SOURCE_DIR}/boards/${filename}" CACHE FILEPATH "path to PX4 CONFIG file" FORCE)
                break()
            endif()

        endif()
    endforeach()
endif()

boards 文件夹下所有子文件包括的cmake 文件中查找CONFIG 对应的 .cmake 文件, 比如当 CONFIG 的值为px4_sitl_default 是查找的文件为px4/sitl/default.cmake. 对于每个通配符匹配到的.cmake 文件,把文件路径切分为三部分分别放入vendor, modellabel 变量中, 例如对于 aerotenna/ocpoc/ubuntu.cmake 会被切分成aerotenna, ocpocubuntu 三部分, 然后通过不同的拼接组合和CONFIG 的值进行比较, 如果相等则设置 PX4_CONFIG_FILE 的值为当前的cmake 文件.

if(NOT PX4_CONFIG_FILE)
          message(FATAL_ERROR "PX4 config file not set, try one of ${PX4_CONFIGS}")
endif()

如果遍历完所有文件之后, PX4_CONFIG_FILE值为空, 则报错退出.

message(STATUS "PX4 config file: ${PX4_CONFIG_FILE}")
include(px4_add_board)
include(${PX4_CONFIG_FILE})
message(STATUS "PX4 config: ${PX4_CONFIG}")
message(STATUS "PX4 platform: ${PX4_PLATFORM}")

如果找到了该PX4_CONFIG_FILE 输出当前状态, 然后包括 px4_add_board 这个cmake 文件, 其中包含了 px4_add_board 这个函数. 同时导入 PX4_CONFIG_FILE 这个文件. 在该文件中调用了 px4_add_board 这个函数, 该函数设置了 PX4_CONFIGPX4_PLATFORM 两个变量. 对于CONFIG 的值为px4_sitl_default 这两个值为px4_sitl_defaultposix.

if (ENABLE_LOCKSTEP_SCHEDULER)
    add_definitions(-DENABLE_LOCKSTEP_SCHEDULER)
    message(STATUS "PX4 lockstep: enabled")
else()
    message(STATUS "PX4 lockstep: disabled")
endif()

目的未知…

# external modules
set(EXTERNAL_MODULES_LOCATION "" CACHE STRING "External modules source location")

if (NOT EXTERNAL_MODULES_LOCATION STREQUAL "")
    get_filename_component(EXTERNAL_MODULES_LOCATION "${EXTERNAL_MODULES_LOCATION}" ABSOLUTE)
endif()	

添加外部模块路径

set_property(GLOBAL PROPERTY PX4_MODULE_CONFIG_FILES)
include(platforms/${PX4_PLATFORM}/cmake/px4_impl_os.cmake)
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/platforms/${PX4_PLATFORM}/cmake)

导入px4_impl_os.cmake 中针对于特定操作系统的一些命令, 这些命令用来生成一些程序源码和执行一些文件操作. 并把对应于这个platform 的cmake文件夹放到 CMAKE_MODULE_PATH 中.

if(EXISTS "${PX4_SOURCE_DIR}/platforms/${PX4_PLATFORM}/cmake/init.cmake")
    include(init)
endif()

导入初始化cmake 文件

# CMake build type (Debug Release RelWithDebInfo MinSizeRel Coverage)
if (NOT CMAKE_BUILD_TYPE)    if (${PX4_PLATFORM} STREQUAL "nuttx")
        set(PX4_BUILD_TYPE "MinSizeRel")
    else()
        set(PX4_BUILD_TYPE "RelWithDebInfo")    endif()

    set(CMAKE_BUILD_TYPE ${PX4_BUILD_TYPE} CACHE STRING "Build type" FORCE)
endif()

set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel;Coverage;AddressSanitizer;UndefinedBehaviorSanitizer")

设置编译类型

message(STATUS "PX4 version: ${PX4_GIT_TAG}")
message(STATUS "cmake build type: ${CMAKE_BUILD_TYPE}")

输出 PX4 版本信息和编译类型

project(px4 CXX C ASM)

set(package-contact "px4users@googlegroups.com")

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

设置项目名称为px4 语言为 CXX C ASM, 同时设置了包的沟通方式以及有关编程语言的一些编译设置和是否导出设置.

# For the catkin build process, unset build of dynamically-linked binaries
# and do not change CMAKE_RUNTIME_OUTPUT_DIRECTORY
if (NOT CATKIN_DEVEL_PREFIX)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PX4_BINARY_DIR})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PX4_BINARY_DIR})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PX4_BINARY_DIR})
else()
    SET(BUILD_SHARED_LIBS OFF)
endif()

catkin 有自己的默认的二进制文件编译目录,因此这里对它进行一些特殊处理

# Setup install paths
if (${PX4_PLATFORM} STREQUAL "posix")

    # This makes it possible to dynamically load code which depends on symbols
    # inside the px4 executable.
    set(CMAKE_POSITION_INDEPENDENT_CODE ON)
    set(CMAKE_ENABLE_EXPORTS ON)

    include(coverage)
    include(sanitizers)

    # Define GNU standard installation directories
    include(GNUInstallDirs)

    if (NOT CMAKE_INSTALL_PREFIX)
        set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Install path prefix" FORCE)
    endif()
endif()

设置安装路径

# ccache
#
option(CCACHE "Use ccache if available" ON)
find_program(CCACHE_PROGRAM ccache)
if (CCACHE AND CCACHE_PROGRAM AND NOT DEFINED ENV{CCACHE_DISABLE})

    get_filename_component(ccache_real_path ${CCACHE_PROGRAM} REALPATH)
    get_filename_component(cxx_real_path ${CMAKE_CXX_COMPILER} REALPATH)
    get_filename_component(cxx_abs_path ${CMAKE_CXX_COMPILER} ABSOLUTE)

    if ("${ccache_real_path}" STREQUAL "${cxx_real_path}")
        message(STATUS "ccache enabled via symlink (${cxx_abs_path} -> ${cxx_real_path})")
    else()
        message(STATUS "ccache enabled (export CCACHE_DISABLE=1 to disable)")
        set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
    endif()

endif()

ccache 是一个辅助编译的工具, 可以避免大量重复的编译工作

# see if catkin was invoked to build this
if (CATKIN_DEVEL_PREFIX)
    message(STATUS "catkin ENABLED")
    find_package(catkin REQUIRED)
    if (catkin_FOUND)
        catkin_package()
    else()
        message(FATAL_ERROR "catkin not found")
    endif()
endif()
find_package(PythonInterp REQUIRED)

option(PYTHON_COVERAGE "Python code coverage" OFF)
if(PYTHON_COVERAGE)
    message(STATUS "python coverage enabled")
    set(PYTHON_EXECUTABLE coverage run -p)
else()
    # run normally (broken under coveragepy)
    px4_find_python_module(jinja2 REQUIRED)
endif()

Catkin build 设置

include(px4_add_common_flags)
px4_add_common_flags()
px4_os_add_flags()

设置一些编译选项, 包括是否 Debug 编译, errorwarning 设置, 以及一些针对编译平台的选项设置

include(px4_metadata)

add_subdirectory(msg EXCLUDE_FROM_ALL)

px4_generate_airframes_xml(BOARD ${PX4_BOARD})

添加待编译目录msg, 添加生成文档编译目标

px4_add_git_submodule(TARGET git_driverframework PATH "src/lib/DriverFramework")
set(OS ${PX4_PLATFORM})
add_subdirectory(src/lib/DriverFramework/framework)
# List the DriverFramework drivers
if (DEFINED config_df_driver_list)
    message("DF Drivers: ${config_df_driver_list}")
endif()

set(df_driver_libs)
foreach(driver ${config_df_driver_list})
    add_subdirectory(src/lib/DriverFramework/drivers/${driver})
    list(APPEND df_driver_libs df_${driver})
    message("Adding DF driver: ${driver}")
endforeach()

驱动框架

set(ep_base ${PX4_BINARY_DIR}/external)
set_property(DIRECTORY PROPERTY EP_BASE ${ep_base})

# add external project install folders to build
link_directories(${ep_base}/Install/lib)
include_directories(${ep_base}/Install/include)
# add the directories so cmake won't warn
execute_process(COMMAND cmake -E make_directory ${ep_base}/Install/lib)
execute_process(COMMAND cmake -E make_directory ${ep_base}/Install/include)

外部项目

set(external_module_paths)
if (NOT EXTERNAL_MODULES_LOCATION STREQUAL "")
    message(STATUS "External modules: ${EXTERNAL_MODULES_LOCATION}")
    add_subdirectory("${EXTERNAL_MODULES_LOCATION}/src" external_modules)

    foreach(external_module ${config_module_list_external})
        add_subdirectory(${EXTERNAL_MODULES_LOCATION}/src/${external_module} external_modules/${external_module})
        list(APPEND external_module_paths ${EXTERNAL_MODULES_LOCATION}/src/${external_module})
    endforeach()
endif()

外部模块

option(CMAKE_TESTING "Configure test targets" OFF)
if (${PX4_CONFIG} STREQUAL "px4_sitl_test")
    set(CMAKE_TESTING ON)
endif()
if(CMAKE_TESTING)
    include(CTest) # sets BUILD_TESTING variable
endif()

# enable test filtering to run only specific tests with the ctest -R regex functionality
set(TESTFILTER "" CACHE STRING "Filter string for ctest to selectively only run specific tests (ctest -R)")

# if testing is enabled download and configure gtest
list(APPEND CMAKE_MODULE_PATH ${PX4_SOURCE_DIR}/cmake/gtest/)
include(px4_add_gtest)
if(BUILD_TESTING)
    include(gtest)
endif()

add_custom_target(test_results
        COMMAND GTEST_COLOR=1 ${CMAKE_CTEST_COMMAND} --output-on-failure -T Test -R ${TESTFILTER} USES_TERMINAL
        DEPENDS
            px4
            examples__dyn_hello
            test_mixer_multirotor
        USES_TERMINAL
        COMMENT "Running tests"
        WORKING_DIRECTORY ${PX4_BINARY_DIR})
set_target_properties(test_results PROPERTIES EXCLUDE_FROM_ALL TRUE)

测试

add_library(parameters_interface INTERFACE)

include(px4_add_library)
add_subdirectory(src/lib EXCLUDE_FROM_ALL)

add_subdirectory(src/platforms EXCLUDE_FROM_ALL)
add_subdirectory(src/modules/uORB EXCLUDE_FROM_ALL) # TODO: platform layer
add_subdirectory(src/drivers/boards EXCLUDE_FROM_ALL)

if(EXISTS "${PX4_BOARD_DIR}/CMakeLists.txt")
    add_subdirectory(${PX4_BOARD_DIR})
endif()
foreach(module ${config_module_list})
    add_subdirectory(src/${module})
endforeach()

添加子模块

# must be the last module before firmware
add_subdirectory(src/lib/parameters EXCLUDE_FROM_ALL)
target_link_libraries(parameters_interface INTERFACE parameters)

添加parameters编译选项这个很重要因为系统需要它.

# firmware added last to generate the builtin for included modules
add_subdirectory(platforms/${PX4_PLATFORM})

添加platforms/${PX4_PLATFORM} 目录中的编译配置文件, 这个是针对不同平台的编译设置的入口.

set(uorb_graph_config ${PX4_BOARD})

set(graph_module_list "")
foreach(module ${config_module_list})
    set(graph_module_list "${graph_module_list}" "--src-path" "src/${module}")
endforeach()
            
add_custom_command(OUTPUT ${uorb_graph_config}
    COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/uorb_graph/create.py
        ${module_list}
        --exclude-path src/examples
        --file ${PX4_SOURCE_DIR}/Tools/uorb_graph/graph_${uorb_graph_config}
    WORKING_DIRECTORY ${PX4_SOURCE_DIR}
    COMMENT "Generating uORB graph"
)
add_custom_target(uorb_graph DEPENDS ${uorb_graph_config})

uorb

#=============================================================================
# Doxygen
#
option(BUILD_DOXYGEN "Build doxygen documentation" OFF)

if (BUILD_DOXYGEN)
    find_package(Doxygen)
    if (DOXYGEN_FOUND)
        # set input and output files
        set(DOXYGEN_IN ${CMAKE_SOURCE_DIR}/Documentation/Doxyfile.in)
        set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

        # request to configure the file
        configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)

        # note the option ALL which allows to build the docs together with the application
        add_custom_target(doxygen ALL
            COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
            COMMENT "Generating documentation with Doxygen"
            DEPENDS uorb_msgs parameters
            VERBATIM
            USES_TERMINAL
            )

    else()
        message("Doxygen needs to be installed to generate documentation")
    endif()
endif()

Doxygen 文档

file(GLOB_RECURSE yaml_config_files ${PX4_SOURCE_DIR}/src/modules/*.yaml
    ${PX4_SOURCE_DIR}/src/drivers/*.yaml ${PX4_SOURCE_DIR}/src/lib/*.yaml)
add_custom_target(metadata_parameters
    COMMAND ${CMAKE_COMMAND} -E make_directory ${PX4_BINARY_DIR}/docs
    COMMAND ${PYTHON_EXECUTABLE}
    ${PX4_SOURCE_DIR}/Tools/serial/generate_config.py --all-ports --params-file ${PX4_SOURCE_DIR}/src/generated_serial_params.c --config-files ${yaml_config_files}
    COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/parameters/px_process_params.py
        --src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d`
        --inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml
        --markdown ${PX4_BINARY_DIR}/docs/parameters.md
    COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/src/lib/parameters/px_process_params.py
        --src-path `find ${PX4_SOURCE_DIR}/src -maxdepth 4 -type d`
        --inject-xml ${PX4_SOURCE_DIR}/src/lib/parameters/parameters_injected.xml
        --xml ${PX4_BINARY_DIR}/docs/parameters.xml
    COMMENT "Generating full parameter metadata (markdown and xml)"
    USES_TERMINAL
)

metadata_parameters 编译目标

add_custom_target(metadata_module_documentation
    COMMAND ${CMAKE_COMMAND} -E make_directory ${PX4_BINARY_DIR}/docs
    COMMAND ${PYTHON_EXECUTABLE} ${PX4_SOURCE_DIR}/Tools/px_process_module_doc.py -v --src-path ${PX4_SOURCE_DIR}/src
        --markdown ${PX4_BINARY_DIR}/docs/modules
    COMMENT "Generating module documentation"
    USES_TERMINAL
)

metadata_module_documentation 编译目标

add_custom_target(all_metadata
    DEPENDS
        metadata_airframes
        metadata_parameters
        metadata_module_documentation
)

所有的文档目标

set(CPACK_PACKAGE_NAME ${PROJECT_NAME}-${PX4_CONFIG})
set(CPACK_PACKAGE_VERSION ${PX4_GIT_TAG})
set(CPACK_PACKAGE_CONTACT ${package-contact})
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) # TODO: review packaging for linux boards
set(CPACK_DEBIAN_PACKAGE_SECTION "devel")
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "The PX4 Pro autopilot.")
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PX4_CONFIG}-${PX4_GIT_TAG}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PX4_GIT_TAG}")
set(CPACK_SOURCE_GENERATOR "ZIP;TBZ2")
set(CPACK_PACKAGING_INSTALL_PREFIX "")
set(CPACK_SET_DESTDIR "OFF")

if ("${CMAKE_SYSTEM}" MATCHES "Linux")
    set(CPACK_GENERATOR "TBZ2")
    find_program(DPKG_PROGRAM dpkg)
    if (EXISTS ${DPKG_PROGRAM})
        list (APPEND CPACK_GENERATOR "DEB")
    endif()
else()
    set(CPACK_GENERATOR "ZIP")
endif()

include(CPack)

3 参考文献

[1]: CMake Cookbook
[2]: Professional CMake – A Pratical Guide
[3]: https://github.com/ruslo/CGold

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PX4 CMakeLists.txt 文件剖析 的相关文章

随机推荐

  • C++ 智能指针学习

    网上找了一篇很棒的文章 转载自 xff1a https www jianshu com p bf8de014e5c2 C Java python和go等语言中都有垃圾自动回收机制 xff0c 在对象失去引用的时候自动回收 xff0c 而且基
  • 记面试遇到的一个智力题:追击问题

    一个带环的单链表 xff0c 一个快指针 xff08 每次走三步 xff09 xff0c 一个慢指针 xff08 每次走一步 xff09 xff0c 请问这两个指针可能无法相遇吗 xff1f 解 xff1a 假设慢指针入环时 xff0c 快
  • 面试经典题 手撸LRU

    1 C与C 43 43 混搭写法 struct LRUCacheNode int key int value LRUCacheNode prev LRUCacheNode next LRUCacheNode key 0 value 0 pr
  • 腾讯8.23号笔试 刷木板题 DP

    作者 xff1a 夜 xffe3 太美 链接 xff1a https www nowcoder com discuss 486642 type 61 2 来源 xff1a 牛客网 题意 有n xff08 n在5000内 xff09 块木板
  • 京东2018笔试题 神奇数

    题目 东东在一本古籍上看到有一种神奇数 如果能够将一个数的数字分成两组 其中一组数字的和等于另一组数字的和 我们就将这个数称为神奇数 例如242就是一个神奇数 我们能够将这个数的数字分成两组 分别是 2 2 以及 4 而且这两组数的和都是4
  • 绑定mac地址与网卡驱动wlan

    按照之前博客https blog csdn net Lin QC article details 90717218的配置 xff0c 我们可以在树莓派上实现双网卡 xff0c 但是再多次试验中发现 xff0c 每次重启后 xff0c 网卡的
  • 在树莓派上ROS MAVROS的安装使用

    首先 xff0c 我购买的是树莓派3B 43 xff0c 比较新款 xff0c 所以装不了太老的树莓派系统 xff0c 安装的是树莓派官方提供的Raspbian Stretch系统 树莓派系统安装过程较为简单 xff0c 且官网教程详细 x
  • APP引导页UI设计素材模板|轻松留下完美的第一印象

    App首次引导页是当你第一次打开一款应用的时候你看到的引导页 xff0c 它们在你未使用产品之前提前告知产品的主要功能与特点 先来看看 像素精简版引导UI工具包 好的实际案例 xff0c 让初学者更友好 xff01 美丽的用户界面 xff0
  • px4 offboard外部控制仿真

    官网中http dev px4 io en ros mavros offboard html xff0c 只给示例代码 xff0c 却不告诉怎么用 xff0c 实在有点坑 xff0c 还好参照网上的一些博客 xff0c 找到了使用方法 首先
  • POST和GET方法的区别与联系

    错误的一个理论就是 xff0c get是从服务器拿数据 xff0c 而post是给服务器传数据 两者其实都是从服务器端拿数据 xff0c 只是一些细节不同罢了 历史 get和post是HTTP与服务器交互的方式 xff0c 说到方式 xff
  • Dronekit 搭配使用Ardupilot 和 PX4

    Dronekit是一个与无人机飞控搭配使用 xff0c 方便开发者使用代码控制无人机 个人认为它会比搭建ros来控制无人机更容易上手一些 对于Dronekit xff0c PX4被支持的较少 xff0c 不可以进行模式切换 xff0c 而对
  • 堆栈存放什么

    此乃转载别人发表 xff0c 作为知识点保存积累 一 xff1a 概念 1 栈 xff1a 当程序进入一个方法时 xff0c 会为这个方法单独分配一块私属存储空间 xff0c 用于存储这个方法内部的局部变量 xff0c 当这个方法结束时 x
  • 嵌入式实时操作系统ucosii原理及应用(任哲)-- --阅读笔记2

    本文是 嵌入式实时操作系统ucosii原理及应用 xff08 任哲 xff09 一书第三章的阅读笔记 xff0c 知识点多为摘录 xff0c 若希望深入了解 xff0c 请购买该书认真研读 由于一些知识比较零散 xff0c 记起来不大方便
  • 如何做项目总结与汇报

    在我们测试工作过程中 xff0c 由于公司业务发展 xff0c 快速迭代等原因 xff0c 我们遇到的项目以小项目居多 更新界面元素 xff0c 上个活动页 xff0c 优化一下原有的功能等等 xff0c 加上事情繁琐 xff0c 任务多
  • 手机安装linux deploy 安装和配置

    最近在淘了一款二手三星的sw 2014 正好最近正在研究智能家居 就想用它来搭建domoticz来管理 xff0c 虽然手头也有一块吃灰的树莓派3b 但是觉得用树莓派搭建有点浪费 xff0c 索性就用这款手机 为什么不用temux xff1
  • 国家分级保护规范要求解读

    仅就项目建设流程而言 xff0c 涉密信息系统建设使用单位应依据 涉及国家秘密的信息系统分级保护管理办法 国保发 2005 16号 确定系统等级 xff0c 结合本单位业务需求和涉密信息制定安全保密需求 xff0c 依据国家保密标准 BMB
  • PX4 编译分析之Airframe文档生成

    PX4 编译分析之Airframe文档生成 本文假设已经阅读了 PX4 的 1 Makefile分析 2 CMakeLists txt分析 这里要分析的是 make airframe metadata 的指令 在 Makefile 文件中找
  • PX4编译文件 Makefile 剖析

    PX4编译文件 Makefile 剖析 当我们执行 cd Firmware进入PX4源码目录 然后make 的时候 我们会看到一串输出基本如下 第一次编译会有更多的输出 2 Built target df driver framework
  • 如何使用vscode运行和调试c/c++程序

    众所周知 vscode是个万金油 xff0c 而且体型轻巧 xff0c 拓展插件多 xff0c 非常适合初学者编程 那么如何使用vscode进行c c 43 43 程序的运行 xff1f 首先必须确保mingw64正确安装 通过以下链接下载
  • PX4 CMakeLists.txt 文件剖析

    PX4 CMakeLists txt 文件剖析 前面对于 PX4 的 Makefile 已经做了比较详细的分析 见这里 这里进一步对 PX4 的 CMakeLists txt 文件结构进行进一步的分析 1 CMake 简述 CMake 是一