PX4 CMakeLists.txt 文件剖析

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

1 CMake 简述

CMake 是一个 DSL( Domain Specific Language), 主要用来辅助对代码的编译配置和管理, 其具有跨平台, 可维护性较好的特点, 目前在 C++ 项目中得到了普遍应用. 下面是对 CMAKE的简单介绍,如需了解更多,请参考 CMake Documentation和Modern CMake等文档及教程。
CMake 中包含了针对编译配置的特殊函数和变量定义, 语法类C, 包括了控制语句, 模块导入语句, 字符串处理行数等较为通用的功能.

CMake 中的文件结构按功能大致可以分为, Directories, Script 和 Module. 其中 Module 可以通过include 命令导入, include 命令会在 CMAKE_MODULE_PATH 下寻找指定的模块. 下表列出了一些出现频率较高的指令

CMake 指令列表 指令说明
cmake_minimum_required cmake 的最小的版本
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 --tagsOUTPUT_VARIABLE PX4_GIT_TAGOUTPUT_STRIP_TRAILING_WHITESPACEWORKING_DIRECTORY ${PX4_SOURCE_DIR))

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

define_property(GLOBAL PROPERTY PX4_MODULE_LIBRARIESBRIEF_DOCS "PX4 module libs"FULL_DOCS "List of all PX4 module libraries"                 )define_property(GLOBAL PROPERTY PX4_MODULE_PATHSBRIEF_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_configsRELATIVE "${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 presentstring(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 prefixif ((${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_defaultif ((${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 directoriesinclude(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_resultsCOMMAND GTEST_COLOR=1 ${CMAKE_CTEST_COMMAND} --output-on-failure -T Test -R ${TESTFILTER} USES_TERMINALDEPENDSpx4examples__dyn_hellotest_mixer_multirotorUSES_TERMINALCOMMENT "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 filesset(DOXYGEN_IN ${CMAKE_SOURCE_DIR}/Documentation/Doxyfile.in)set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)# request to configure the fileconfigure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)# note the option ALL which allows to build the docs together with the applicationadd_custom_target(doxygen ALLCOMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}COMMENT "Generating documentation with Doxygen"DEPENDS uorb_msgs parametersVERBATIMUSES_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_parametersCOMMAND ${CMAKE_COMMAND} -E make_directory ${PX4_BINARY_DIR}/docsCOMMAND ${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.mdCOMMAND ${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.xmlCOMMENT "Generating full parameter metadata (markdown and xml)"USES_TERMINAL
)

metadata_parameters 编译目标

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

metadata_module_documentation 编译目标

add_custom_target(all_metadataDEPENDSmetadata_airframesmetadata_parametersmetadata_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

PX4 CMakeLists.txt 文件剖析相关推荐

  1. CMakeLists.txt文件如何编写?(一 基础篇)

    本文首发于微信公众号「3D视觉工坊」--CMakeLists.txt文件如何写? 本文以linux平台下CMakeLists.txt文件书写方法总结. 一 开头通用模块 1.1 cmake版本要求 c ...

  2. Cmake知识----编写CMakeLists.txt文件编译C/C++程序

    1.CMake编译原理 CMake是一种跨平台编译工具,比make更为高级,使用起来要方便得多.CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt ...

  3. ROS学习(六):CMakeLists.txt 文件

    CMakeLists.txt 文件 为 CMake build 文件.是 CMake 编译系统中软件包的输入.描述如何编译代码.安装到哪里. http://wiki.ros.org/catkin/CM ...

  4. 熟悉 CMake(二)—— 以一个实例说明 CMakeLists.txt 文件的编写

    原文请见 cmake使用总结(转)-工程主目录CMakeList文件编写 在 Linux 下进行开发很多人选择编写 makefile 文件进行项目环境搭建,而makefile 文件依赖关系复杂,工作量 ...

  5. 在CMakeLists.txt文件中包含Eigen

    挺简单的一个问题,弄了好半天,主要是关于CMAKELISTS的一些语法和Eigen的库记不清楚了:这里整理一下做一个记录: 首先说Eigen只有头文件(headers only),只需要设定一个包含路 ...

  6. CMakeLists.txt文件常见编译错误

    错误一:目标文件未成功链接到该函数HelloFunc所在的库文件或者未安装该库文件 CMakeFiles/hello.dir/main.c.o:在函数'main'中: main.c:(.text+0x ...

  7. cmake 编译文件 CMakeLists.txt 语法介绍与实例演练

    一.Cmake 简介 cmake 是一个跨平台.开源的构建系统.它是一个集软件构建.测试.打包于一身的软件.它使用与平台和编译器独立的配置文件来对软件编译过程进行控制. 二.常用命令 1. 指定 cm ...

  8. Ubuntu下使用cmake结合CmakeLists.txt生成makefile文件并进行编译

    转自1:https://www.cnblogs.com/cv-pr/p/6206921.html 转自2:https://blog.csdn.net/qqwangfan/article/details ...

  9. android 多个c文件编译成一个so,AndroidStudio使用CMakeLists.txt编译多个so库

    对于单个so库编译就不说了,AndroidStudio可以直接生成单个so库编译的模板 对于实际项目中,多用到的是好几个库,下面说一下编译多个so库的情况 TIM图片20180927155108.pn ...

最新文章

  1. Windows10下SSH远程拷贝文件
  2. JavaScript window
  3. 用Tableau画可调整的树状图(Tree Diagram)
  4. 增加外键时候的一个小错误
  5. C++ Applications
  6. ar路由器 pppoe下发ipv6 dns_IPv6网络设置各种疑难杂症诊疗区
  7. linux中如何让vim永久显示行号(永久显示+临时显示)
  8. python网络编程学习笔记(6):Web客户端访问
  9. SoftGrid教程系列
  10. 【ubuntu操作系统入门】Ubuntu常用命令大全二
  11. python 基本数据类型及其功能-2-字符串 重点命令
  12. element table多选表格_element-ui 表格打印
  13. 2018年中国财富管理才真正迎来发展元年
  14. 【FPGA】基于bt1120时序设计实现棋盘格横纵向灰阶图数据输出
  15. dsp2812 linux开发板,自制DSP2812开发板
  16. VARCHART XGantt_v5.1用户手册:如何把控件放在表单上
  17. 2021中兴捧月杯算法大赛模面大赛总结
  18. EasyX---快速入门---(一)基本绘图与文字绘制
  19. Android美团评分组件及消息提示框自我定制(14)
  20. WAV音频信号文件的相关知识

热门文章

  1. pytorch学习笔记(6):GPU和如何保存加载模型
  2. 侏罗纪世界手游显示无法登陆到服务器,《侏罗纪世界手游》不能玩 解决攻略...
  3. 机器找不到 libcudnn.so.6
  4. android异步编程,AsyncTask简单的异步编程android 中的实现
  5. java工程转maven工程_Java工程转换为Maven工程
  6. HDU 1556 Color the ball (数状数组)
  7. PostgreSQL 优化器案例之 - order by limit 索引选择问题
  8. ruby编程API阅读之BasicObject阅读
  9. 浏览器九宫格的简单实现 - 蒋宇捷的专栏 - 博客频道 - CSDN.NET
  10. 微软从安卓那里获取的盈利比重WinPhone 7还多