CMake文件CMakeLists.txt,实例精讲

 Refer: 官网cmake-commands(7) — CMake 3.7.2 Documentation

 一、 CMakeLists.txt  必杀技 

#*************** CMakeLists.txt ********************* 
# CMake 最低版本号要求 
cmake_minimum_required(VERSION 3.16)
# CMake 内置编译器
# arm嵌入式c,编译器使用这个
set(CMAKE_C_COMPILER "arm-linux-gnueabihf-gcc")
# arm嵌入式c++,编译器使用这个
set(CMAKE_CXX_COMPILER "arm-linux-gnueabihf-g++")

# This project requires C++11.
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# CMake 编译器选项
# 方式一:This project requires C/C++ flags.
set(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS} -std=gnu99")
set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -rdynamic -O3 -fPIC -ggdb -std=c++11 -Wall -Wno-deprecated -Werror -Wno-unused-function -Wno-builtin-macro-redefined -Wno-deprecated-declarations")

# 方式二:如果使用 add_compile_options 则对所有编译器生效(包括c和c++编译器) add_compile_options(-fvisibility=hidden) // -std=gnu99或-std=c++11-std=gnu99 -O3 -g -W -Wall
add_compile_definitions(_ARM_GCC_)

 

# 编译命令后缀 因为使用了线程,需要添加-lpthread 
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lpthread")
# c++使用这个
set(CMAKE_CXX_FLAGS -lpthread)
# 自定义源码编译选项, 可以在cmakelist文件接下来的部分使用
# 与set 的区别, set有更丰富的 使用方法, 而option只能定义 ON 或者 OFF
option(LEVELDB_BUILD_TESTS "Build LevelDB's unit tests" ON)
option(LEVELDB_BUILD_BENCHMARKS "Build LevelDB's benchmarks" ON)
option(LEVELDB_INSTALL "Install LevelDB's header and library" ON)


# 设置工程名、版本等信息
#add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])project(<PROJECT-NAME>
[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
        [LANGUAGES <language-name>...])
project (CANopen_Linux VERSION 1.22.0 LANGUAGES C CXX)
# 设置项目的名称并将名称存储在 PROJECT_NAME 变量中。此外,这会设置变量
# PROJECT_SOURCE_DIR、<PROJECT-NAME>_SOURCE_DIR
# PROJECT_BINARY_DIR、<PROJECT-NAME>_BINARY_DIR
# 添加源代码宏定义, 如果你的代码中定义了#ifdef ENABLE_DEBUG #endif,这个代码块就会生效。
# CMake中的add_definitions命令用于为当前路径以及子目录的源文件,在编译中添加-D定义标志
add_definitions (-DENABLE_DEBUG -DABC=10)


# 指定"引入"头文件路径   相当于gcc命令的-I选项的作用
#include_directories ([AFTER|BEFORE] [SYSTEM] <dir1> [<dir2> ...])
include_directories (main CANopen/inc CANopen/inc/linux )
include_directories (CANopen/dictionary CANopen/hardware)
# 指定"引入"链接库文件路径  相当于gcc命令的-L选项的作用
#link_directories(directory1 directory2 ...)
link_directories ("CANpen/lib" "../util/lib")
# 指定"引入"待链接的库文件      相当于gcc命令的-l选项的作用
#link_libraries([item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)
link_libraries (“/home/server/third/lib/libcommon.a” "libpthread.a")

# 自动收集指定路径下的源代码  用于“自动”将指定目录下的“所有”源文件列表,赋值给一个变量。如果只指定目录下“部分”源文件,就只能使用set(<variable> <value>... [type] [docsring] [force])
#aux_source_directory (<dir> <variable>)
aux_source_directory (${PROJECT_SOURCE_DIR}/CANopen/src CANOPEN_SRC)                #添加canopen源代码目录
aux_source_directory (${PROJECT_SOURCE_DIR}/CANopen/hardware CANOPEN_HARDWARE) #添加硬件源代码目录
aux_source_directory (${PROJECT_SOURCE_DIR}/CANopen/dictionary CANOPEN_DICTIONARY) #添加词典源代码目录
aux_source_directory (${PROJECT_SOURCE_DIR}/main MAIN_SRCS) #添加main程序入口代码目录

# 生成·可执行目标canopen_exe 
add_executable(<exe_file_name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 ...])
add_executable (canopen_exe ${MAIN_SRCS} ${CANOPEN_HARDWARE} ${CANOPEN_SRC} ${CANOPEN_DICTIONARY})

