CMake学习(4)—— 使用技巧

本文介绍了如何使用CMake在Visual Studio下创建Qt项目,并设置不弹出控制台窗口。同时,针对MSVC环境,解决UTF-8编码问题,确保源码中文字符正常显示。通过在CMakeLists.txt中修改add_executable参数和添加编译选项,可以实现所需功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建工程时指定构建类型

cmake -B 工程目录 -DCMAKE_BUILD_TYPE=构建类型
构建类型有:Debug(默认),ReleaseRelWithDebInfoMinSizeRel
例如:cmake -B build -DCMAKE_BUILD_TYPE=Release

搭建基于Visual Studio的Qt项目,设置不弹控制台窗口

CMakeLists.txt中,修改add_executable,添加WIN32项(标志该程序为窗口程序),例如:

add_executable(test WIN32 ${src_files})

MSVC环境下支持UTF8

MSVC对于UTF-8 without BOM格式支持不好,如果源码含有中文字符则会显示乱码,需要指定编译选项:

if (MSVC)
    add_compile_options("/utf-8") # 添加UTF8编码支持, 必须在add_executable前调用
endif()

或在Visual Studio 2019工程手动设置,参考:VS中utf-8无bom编码的源文件中文乱码

减少非必要的库依赖 LINKER:–as-needed

编译后,目标文件有时会依赖一些非必要的库(程序中没使用到的),例如,代码中未使用到系统函数库libm,但是ldd目标文件时还是能看到对它的依赖

root@linux:/root/workspace/test_cpp/build# ldd test_cpp
        linux-vdso.so.1 (0x0000007f91217000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f9111e000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f90fab000)
        /lib/ld-linux-aarch64.so.1 (0x0000007f911e7000)

可以在链接依赖库前添加设置:
target_link_options(目标名 PRIVATE LINKER:--as-needed)
这样可以减少最终目标文件的依赖性,因为它告诉链接器只链接那些实际被程序使用的库中的符号。如果库中的符号没有被用到,那么这个库就不会被链接到最终的可执行文件中。
例如:

# CMake版本
cmake_minimum_required(VERSION 3.18.0)
# 工程名
project(test_cpp)
# 构建可执行文件
add_executable(${PROJECT_NAME} main.cpp)

# 设置非必要性的依赖库
target_link_options(${PROJECT_NAME} PRIVATE LINKER:--as-needed)

# 链接依赖库文件
target_link_libraries(${PROJECT_NAME})

编译后,目标文件依赖结果如:

root@linux:/root/workspace/test_cpp/build# ldd test_cpp
        linux-vdso.so.1 (0x0000007fbe396000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007fbe12a000)
        /lib/ld-linux-aarch64.so.1 (0x0000007fbe366000)

链接 libgcc 和 libstdc++ 静态库

正常编译出来的目标文件是动态链接libgcclibstdc++库,例如:

root@linux:/root/workspace/test_cpp/build# ldd test_cpp
        linux-vdso.so.1 (0x0000007f9f123000)
        libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007f9eef0000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007f9ee45000)
        libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007f9ee21000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007f9ecae000)
        /lib/ld-linux-aarch64.so.1 (0x0000007f9f0f3000)

如果希望编译出来的目标文件以静态链接的方式包含libgcclibstdc++库,则可以在链接依赖库文件前进行设置:
方法一:
target_link_options(目标名 PRIVATE -static-libgcc -static-libstdc++)
方法二:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
例如:

# CMake版本
cmake_minimum_required(VERSION 3.18.0)
# 工程名
project(test_cpp)
# 构建可执行文件
add_executable(${PROJECT_NAME} main.cpp)

# 设置链接器标志以使用静态版本的 libgcc 和 libstdc++
# 方法一
target_link_options(${PROJECT_NAME} PRIVATE LINKER:--as-needed -static-libgcc -static-libstdc++)
# 方法二
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")

# 链接依赖库文件
target_link_libraries(${PROJECT_NAME})

编译后,目标文件依赖结果如:

root@linux:/root/workspace/test_cpp/build# ldd test_cpp
        linux-vdso.so.1 (0x0000007fbe396000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007fbe29d000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007fbe12a000)
        /lib/ld-linux-aarch64.so.1 (0x0000007fbe366000)

链接 libm 静态库

需要查找系统中libm.a静态库文件,如果找到的话,再添加到链接依赖库中,例如:

# CMake版本
cmake_minimum_required(VERSION 3.18.0)
# 工程名
project(test_cpp)
# 构建可执行文件
add_executable(${PROJECT_NAME} main.cpp)
# 设置链接器标志以使用静态版本的 libgcc 和 libstdc++
target_link_options(${PROJECT_NAME} PRIVATE LINKER:--as-needed -static-libgcc -static-libstdc++)

# 查找libm的静态依赖库
find_library(LIBM_LIBRARY NAMES libm.a)
message(STATUS "LIBM_LIBRARY: "${LIBM_LIBRARY})

# 链接依赖库文件
if(MATH_LIBRARY)
    target_link_libraries(${PROJECT_NAME} ${LIBM_LIBRARY})
else()
    target_link_libraries(${PROJECT_NAME})
endif()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值