cmake的一点点初步使用

cmake的一点点初步使用   https://cmake.org/

-------------

 

cmake打包程序。

1.开源跨平台

2.构建build,测试test,打包软件package sofrware的工具软件.

3.cmake的配置文件简单易懂,不依赖于其他平台的编译器

4.使用cmake配置文件来控制软件的编译过程,生成器generator生成指定项目文件(native makefile,MinGW Makefiles,Ninja,Visual Studio)等等的workspaces。

通过,对应的编译软件,最终编译成目标程序。

cmake命令,在那个目录下执行,就会搜索CMakeLists.txt,并在当前目录下生成相关文件(如果在代码目录执行,会在代码文件目录,会污染代码目录)。

所以一般是,建立build目录,和bin目录,在build目录中执行cmake ..(在上一级目录找CMakeLists.txt), build目录生成处理文件,最终可执行文件在bin中

 一 ,简单的cmake

  1 先看下目录结构 (-I表示忽略的目录)

$  tree . -I "bin|build|lib|src"
.
|-- CMakeLists.txt
|-- fun1.c
|-- fun2.c
|-- include
|   |-- fun1.h
|   `-- fun2.h
`-- test01.c

1 directory, 6 files

 

# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10.0)

#定义项目的名称和使用的编程语言
project(code1 VERSION 0.1.0 LANGUAGES C)

#指定要生成的可执行文件和其源文件
add_executable(code1 test01.c fun1.c fun2.c)

  如果文件夹有很多源码文件总不能一个一个添加吧,这里用到 aux_source_directory(. SRC_LIST)

# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10.0)

#定义项目的名称和使用的编程语言
project(code1 VERSION 0.1.0 LANGUAGES C)

#将当前目录.的所有源码文件保存在SRC_LIST变量中
aux_source_directory(. SRC_LIST)

#指定要生成的可执行文件和其源文件
add_executable(code1 ${SRC_LIST})

 

  2 最后在build目录下执行 cmake ..

二 , cmake正规的组织结构

