cmake 简单使用

本文介绍了一个使用CMake构建的C++ demo项目的结构与配置。详细解析了CMakeLists.txt文件中的各种指令,包括编译选项设置、源文件管理、第三方库链接等。并通过示例解释了target_link_libraries命令中PUBLIC、PRIVATE、INTERFACE参数的区别。

cmake 构建的C++ demo 工程

  • 工程结构
./project 
 |---- my_demo/ 
 |      |---- demo.cpp
 |      `---- others.cpp
 |---- test/ 
 |      |---- test.cpp
 |      `---- CMakeLists.txt 
 |---- CMakeLists.txt 
 `---- run_build.sh 
  • CMakeLists.txt
PROJECT(my_demo)

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)  

set(MY_DEMO_VERSION 3.5) 

# default C / CXX flags
set(CMAKE_C_FLAGS " -g -ggdb -O0 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")
set(CMAKE_CXX_FLAGS " -g -ggdb -O0 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")

set(CMAKE_C_FLAGS_DEBUG " -g -ggdb -O0 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")
set(CMAKE_CXX_FLAGS_DEBUG " -g -ggdb -O0 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")

set(CMAKE_C_FLAGS_RELEASE " -O3 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")
set(CMAKE_CXX_FLAGS_RELEASE " -O3 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")

set(CMAKE_C_FLAGS_MINSIZEREF " -Os -Wall  -fpic -fPIC -D_LARGEFILE64_SOURCE")
set(CMAKE_CXX_FLAGS_MINSIZEREF " -Os -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")

set(CMAKE_C_FLAGS_RELWITHDEBINFO " -O2 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO " -O2 -Wall -fpic -fPIC -D_LARGEFILE64_SOURCE")

set(CMAKE_C_FLAGS_COVERAGE " ${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS_COVERAGE " ${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverag")

set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/build/${CMAKE_BUILD_TYPE}/lib)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/build/${CMAKE_BUILD_TYPE}/bin)
# name object files as xxx.o instead of xxx.cpp.o 
set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)
set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)   

# add include dirs  -> -I 
include_directories(${CMAKE_BINARY_DIR})
include_directories(${APR_INCLUDE_DIR})
include_directories(${APR_UTIL_INCLUDE_DIR})
include_directories(${MINIXML_INCLUDE_DIR})
include_directories(${CURL_INCLUDE_DIR})
include_directories(${MODULE_SDK_INCLUDE_DIR})

# add lib dirs -> -L 
#link_directories("/usr/lib64/")
link_directories(${THIRDPARTY_LIB_PATH})
link_directories(${MODULE_SDK_LIB_PATH})

message(STATUS "CPPPATH:"  
               ${APR_INCLUDE_DIR}
               ${APR_UTIL_INCLUDE_DIR} 
               ${MINIXML_INCLUDE_DIR} 
               ${CURL_INCLUDE_DIR})

message(STATUS  "LIB_PATH:${THIRDPARTY_LIB_PATH}")    
find_library(EXPAT_LIBRARY  libexpat.a) 
find_library(UUID_LIBRARY  libuuid.a ${THIRDPARTY_LIB_PATH}) 
IF (UUID_LIBRARY) 
    message(STATUS  ${UUID_LIBRARY})
else()
    message(WARN "libuuid.a not find")
endif()

# add source files 
aux_source_directory(my_demo DEMO_SRC)
message(STATUS ${DEMO_SRC})

# compile targets: libmy_demo.so and libmy_demo_static.a 
add_library(${CMAKE_PROJECT_NAME} SHARED ${DEMO_SRC})
add_library(${CMAKE_PROJECT_NAME}_static STATIC ${DEMO_SRC})

set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES VERSION ${MY_DEMO_VERSION}  SOVERSION ${MY_DEMO_VERSION})

# link static lib and all symbols -> -l 
target_link_libraries(${CMAKE_PROJECT_NAME} "-Wl,--whole-archive"  
                      ${MODULE_SDK_LIBRARY}
                      ${APR_LIBRARY}
                      ${APR_UTIL_LIBRARY}
                      ${MINIXML_LIBRARY} 
                      ${EXPAT_LIBRARY} 
                      ${UUID_LIBRARY}
                      "-Wl,--no-whole-archive")

install(TARGETS ${CMAKE_PROJECT_NAME} LIBRARY DESTINATION lib)
install(TARGETS ${CMAKE_PROJECT_NAME}_static ARCHIVE DESTINATION lib)

install(FILES
  my_demo/my_demo.h
  DESTINATION include/my_demo)

# a sub dir of this project, there is a CMakeLists.txt in it also 
add_subdirectory(test)
  • run_build.sh
#!/usr/bin/bash

CURDIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd )
rm -rf CMakeCache.txt 
rm -rf CMakeFiles 
rm -rf cmake_install.cmake

MODULE_SDK_DIR=$CURDIR/usr/local/
MODULE_DEPS_DIR=$CURDIR/third_party
THIRDPARTY_LIB_PATH=$MODULE_DEPS_DIR/lib/ 

# reset the VARS in CMakeLists.txt by command line 

cmake . -DCURL_INCLUDE_DIR=$MODULE_DEPS_DIR/include/curl -DCURL_LIBRARY=$MODULE_DEPS_DIR/lib/libcurl.so \
        -DAPR_INCLUDE_DIR=$MODULE_DEPS_DIR/include/apr-1/ -DAPR_LIBRARY=$MODULE_DEPS_DIR/lib/libapr-1.a \
        -DAPR_UTIL_INCLUDE_DIR=$MODULE_DEPS_DIR/include/apr-1/ -DAPR_UTIL_LIBRARY=$MODULE_DEPS_DIR/lib/libaprutil-1.a \
        -DMINIXML_INCLUDE_DIR=$MODULE_DEPS_DIR/include -DMINIXML_LIBRARY=$MODULE_DEPS_DIR/lib/libmxml.a \
        -DUUID_LIBRARY=$MODULE_DEPS_DIR/lib/libuuid.a \
        -DMODULE_SDK_INCLUDE_DIR=$MODULE_SDK_DIR/include/module_c_sdk \
        -DMODULE_SDK_LIBRARY=$MODULE_SDK_DIR/lib/libmodule_c_sdk_static.a \
        -DCMAKE_INSTALL_PREFIX=./usr/local/ \
        -DTHIRDPARTY_LIB_PATH=$THIRDPARTY_LIB_PATH

注:一些cmake 的Flags 也可以在命令行中修改, 如 -DCMAKE_CXX_FLAGS=fPIC


TIPS

__FILE__变成相对路径

使用cmake 编译项目,会把 __FILE__ 展开成绝对路径,形如:

[/home/admin/myworks/logging/test.cpp:74]

这样会增加不少无用文本,其实只需要相对路径就行
增加编译选项: -ffile-prefix-map=old=new 或者 -fmacro-prefix-map

refe:https://mcuoneclipse.com/2021/01/23/assert-__file__-path-and-other-cool-gnu-gcc-tricks-to-be-aware-of/

具体在CMakeLIsts.txt 中增加

add_compile_options(-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.)

结果形如:

[./test.cpp:74]

测试代码

// test.cpp 
...
std::cout << "[" << __FILE__ << "]" << std::endl;
...

A: cmake的CMakeLists里target_link_libraries PUBLIC,PRIVATE参数表示什么意思

ChatGPT3.5 Q: 在 CMakeLists.txt 文件中,target_link_libraries 命令用于指定一个或多个库文件链接到目标可执行文件或库文件中。当使用该命令时,通常需要使用 PUBLIC、PRIVATE 或 INTERFACE 关键字来指定链接的方式。这三个关键字的作用如下:

  • PUBLIC:指定库文件将被链接到目标文件中,并且该链接关系将被传递给目标文件依赖的其他目标,即链接库文件的使用者和其依赖的其他目标都将链接该库文件。例如,如果一个库文件 foo 使用了库文件 bar,那么在 foo 的 CMakeLists.txt 文件中使用 target_link_libraries(foo PUBLIC bar) 命令将同时链接 bar 到 foo 和其它使用 foo 的目标中。
  • PRIVATE:指定库文件将被链接到目标文件中,但该链接关系不会被传递给目标文件依赖的其他目标,即只有链接库文件的目标本身才会链接该库文件。例如,如果一个可执行文件 main 使用了库文件 foo,并在 main 的 CMakeLists.txt 文件中使用 target_link_libraries(main PRIVATE foo) 命令,那么只有 main 本身会链接 foo,而其它依赖于 main 的目标并不会链接 foo。
  • INTERFACE:指定库文件将不会被链接到目标文件中,但该链接关系将会被传递给目标文件依赖的其他目标,即该链接库文件的依赖目标都会链接该库文件,但目标文件本身不会链接该库文件。这种方式通常用于定义头文件库,即只提供头文件,而不提供实现文件的库。
    通过使用 target_link_libraries 命令和 PUBLIC、PRIVATE、INTERFACE 关键字,可以在 CMakeLists.txt 文件中方便地配置库文件的链接方式,从而确保程序的正确链接和运行。

可以画一个简单的图来解释 target_link_libraries 命令中的 PUBLIC、PRIVATE、INTERFACE 关键字的关系。假设有两个目标文件 main 和 libfoo,及一个库文件 libbar,它们之间的依赖关系如下图所示:

main ----> libfoo
 |           |
 +-----<-----+
       |
    libbar

在这个例子中,main 依赖于 libfoo,而 libfoo 又依赖于 libbar。

接下来,我们考虑在 main 和 libfoo 的 CMakeLists.txt 文件中使用 target_link_libraries 命令来链接库文件 libbar,并使用 PUBLIC、PRIVATE 和 INTERFACE 关键字来指定链接方式。我们分别使用红色、蓝色和绿色的箭头来表示不同的链接方式。具体如下:

target_link_libraries(main PUBLIC libbar):指定库文件 libbar 将被链接到 main 中,并且该关系将被传递给 main 依赖的其他目标。因此,使用红色箭头来表示。

main ----> libfoo
 |           |
 +-----> libbar

target_link_libraries(libfoo PRIVATE libbar):指定库文件 libbar 将被链接到 libfoo 中,但该关系不会被传递给 libfoo 依赖的其他目标。因此,只有 libfoo 本身会链接 libbar。使用蓝色箭头来表示。

main ----> libfoo
 |           |
 +-----<-----+
       |
    libbar

target_link_libraries(libfoo INTERFACE libbar):指定库文件 libbar 将不会被链接到 libfoo 中,但该关系将被传递给 libfoo 依赖的其他目标。因此,使用绿色箭头来表示。

main ----> libfoo
 |           |
 +-----<-----+
       |
    libbar

通过上述图示,我们可以更加清晰地理解 target_link_libraries 命令中的 PUBLIC、PRIVATE 和 INTERFACE 关键字的作用和区别。使用这些关键字,可以方便地控制库文件的链接方式,并保证程序的正确链接和运行。

<think> 我们正在回答用户关于CMake GUI使用方法的问题。根据引用内容,我们可以总结出CMake GUI的基本使用步骤和一些关键配置选项。 步骤1: 安装CMake GUI 根据引用[2],CMake是一个跨平台的构建工具,可以生成各种构建文件(如Makefile或项目文件)。首先需要安装CMake,安装包中通常包含cmake-gui。 步骤2: 打开CMake GUI并设置路径 打开cmake-gui工具(引用[3]): - 设置源代码路径(Source code path),通常是项目根目录(包含CMakeLists.txt的目录)。 - 设置构建路径(Build path),用于存放生成的构建文件(如Makefile和项目文件等)。通常建议新建一个目录(如build)与源代码分离。 步骤3: 配置(Configure) 点击“Configure”按钮,然后选择生成器(Generator)。生成器的选择取决于你使用的编译环境,例如: - 在Windows上,可以选择Visual Studio的相应版本,或者MinGW等。 - 在Unix/Linux上,可以选择Unix Makefiles等。 - 在Android交叉编译时,需要指定工具链文件(如引用[3]中提到的android.toolchain.cmake)和ABI等选项。 步骤4: 设置配置选项(可选) 在配置过程中,可能会出现一些配置选项(如引用[3]中提到的): - CMAKE_INSTALL_PREFIX:指定安装路径(即make install时的目标路径)。 - BUILD_SHARED_LIBS:是否构建动态库(.dll或.so)。 - 其他项目特定的选项(如ENABLE_FLOAT, ENABLE_THREADS等)。 注意:在第一次配置后,可能需要根据项目需求调整这些选项,然后再次点击“Configure”直到没有红色标记。 步骤5: 生成(Generate) 点击“Generate”按钮,生成构建文件(如Makefile或Visual Studio项目文件等)。 步骤6: 构建 使用生成的构建文件进行构建: - 在命令行中,进入构建目录,运行相应的构建命令(如make, ninja, 或者打开生成的Visual Studio项目进行构建)。 - 如引用[3]中,在MinGW环境下使用`mingw32-make`命令,然后使用`mingw32-make install`进行安装。 额外说明(交叉编译): 对于Android等平台的交叉编译,需要在配置前设置工具链文件(通过工具链文件设置交叉编译工具链),并设置相关选项(如ANDROID_ABI, ANDROID_PLATFORM等)。如引用[3]中所示,可以通过点击“Add Entry”按钮手动添加这些变量。 示例(使用CMake GUI配置一个简单的项目): 假设我们有一个简单的项目,其CMakeLists.txt内容如下(参考引用[4]的格式): ``` cmake_minimum_required(VERSION 3.10) project(MyProject) add_executable(hello main.cpp) ``` 在CMake GUI中: 1. 源代码路径:设置为包含上述CMakeLists.txt的目录。 2. 构建路径:设置为一个新建的目录(例如项目根目录下的build目录)。 3. 点击“Configure”,选择生成器(例如Visual Studio 17 2022)。 4. 配置完成后,点击“Generate”。 5. 打开生成的解决方案(在build目录下),即可进行编译。 注意事项: - 在配置过程中,如果出现错误,需要检查CMakeLists.txt是否有语法错误或缺失的依赖。 - 配置选项(如引用[3]中提到的)根据项目需求设置。 根据以上步骤,我们可以编写使用指南。 </think>以下是 CMake GUI 的详细使用指南,结合官方文档和最佳实践整理而成: ### 一、CMake GUI 基础操作 1. **路径设置** - **源代码路径**:选择包含 `CMakeLists.txt` 的目录(项目根目录) - **构建路径**:新建空目录(如 `build/`)存放生成的文件[^1][^3] ![路径设置示意图](https://cmake.org/cmake/help/latest/_images/gui_paths.png) 2. **配置流程** ```mermaid graph LR A[点击 Configure] --> B{选择生成器} B -->|Visual Studio| C[设置VS版本] B -->|MinGW| D[设置编译器路径] C/D --> E[检查红色配置项] E --> F[修改参数] F --> G[再次Configure] G --> H[红色消失?] H -->|是| I[点击 Generate] H -->|否| F ``` 3. **关键配置选项** | 参数名 | 类型 | 作用 | 示例值 | |--------|------|------|--------| | `CMAKE_INSTALL_PREFIX` | PATH | 安装路径 | `C:/Program Files/MyProject` | | `BUILD_SHARED_LIBS` | BOOL | 生成动态库 | `ON` | | `CMAKE_BUILD_TYPE` | STRING | 构建类型 | `Release/Debug` | | `CMAKE_TOOLCHAIN_FILE` | FILEPATH | 交叉编译工具链 | `android.toolchain.cmake` [^3] | ### 二、进阶配置技巧 1. **添加自定义参数** 点击 `Add Entry` 添加新变量(如安卓编译参数)[^3]: ```cmake Name: ANDROID_ABI Type: STRING Value: armeabi-v7a Name: ENABLE_FLOAT Type: BOOL Value: ON ``` 2. **依赖库配置示例**(参考 VTK 配置[^4]): ```cmake # 在CMakeLists.txt中添加 find_package(VTK REQUIRED) target_include_directories(MyApp ${VTK_INCLUDE_DIRS}) target_link_libraries(MyApp ${VTK_LIBRARIES}) ``` 3. **生成后操作** - Windows: 打开生成的 `.sln` 用 Visual Studio 编译 - Linux/macOS: 终端执行: ```bash cd build/ make -j4 # 编译 make install # 安装到指定路径 ``` ### 三、常见问题解决 1. **配置错误处理** - 红色条目:表示需要修正的参数 - 错误日志:查看下方日志窗口的报错信息 2. **清除缓存** 删除 `CMakeCache.txt` 文件或整个 `build/` 目录后重新配置 3. **跨平台编译** Android 交叉编译示例[^3]: ```cmake CMAKE_TOOLCHAIN_FILE = ${NDK}/build/cmake/android.toolchain.cmake ANDROID_PLATFORM = android-21 CMAKE_POSITION_INDEPENDENT_CODE = ON ``` > **提示**:CMake GUI 本质是命令行 `cmake` 的图形封装,所有操作最终会转换为 `CMakeCache.txt` 中的配置项[^2]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值