# add_library 命令,生成动态/静态链接库, 即添加一个目标, 后续会根据目标名进行区分
# 语法 : ADD_LIBRARY(<name> [STATIC | SHARED | MODULE] [source1] [source2 ...])
# add_library (leveldb SHARED "") # 生成动态链接目标
# add_library (leveldb STATIC "") # 生成静态链接目标(默认静态)
# add_executable (leveldb "") # 生成可执行文件
# 指定生成目标,所使用的源码文件列表
#target_sources(<target>
# <INTERFACE|PUBLIC|PRIVATE> [items1...]
# [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
# 指定链接库leveldb 所需的文件列表
target_sources (leveldb # PROJECT_SOURCE_DIR是根目录
PRIVATE
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
"${PROJECT_SOURCE_DIR}/db/builder.cc"
"${PROJECT_SOURCE_DIR}/db/builder.h"
"${PROJECT_SOURCE_DIR}/db/c.cc"
"${PROJECT_SOURCE_DIR}/db/db_impl.cc"
"${PROJECT_SOURCE_DIR}/db/db_impl.h"
"${PROJECT_SOURCE_DIR}/db/db_iter.cc"
"${PROJECT_SOURCE_DIR}/db/db_iter.h"
"${PROJECT_SOURCE_DIR}/db/dbformat.cc")
# target_sources 可以不连续, 在后面也可以再次定义,会自动视为append, 例如下面需要根据平台引入不同的文件
if (WIN32)
    target_sources(leveldb
    PRIVATE
    "${PROJECT_SOURCE_DIR}/util/env_windows.cc"
    "${PROJECT_SOURCE_DIR}/util/windows_logger.h"
)
else (WIN32)
    target_sources(leveldb
    PRIVATE
    "${PROJECT_SOURCE_DIR}/util/env_posix.cc"
  "${PROJECT_SOURCE_DIR}/util/posix_logger.h"
)
endif (WIN32)

# 编译子文件夹的CMakeLists.txt, 如果子目录下有CMakeList.txt文件,可以通过该命令找到子目录进行编译
#add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
add_subdirectory (test)

 

三、link_libraries 和 target_link_libraries 区别(设置要链接的库文件的名称)

动态库与静态库的区别:https://juejin.cn/post/7541283508040679487

在cmake语法中,link_libraries 和 target_link_libraries是很重要的两个链接库的方式,虽然写法上很相似,但是功能上有很大区别:

1. link_libraries 用在 add_executable 之,target_link_libraries 用在 add_executable之

2. link_libraries用来链接静态库, target_link_libraries用来链接导入库,即按照header file + .lib + .dll方式隐式调用动态库的.lib库

3. link_libraries 将库链接到稍后添加的”所有“目标。  注意:因为全局有效,所以后来add_library  add_executable生成的所有目标都链接,所以慎用。 

4. target_link_libraries 指令作用是将目标文件与库文件进行链接,会修改原目标ELF程序中 rpath (全称是run-time search path)。仅仅目标文件有效。

 

关键字作用范围
PUBLIC 该目标和所有依赖它的目标都可见
INTERFACE 仅对依赖该目标的目标可见(但自身不可用)
PRIVATE 仅对该目标可见,依赖它的目标不可见

add_library(lib_demo
        cmd.cpp
        global.cpp
        md5.cpp)
link_libraries(lib_demo)
add_executable(demo
        main.cpp)

 

# cmake中使用第三方库的一般步骤
# 1. 设置头文件位置
#target_include_directories(<target> PRIVATE "<dir/include>")

 

# 2. 设置库文件搜索位置
#target_link_directories(<target> PRIVATE "<dir/lib>")

 

# 3. 指定需要链接的库(libXXX.a libXXX.dll直接写成XXX的形式即可)
# link library in static mode  
#target_link_libraries(<target>
      <PRIVATE|PUBLIC|INTERFACE> <item>...
     [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

target_link_libraries (demo libuuid.a )

三、include_directories 和 target_include_directories 区别

 ref: https://blog.csdn.net/Tommy_wxie/article/details/77698627?spm=1001.2014.3001.5506

 

四、find_package 和 find_library区别

 Refer: CMake4-指令4-2:find_package【用于查找并配置复杂的第三方软件包】【通过查找第三方库的.cmake的文件,并不是直接去找具体的动态库文件和头文件】【指定第三方库所在路径】_find package找不到包-CSDN博客https://blog.csdn.net/u013250861/article/details/127935779

 

posted @ 2022-12-02 12:02  suntroop  阅读(918)  评论(0)    收藏  举报