$  tree . 
.
|-- CMakeLists.txt
|-- bin
|-- build
|-- include
|   |-- fun1.h
|   `-- fun2.h
|-- lib
`-- src
    |-- fun1.c
    |-- fun2.c
    `-- test01.c

5 directories, 6 files

 

# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10.0)

#定义项目的名称和使用的编程语言
project(code1 VERSION 0.1.0 LANGUAGES C)

# bin目录下将来存最终生成的可执行文件
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

#将当前目录.的src所有源码文件保存在SRC_LIST变量中
aux_source_directory(src SRC_LIST)

# 指定头文件目录include
include_directories(include)

#指定要生成的可执行文件和其源文件
add_executable(code1 ${SRC_LIST})

 

这里介绍几个cmake的变量, EXECUTABLE_OUTPUT_PATH :可执行文件生成路径;PROJECT_SOURCE_DIR :项目的路径。

set()设置变量;include_directories()设置头文件目录;aux_source_directory()设置源码路径。


三, cmake处理编译动态库静态库 

1.创建并处理自制动态库windows下(单个CMakeLists.txt )

$ tree .
.
|-- CMakeLists.txt
|-- build
`-- src
    |-- include
    |   `-- mylib.h
    |-- lib
    |   |-- module1.cpp
    |   `-- module2.cpp
    `-- main.cpp

四个文件内容

mylib.h
 #pragma once

// 跨平台导出宏(Windows 专用)
#ifdef _WIN32
  #ifdef LIB_BUILDING
    #define LIB_API __declspec(dllexport)
  #else
    #define LIB_API __declspec(dllimport)
  #endif
#else
  #define LIB_API
#endif


namespace MOD1 {
    LIB_API int add(int a, int b);
    LIB_API int subtract(int a, int b);
}

namespace MOD2 {
    LIB_API int add(int a, int b);
    LIB_API int subtract(int a, int b);
}
module1.cpp
#include <iostream>
#include "mylib.h"

namespace MOD1 {
    int add(int a, int b) { return a + b; }
    int subtract(int a, int b) { return a - b; }
}
module2.cpp
#include <iostream>
#include "mylib.h"

namespace MOD2 {
    int add(int a, int b) { return a + b; }
    int subtract(int a, int b) { return a - b; }
}
main.cpp
#include <iostream>
#include "mylib.h"

int main(){

    std::cout << MOD1::add(1,2)<< std::endl;
    std::cout << MOD2::add(5,2)<< std::endl;
    return 0;
}
CMakeLists.txt
###项目设置#########################

cmake_minimum_required(VERSION 3.10)   # 指定最低 CMake 版本
project(MyProject VERSION 1.0)          # 定义项目名称和版本

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 包含头文件路径
include_directories(${PROJECT_SOURCE_DIR}/src/include)


###动态库设置#########################

# 创建动态库
add_library(MyLib SHARED
    src/lib/module1.cpp
    src/lib/module2.cpp
)

# 设置公共头文件路径
target_include_directories(MyLib
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
)

# 关键:定义宏**_BUILDING,让头文件知道当前是“构建 DLL”
target_compile_definitions(MyLib PRIVATE LIB_BUILDING)

# 可选:统一输出目录(更整洁)
set_target_properties(MyLib PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
)

###主程序设置#########################
# 找自定库的路径
#find_library(MyLib ${PROJECT_SOURCE_DIR}/lib)

# 创建可执行程序
add_executable(MyApp src/main.cpp)

# 链接动态库(直接写目标名!CMake 自动处理 .lib 路径)
target_link_libraries(MyApp PRIVATE MyLib)


# 👇 关键:Windows 下自动复制 .dll 到 .exe 目录 (不添加手动复制dll到可执行程序也可以)
if(WIN32)
    add_custom_command(TARGET MyApp POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
            $<TARGET_FILE:MyLib>          # MyLib.dll
            $<TARGET_FILE_DIR:MyApp>        # 目标:MyApp.exe 所在目录
        COMMENT "Copying MyLib.dll to MyApp directory"
    )
endif()

 

 

2.创建并处理自制动态库windows下(多个CMakeLists.txt 子工程)

 项目结构(推荐) 这种结构清晰、可扩展,适合中小型到大型项目。

MyProject/
├── CMakeLists.txt              # 根 CMake
├── MathLib/                    # 动态库模块
│   ├── CMakeLists.txt
│   ├── include/MathLib.h
│   └── src/MathLib.cpp
└── MyApp/                      # 主程序
    ├── CMakeLists.txt
    └── main.cpp

 第一步:编写动态库代码   

MathLib/include/MathLib.h

#pragma once

// 跨平台导出宏(Windows 专用)
#ifdef _WIN32
  #ifdef MATHLIB_BUILDING
    #define MATHLIB_API __declspec(dllexport)
  #else
    #define MATHLIB_API __declspec(dllimport)
  #endif
#else
  #define MATHLIB_API
#endif

namespace Math {
    MATHLIB_API int add(int a, int b);
    MATHLIB_API int subtract(int a, int b);
}

MathLib/src/MathLib.cpp

#include "MathLib.h"

namespace Math {
    int add(int a, int b) { return a + b; }
    int subtract(int a, int b) { return a - b; }
}

第二步:MathLib/CMakeLists.txt(构建 DLL)

# 创建动态库
add_library(MathLib SHARED
    src/MathLib.cpp
)

# 设置公共头文件路径(供 MyApp 使用)
target_include_directories(MathLib
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
)

# 关键:定义宏,让头文件知道当前是“构建 DLL”
target_compile_definitions(MathLib PRIVATE MATHLIB_BUILDING)

# 可选:统一输出目录(更整洁)
set_target_properties(MathLib PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
)

PUBLIC 表示:任何链接 MathLib 的目标,都会自动获得 include/ 路径。

第三步:主程序代码

MyApp/main.cpp

#include <iostream>
#include "MathLib.h"  // 来自 MathLib/include/

int main() {
    std::cout << "10 + 5 = " << Math::add(10, 5) << "\n";
    std::cout << "10 - 3 = " << Math::subtract(10, 3) << "\n";
    return 0;
}

第四步:MyApp/CMakeLists.txt(引用 DLL)

# 创建可执行程序
add_executable(MyApp main.cpp)

# 链接动态库(直接写目标名!CMake 自动处理 .lib 路径)
target_link_libraries(MyApp PRIVATE MathLib)

# 👇 关键:Windows 下自动复制 .dll 到 .exe 目录
if(WIN32)
    add_custom_command(TARGET MyApp POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
            $<TARGET_FILE:MathLib>          # 源:MathLib.dll
            $<TARGET_FILE_DIR:MyApp>        # 目标:MyApp.exe 所在目录
        COMMENT "Copying MathLib.dll to MyApp directory"
    )
endif()

$<TARGET_FILE:MathLib> 会自动解析为 Debug/MathLib.dllRelease/MathLib.dll,完全匹配当前配置!

第五步:根 CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(MyProject LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 添加子模块
add_subdirectory(MathLib)
add_subdirectory(MyApp)

构建步骤(VS2022 + CMake)

方法一:用命令行(推荐)

# 在 MyProject 目录下
mkdir build
cd build

# 生成 VS2022 项目(x64)
cmake .. -G "Visual Studio 17 2022" -A x64

# 构建 Release 版本
cmake --build . --config Release

# 运行(自动找到 DLL!)
.\Release\MyApp.exe

方法二:用 VS2022 IDE

  1. 打开 VS2022 → 文件 → 打开 → CMake... → 选择 MyProject/CMakeLists.txt
  2. VS 会自动加载项目
  3. 顶部选择 x64-Release
  4. 右键 MyApp → 设为启动项
  5. 按 F5 运行!
10 + 5 = 15
10 - 3 = 7

 构建后目录结构(build/ 下)

build/
├── bin/
│   └── Release/
│       ├── MathLib.dll      ← 动态库
│       └── MyApp.exe        ← 可执行文件(同目录,运行无忧)
├── lib/
│   └── Release/
│       └── MathLib.lib      ← 导入库(链接时用)
└── MyProject.sln            ← VS 解决方案

💡 因为用了 add_custom_command,运行时绝不会报“找不到 MathLib.dll”!

3.使用链接器默认目录下的动态库

 

4.使用指定目录下的动态库

 

 

 

 

 

四,cmake 综合处理上面的情况

 

 

 

 

 

 

 

https://blog.csdn.net/hhltaishuai/article/details/123795718

https://www.runoob.com/cmake/cmake-basic.html

扩展:cake

https://www.bilibili.com/video/BV1nw411C71Z

https://www.bilibili.com/video/BV1EuWKevE23

gcc编译:

https://www.bilibili.com/video/BV192pZeTE9B

 

使用CMake生成动态链接库(.dll和.so)和静态链接库(.lib和.a)的方法

https://blog.csdn.net/weixin_43325228/article/details/143139745

 

posted @ 2025-12-12 15:45  与f  阅读(1)  评论(0)    收藏  举报