windows--cmake与c++的使用教程(9)
1 概述
- 本文基于前文环境
本节目标:动态库和Exe项目修改CMake默认输出路径
2 准备工作
- 目录结构
.
│ CMakeLists.txt
└─src
main.cc
2.1 代码准备
- main.cc中的代码如下
#include <iostream>
/// 程序入口
int main(int argc, char* argv[], char* env[])
{
const std::string str_hello{"hello cmake"};
std::cout << "\n" << str_hello.c_str() << "\n";
return 0;
}
2.2 CMakeLists.txt
- CMakeLists.txt脚本内容
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# 指定代码文件
set( src_files
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
)
# 用于生成可执行程序, 第一个参数是项目名称, 第二个参数是项目文件
add_executable(${PROJECT_NAME} ${src_files})
2.3 编译代码
- VSCode命令面板分别执行下面的步骤
>CMake:Select a kit
>CMake:Select Variant
>CMake:Configure
>CMake:Build
关于这些命令的详细使用,详见前文
3 可执行程序默认输出路径
- 编译结束后,默认输出到build文件夹中
2.1 executable输出
- 输出位于build目录下的Debug目录
- 这里仅仅列出咱们关心的目录
.
│ CMakeLists.txt
│
├─build
│ ├─Debug
│ │ HelloCMake.exe
│ │ HelloCMake.pdb
│
└─src
main.cc
5 Libray默认输出路径
- 关于library的默认输出, 咱们也做一个测试
5.1 动态库CMake脚本准备
- 动态库创建, add_library 使用的是关键字 SHARED
- 基于上文环境,咱们将CMakeLists.txt改为如下脚本
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# 指定代码文件
set( src_files
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
)
# 用于生成可执行程序, 第一个参数是项目名称, 第二个参数是项目文件
add_library(${PROJECT_NAME} SHARED ${src_files})
5.2 编译后查看输出
- 依次执行以下命令
>CMake:Select a kit
>CMake:Select Variant
>CMake:Configure
>CMake:Build
- 执行后,动态库DLL输出路径与EXE的输出路径相同:位于build/Debug目录下
.
│ CMakeLists.txt
│
├─build
│ ├─Debug
│ │ HelloCMake.dll
│ │ HelloCMake.pdb
└─src
main.cc
5.3 静态库CMake脚本准备
- 与动态库创建不同,add_library 使用的是关键字 STATIC
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# 指定代码文件
set( src_files
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
)
# 用于生成可执行程序, 第一个参数是项目名称, 第二个参数是项目文件
add_library(${PROJECT_NAME} STATIC ${src_files})
- 编译输出
.
│ CMakeLists.txt
│
├─build
│ ├─Debug
│ │ HelloCMake.lib
│ │ HelloCMake.pdb
└─src
main.cc
6 修改默认输出路径
6.1 变量重新赋值一定要放在 add_library 或者 add_executable
6.2 变量重新赋值一定要放在 add_library 或者 add_executable
6.3 变量重新赋值一定要放在 add_library 或者 add_executable
如果顺序不对,或 无法达到修改输出路径的效果
- 使用顺序
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "你想要输出的目录")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "你想要输出的目录")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "你想要输出的目录")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE "你想要输出的目录")
...
add_library(...)
...
内置变量说明见下表
- CMake内置变量说明
序号 | 名称 | 说明 |
---|---|---|
1 | CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG | 可执行程序EXE Debug输出目录 |
2 | CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE | 可执行程序EXE Release输出目录 |
3 | CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG | 动态库或静态库 Debug输出目录 |
5 | CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE | 动态库或静态库 Release输出目录 |
6.5 一个栗子
- 下面的脚本,设置动态库(某种意义上也是一种可执行程序)和可执行程序exe的输出路径到CMakeLists.txt所在的目录下的Publish下
# 64位
if (CMAKE_CL_64)
set(platform_info x64)
# 86
else()
set(platform_info x86)
endif()
# 设置 可执行程序输出目录
set(publish_bin_debug ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/bin/debug)
set(publish_bin_release ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/bin/release)
# 设置库文件输出目录
set(publish_lib_debug ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/lib/debug)
set(publish_lib_release ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/lib/release)
# 指定可执行程序输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${publish_bin_debug})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${publish_bin_release})
# 指定 库文件输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${publish_lib_debug})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE ${publish_lib_release})
可以继续扩展,输出路径中可加入编译器名称,比如 ${CMAKE_CURRENT_SOURCE_DIR}/publish/VS2019/x86/lib/release。 你可以试试。
- 下面就逐一解释脚本内容
6.5.1 构建套件类型
# 64位
if (CMAKE_CL_64)
set(platform_info x64)
# 86
else()
set(platform_info x86)
endif()
引入了if语法,这里不展开, 可参考官方文档, (在线文档无法查看。可查看CMake离线文档, ) ,记住一点,cmake的if需要 与 endif配对使用。
离线文档入口位于 CMake的安装目录/doc/cmakehtml/下的index.html。打开后,搜索if即可
搜索if结果展示
if语法使用说明离线文档展示
- 说人话,就是判断当前程构建套件是x86还是x64。
6.5.2 核心代码
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${publish_bin_debug})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${publish_bin_release})
# 指定 库文件输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${publish_lib_debug})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE ${publish_lib_release})
- 直接修改CMake内置的变量值。 如和查看是否修改成功? 可使用Message输出变量的值, 比如
message("CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG=${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}")
message("CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}")
message("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG}")
message("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE}")
7 EXE修改CMake默认输出路径
演示可执行程序EXE的输出路径
7.1 exe输出路径修改
- 完整Cmake脚本:
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# -----------------------------------------------------------------------------------------------------
# 64位
if (CMAKE_CL_64)
set(platform_info x64)
# 86
else()
set(platform_info x86)
endif()
# 设置 可执行程序输出目录
set(publish_bin_debug ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/bin/debug)
set(publish_bin_release ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/bin/release)
# 设置库文件输出目录
set(publish_lib_debug ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/lib/debug)
set(publish_lib_release ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/lib/release)
# 指定可执行程序输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${publish_bin_debug})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${publish_bin_release})
# 指定 库文件输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${publish_lib_debug})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE ${publish_lib_release})
# -----------------------------------------------------------------------------------------------------
# 指定代码文件
set( src_files
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
)
# 用于生成可执行程序, 第一个参数是项目名称, 第二个参数是项目文件
add_executable(${PROJECT_NAME} ${src_files})
由于脚本有更新,请在构建脚本后查看输出
7.2 查看输出
- 构建结束后, 查看输出
.
│ CMakeLists.txt
│
├─publish
│ └─x64
│ ├─bin
│ │ └─debug
│ │ HelloCMake.exe
│ │ HelloCMake.pdb
│ │
│ └─lib
│ └─debug
└─src
main.cc
- 可见, HelloCMake.exe已经输出在咱们指定的文件夹了
8 Library修改CMake默认输出路径
演示可执行程序library的输出路径
- 完整脚本如下
# 指定CMake脚本解析的最低版本,
cmake_minimum_required(VERSION 3.18)
# 指定项目
project(HelloCMake)
# -----------------------------------------------------------------------------------------------------
# 64位
if (CMAKE_CL_64)
set(platform_info x64)
# 86
else()
set(platform_info x86)
endif()
# 设置 可执行程序输出目录
set(publish_bin_debug ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/bin/debug)
set(publish_bin_release ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/bin/release)
# 设置库文件输出目录
set(publish_lib_debug ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/lib/debug)
set(publish_lib_release ${CMAKE_CURRENT_SOURCE_DIR}/publish/${platform_info}/lib/release)
# 指定可执行程序输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${publish_bin_debug})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${publish_bin_release})
# 指定 库文件输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${publish_lib_debug})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RLEASE ${publish_lib_release})
# -----------------------------------------------------------------------------------------------------
# 指定代码文件
set( src_files
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc
)
# 用于生成动态库
add_library(${PROJECT_NAME} SHARED ${src_files})
- 输出结果
│ CMakeLists.txt
│
├─build
│
├─publish
│ └─x64
│ ├─bin
│ │ └─debug
│ │ HelloCMake.dll
│ │ HelloCMake.pdb
│ │
│ └─lib
│ └─debug
└─src
main.cc
至此, 本节目标达成