CMake入门01- 可执行文件

本文详细介绍了如何使用CMake从源码构建和链接静态库、动态库,包括创建可执行文件、对象库以及处理同名静态和动态库。还讨论了CMake的流程控制和选项设置,包括设置默认选项和处理选项依赖。此外,文章给出了具体示例,展示如何链接已生成的第三方库。

最简单的创建单个源文件CMakeLists.txt

创建可执行文件

# 设置满足条件的cmake最小版本
cmake_minimum_required(VERSION 3.25 FATAL_ERROR)
#设置项目名称,项目用到的语言
project(SingleSrc LANGUAGES CXX)
#生成可执行文件printHello, 添加源文件test01.cpp
add_executable(printHello test01.cpp)

在CMakeLists.txt目录执行以下命令即可构建可执行文件

mkdir -p build && cd build
cmake ..
cmake --build .

切换生成器(构建系统)

unix系统默认(Unix Makefile), 还有其他ninja之类的构建系统

mkdir -p build && cd build
cmake -G Ninja ..
cmake --build .

从源码构建和链接静态和动态库

构建和链接静态库

目录结构

.
├── build
├── CMakeLists.txt
├── readme.md
├── src
│   └── Helloworld.cpp
    ├── Message.cpp
    └── Message.hpp

CMakeLists.txt

cmake_minimum_required(VERSION 3.25.1 FATAL_ERROR)
project(CMakeLib LANGUAGES CXX)
#将Message源文件编译成静态库
#CMAKE_CURRENT_SOURCE_DIR当前cmakelists.txt文件所在目录
add_library(Message
STATIC
    ${CMAKE_CURRENT_SOURCE_DIR}/src/Message.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/src/Message.cpp
)
#Helloworld编译成可执行文件
add_executable(Helloworld ${CMAKE_CURRENT_SOURCE_DIR}/src/Helloworld.cpp)
#Message静态库链接到将helloworld文件
target_link_libraries(Helloworld Message)

CMAKE_CURRENT_SOURCE_DIR为当前CMakeLists.txt文件所在的目录。

add_library() 为创建静态或动态库,库名称自定(如Message), 静态库或动态库由两个关键字指定(STATICSHARED)。再添加生成库的源文件路径

target_link_libraries()将动态或静态库链接到项目文件中

执行以下命令

cd  build
cmake ..
cmake --build .

对象库

如果需一次性创建静态库和动态库,则使用OBJECT关键词,创建对象库。

cmake_minimum_required(VERSION 3.25.1 FATAL_ERROR)
project(CMakeLib LANGUAGES CXX)

add_library(Message
OBJECT
    ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/Message.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/Message.cpp
)

set_target_properties(Message 
##下两命令暂时不能缺
    PROPERTIES
        POSITION_INDEPENDENT_CODE 1
)

add_library(Message_shared
    SHARED
        $<TARGET_OBJECTS:Message>    
)
add_library(Message_static
    STATIC
        $<TARGET_OBJECTS:Message>
)
#Helloworld编译成可执行文件
add_executable(Helloworld ${CMAKE_CURRENT_SOURCE_DIR}/src/Helloworld.cpp)
#Message静态库链接到将helloworld文件
target_link_libraries(Helloworld Message_shared)

生成同名的静态和动态库

cmake_minimum_required(VERSION 3.25.1 FATAL_ERROR)
project(CMakeLib LANGUAGES CXX)

add_library(Message
OBJECT
    ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/Message.hpp
    ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/Message.cpp
)

set_target_properties(Message 
##下两命令暂时不能缺
    PROPERTIES
        POSITION_INDEPENDENT_CODE 1
)

add_library(Message_shared
    SHARED
        $<TARGET_OBJECTS:Message>    
)
#设置Message_shared库的属性
set_target_properties(Message_shared
    PROPERTIES
        OUTPUT_NAME "Message"
)

add_library(Message_static
    STATIC
        $<TARGET_OBJECTS:Message>
)
#设置Message_static库的属性
set_target_properties(Message_static
    PROPERTIES
        OUTPUT_NAME "Message"
)

#Helloworld编译成可执行文件
add_executable(Helloworld ${CMAKE_CURRENT_SOURCE_DIR}/src/Helloworld.cpp)
#Message静态库链接到将helloworld文件
target_link_libraries(Helloworld Message_shared)

关键点:

  • add_library中targetName需要有区分,不然在target_link_libraries中无法区分链接哪个库

链接已生成的第三方库

假设系统中已经有了第三方库libMessage_shared.so文件
则CMakeLists.txt如下

cmake_minimum_required(VERSION 3.25.1 FATAL_ERROR)
project(CMakeLib LANGUAGES CXX)
#添加要链接库.so文件的路径
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty)
#Helloworld编译成可执行文件
add_executable(Helloworld ${CMAKE_CURRENT_SOURCE_DIR}/src/Helloworld.cpp)
#Message动态库链接到将helloworld文件
target_link_libraries(Helloworld libMessage_shared.so)

Cmake流程控制,及选项设置

文件结构如下

.
├── build
├── CMakeLists.txt
├── readme.md
├── src
│   └── Helloworld.cpp
└── thirdparty
    └── Message
        ├── include
        │   └── Message.hpp
        ├── lib
        │   ├── libMessage.a
        │   └── libMessage.so
        └── src
            └── Message.cpp

7 directories, 7 files

CMakeLists.txt文件

cmake_minimum_required(VERSION 3.25.1 FATAL_ERROR)
project(IfelseOption LANGUAGES CXX)
option(use_Message_shared "use Message shared lib" 1)
#添加库 .h头文件路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/Message/include)
#添加链接第三方库.so或.a文件的路径
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/Message/lib)
#生成可执行文件
add_executable(Helloworld ${CMAKE_CURRENT_SOURCE_DIR}/src/Helloworld.cpp)
if(use_Message_shared)
    target_link_libraries(Helloworld libMessage.so) 
    message(STATUS "use Message shared lib")
else()
    target_link_libraries(Helloworld libMessage.a)
    message(STATUS "use Message STATIC lib")
endif()

option用于设置默认选项(0==off==OFF==false==FALSE, 1==on==ON==ture==TRUE) ,其中if()else()endif()用于流程控制。

执行以下命令

[root build]# cmake -D use_Message_shared=0 ..
-- The CXX compiler identification is GNU 10.2.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/rh/devtoolset-10/root/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- use Message STATIC lib
-- Configuring done
-- Generating done
-- Build files have been written to: /home/work/CmakeLearning/part01/IfelseOption02/build
[root build]# cmake --build .
[ 50%] Building CXX object CMakeFiles/Helloworld.dir/src/Helloworld.cpp.o
[100%] Linking CXX executable Helloworld
[100%] Built target Helloworld
[root build]# ll
total 52
-rw-r--r-- 1 root root 13009 Dec 29 09:06 CMakeCache.txt
drwxr-xr-x 6 root root  4096 Dec 29 09:06 CMakeFiles
-rw-r--r-- 1 root root  1694 Dec 29 09:06 cmake_install.cmake
-rwxr-xr-x 1 root root 18184 Dec 29 09:06 Helloworld
-rw-r--r-- 1 root root  5490 Dec 29 09:06 Makefile
[root build]# ./Helloworld
This is my very nice message:
Hello, CMake World!
This is my very nice message:
Goodbye, CMake World

cmake -D use_Message_shared=0 .. 命令后输出-- use Message STATIC lib说明设置use_Message_shared=0成功。

选项依赖

在实际工程中,一些编译选项依赖其他选项。则可以使用以下实现设置默认选项值和选项依赖。

include(CMakeDependentOption)
# second option depends on the value of the first
cmake_dependent_option(
    MAKE_STATIC_LIBRARY "Compile sources into a static library" OFF
    "USE_LIBRARY" ON
    )
# third option depends on the value of the first
cmake_dependent_option(
    MAKE_SHARED_LIBRARY "Compile sources into a shared library" ON
    "USE_LIBRARY" ON
    )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值