您的位置:首页 > 健康 > 美食 > 邯郸做网站最好的公司_东莞手机建网站_佛山百度关键词seo外包_seo搜索优化工具

邯郸做网站最好的公司_东莞手机建网站_佛山百度关键词seo外包_seo搜索优化工具

2025/4/2 17:52:39 来源:https://blog.csdn.net/cheese_burger_/article/details/146480430  浏览:    关键词:邯郸做网站最好的公司_东莞手机建网站_佛山百度关键词seo外包_seo搜索优化工具
邯郸做网站最好的公司_东莞手机建网站_佛山百度关键词seo外包_seo搜索优化工具

文章目录

  • 一、CMake 环境搭建
  • 二、简单入门
    • 1. 项目结构 与 示例源码
    • 2. 运行查看
    • 3. 然后在终端下输入 make
    • 4. 然后运行 main
  • 三、编译多个源文件 (同一目录下 简单版)
    • 1. 项目结构 与 示例源码
    • 2. 运行查看
  • 四、编译多个源文件 (同一目录下 复杂版)
    • 1. 新指令 `aux_source_directory`
    • 2. 项目结构 与 示例源码
    • 3. 运行查看
  • 五、编译多个源文件 (不同目录下)
    • 1. 新指令 `include_directories`
    • 2. 项目结构 与 示例源码
    • 3. 运行查看
  • 六、项目级的组织结构
    • 1. 新指令 `add_subdirectory`
    • 2. 项目结构 与 示例源码
    • 3. 新指令 `set`
    • 4. 运行查看
  • 七、动态库和静态库的编译控制
    • 1. 生成库文件
      • 1.1 新指令 `add_library`
      • 1.2 新指令 `set_target_properties`
      • 1.3 项目结构 与 示例源码
      • 1.4 运行查看
    • 2. 链接库文件
    • 2.1 新指令 `find_library`
    • 2.2 新指令 `target_link_libraries`
      • 2.3 项目结构 与 示例源码
    • 2.4 运行查看


 CMake是开源、跨平台的构建工具,可以让我们通过 编写简单的配置文件 去生成 本地的 Makefile,这个配置文件是 独立于运行平台和编译器 的,这样就不用亲自去编写 Makefile 了,而且配置文件可以直接拿到其它平台上使用,无需修改,非常方便。
 这里主要讲述在 Linux 下如何使用 CMake 来编译我们的程序。

一、CMake 环境搭建

 Ubuntu 下安装 CMake 的命令如下

sudo apt install cmake// 安装完成后可以输入下面代码查看
cmake -version

二、简单入门

1. 项目结构 与 示例源码

|
|——CMakeLists.txt
|——main.cpp
// main.cpp
#include <iostream>int main()
{std::cout << "Hello World" << std::endl;return 0;
}
// CMakeLists.txt
cmake_minimum_required (VERSION 2.8)project (demo)add_executable(main main.cpp)

2. 运行查看

 在终端下切到 main.cpp 所在的目录下,然后输入以下命令运行 cmake:

cmake .

 此时,建议留意一下这个文件夹下多生成的文件都有哪些。可以看到成功生成了 Makefile,还有一些 cmake 运行时自动生成的文件。

3. 然后在终端下输入 make

make

 可以看到执行 cmake 生成的 Makefile 可以显示进度,并带颜色。再看下目录下的文件可以看到我们需要的 可执行文件 main 也成功生成了!

4. 然后运行 main

./main

三、编译多个源文件 (同一目录下 简单版)

1. 项目结构 与 示例源码

|
|——CMakeLists.txt
|——main.cpp
|——testFunc.cpp
|——testFunc.h

 基本方法就是,在 add_executable 的参数里把 testFunc.c 加进来,值得在意的是,只要加 .cpp 文件,即源文件,即可

// testFunc.h#ifndef _TEST_FUNC_H_
#define _TEST_FUNC_H_void func(int data);#endif
// testFunc.cpp#include <iostream>
#include "testFunc.h"void func(int data)
{std::cout << "data is " << data << std::endl;
}
// main.cpp#include <iostream>
#include "testFunc.h"int main()
{func(100);return 0;
}
// CMakeLists.txt
cmake_minimum_required (VERSION 2.8)project (demo)add_executable(main main.cpp testFunc.cpp)

2. 运行查看

cmake .
make
./main

四、编译多个源文件 (同一目录下 复杂版)

1. 新指令 aux_source_directory

 可以类推,如果在 同一目录下多个源文件,那么只要在 add_executable 里把 所有源文件都添加进去 就可以了。
 但是如果有一百个源文件,再这样做就有点坑了,无法体现 cmake 的优越性。因此 cmake 提供了一个命令可以 把指定目录下所有的源文件存储在一个变量中 ,这个命令就是:

aux_source_directory(dir var)
  • dir 就是指定目录的路径,一般是相对路径,当前路径 ./ 指的是 CMakeLists.txt 所在的目录。
  • var 就是变量。

2. 项目结构 与 示例源码

|
|——CMakeLists.txt
|——main.cpp
|——testFunc1.cpp
|——testFunc1.h
|——testFunc.cpp
|——testFunc.h
// testFunc.h#ifndef _TEST_FUNC_H_
#define _TEST_FUNC_H_void func(int data);#endif
// testFunc.cpp#include <iostream>
#include "testFunc.h"void func(int data)
{std::cout << "data is " << data << std::endl;
}
//testFunc1.h#ifndef _TEST_FUNK_H_
#define _TEST_FUNC1_H_void func1(int data);#endif
// testFunc1.cpp#include <iostream>
#include "testFunc1.h"void func1(int data)
{std::cout << "data is " << data << std::endl;
}
// main.cpp#include <iostream>
#include "testFunc.h"
#include "testFunc1.h"int main()
{func(100);func1(200);return 0;
}
// CMakeLists.txt
cmake_minimum_required (VERSION 2.8)project (demo)aux_source_directory(. SRC_LIST)add_executable(main ${SRC_LIST})

3. 运行查看

cmake .
make
./main

五、编译多个源文件 (不同目录下)

 一般来说,当程序文件比较多时,我们会进行分类管理,把代码根据功能放在不同的目录下,这样方便查找。那么这种情况下如何编写 CMakeLists.txt 呢?

1. 新指令 include_directories

 是 CMake 中用来 指定 头文件搜索路径 的命令,路径之间用空格分隔。语法格式为:

include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
参数含义
dir1 dir2 ...要添加的头文件路径(可以是 对于 CMakeLists.txt的相对路径 或 绝对路径)
BEFORE将路径添加到搜索路径的前面(优先查找)
AFTER将路径添加到搜索路径的末尾(默认行为)
SYSTEM标记为系统路径(可避免显示头文件警告)

 因为 main.cppincludetestFunc.htestFunc1.h,如果没有这个命令来指定头文件所在位置,就会无法编译。当然,也可以在 main.cpp 里使用 include 来指定路径,如下

#include "test_func/testFunc.h"
#include "test_func1/testFunc1.h"

 一切以 main.cpp 的位置为起点。另外,我们使用了 2 次 aux_source_directory,因为源文件分布在 2 个 目录下,所以添加 2 次

2. 项目结构 与 示例源码

|
|—CMakeLists.txt
|—main.cpp
|—test_func
|  |—testFunc.cpp
|  |—testFunc.h
|—test_func1|—testFunc1.cpp|—testFunc1.h

CMakeLists.txt 一定要和 main.cpp 在同一目录下。
 把之前的 testFunc.cpptestFunc.h 放到 test_func 目录下,testFunc1.cpptestFunc1.h 则放到 test_func1 目录下。然后写 CMakeLists.txt 文件,其中,CMakeLists.txtmain.cpp 在同一目录下,内容修改成如下所示:

// CMakeLists.txt
cmake_minimum_required (VERSION 2.8)project (demo)include_directories (./test_func ./test_func1)aux_source_directory (test_func SRC_LIST)
aux_source_directory (test_func1 SRC_LIST1)add_executable (main main.cpp ${SRC_LIST} ${SRC_LIST1})

3. 运行查看

cmake .
make
./main

六、项目级的组织结构

 正规一点来说,一般会把 源文件 放到 src 目录下,把 头文件 放入到 include 文件下,生成的对象文件 放入到 build 目录下,最终输出的 可执行程序文件 会放到 bin 目录下,这样整个结构更加清晰。

1. 新指令 add_subdirectory

ass_subdirectory() 是 CMake 中用于 添加子目录 的指令,它的作用是:将某个子目录 (包含 CMakeLists.txt) 纳入当前项目的构建系统,并构建该子目录中的源文件、目标文件等内容。
 基本语法如下:

add_subdirectory(<source_dir> [binary_dir] [EXCLUDE_FROM_ALL])
  • source_dir (必选):
    要添加的子目录路径 (相对于当前 CMakeLists.txt 文件的位置)。
    如果子目录再次包含的 CMakeLists.txt,则将继续处理里层的 CMakeLists.txt,否则就继续处理当前源代码。
  • binary_dir (可选):
    构建该子目录时,生成 中间文件 的地方 (通常是 build 的临时目录)。
    如果不指定,默认 等于 source_dir
  • EXCLUDE_FROM_ALL (可选):
    表示这个目录中的目标不会被默认加入 all 目标(即不会被 make 默认构建)。

 根据上面的说明,特别是对 source_dir 的说明可以知道,实际上该指令告诉 CMake:进入这个子目录,处理该目录中的 CMakeLists.txt 文件,像处理主目录一样继续处理构建逻辑。这是一个 递归逻辑

2. 项目结构 与 示例源码

|
|—bin
|—build
|—CMakeLists.txt
|—include
| |—testFunc1.h
| |—testFunc.h
|—src|—CMakeLists.txt|—main.cpp|—testFunc1.cpp|—testFunc.cpp

testFunc.h testFunc.cpptestFunc1.htestFunc1.cppmain.cpp 的内容不变,需要修改 CMakeLists.txt

//CMakeLists.txt
cmake_minimum_required (VERSION 2.8)project (demo)add_subdirectory (src)

 这里指定 src 目录下存放了源文件,当执行 cmake 时,就会进入 src 目录下去找 src 目录下的 CMakeLists.txt,所以在 src 目录下也建立一个 CMakeLists.txt,内容如下:

// src/CMakeLists.txt
aux_source_directory (. SRC_LIST)include_directories (../include)add_executable (main ${SRC_LIST})set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

3. 新指令 set

 在 CMake 中,set() 是用于 定义变量 或 修改变量值 的命令。其基本语法如下:

set(<variable> <value>... [PARENT_SCOPE | CACHE <type> <docstring> [FORCE]])
参数说明
<variable>要定义的变量名
<value>...要赋的值,可以是单个字符串,也可以是多个,表示一个“CMake 列表”
PARENT_SCOPE将变量值赋给上一层作用域(例如在函数或子目录中向上传递)
CACHE将变量保存到 CMake 缓存中(供 cmake-gui 或其他模块使用)
FORCE强制更新缓存中的已有值

 接下来解析一下 set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 的含义:

  • 将变量 EXECUTABLE_OUTPUT_PATH 设置为 ${PROJECT_SOURCE_DIR}/bin
  • EXECUTABLE_OUTPUT_PATH 是一个 CMake 内置变量,表示 所有可执行文件 (add_executable 产生的) 要放到哪个目录。
  • PROJECT_SOURCE_DIR 是一个 CMake 内置变量,表示 主 CMakeLists.txt 所在的目录,即 项目根目录
  • /bin 表示你希望所有可执行文件最终输出到 项目根目录下的 bin 文件夹 中。

整个语句的含义就是,“把构建出来的可执行文件统一放到项目根目录下的 bin/ 目录中”

4. 运行查看

cd build
cmake ..
make

这里解释一下为什么在build目录下运行cmake?
 还记得在第一个例子里cmake和make之后会生成很多文件,但是跟我们的运行并没有什么关系,因此,如果能把编译隔离在某个文件夹,这样cmake的时候所有的中间文件都将在这个目录下生成,删除的时候也很好删除,非常方便。
 如果不这样做,cmake运行时生成的附带文件就会跟源码文件混在一起,这样会对程序的目录结构造成污染。


七、动态库和静态库的编译控制

 有时 只需要编译动态库静态库,然后 等着让其它程序去使用。让我们看下这种情况该如何使用 cmake。

1. 生成库文件

1.1 新指令 add_library

 在 CMake 中,add_library() 用于 创建一个 库目标 (library target),可以是:

  • 静态库 (Static Library):.a.lib 文件
  • 动态库 (Shared Library / 共享库):.so.dll 文件
  • 模块库 (Module Library):动态加载的插件 .so/.dll

这些库可以被其他目标(如可执行文件或其他库)链接使用。

 其基本语法格式为:

add_library(<name> [STATIC | SHARED | MODULE | OBJECT | INTERFACE] [EXCLUDE_FROM_ALL] source1 source2 ...)
参数说明
<name>创建的库的名字(供 target_link_libraries() 使用)
STATIC静态库(默认类型)
SHARED共享库(动态库)
MODULE 模块库(插件库)
OBJECT对象库(仅编译 .o 文件,不链接)
INTERFACE接口库(无源码,仅用于头文件和依赖传播)
EXCLUDE_FROM_ALL不在默认构建目标中构建
source1 source2 ...指定生成库的源文件

1.2 新指令 set_target_properties

set_target_properties() 是 CMake 用来 设置构建目标 (target) 的一些属性 的指令,如 输出路径、编译选项、版本号、命名规则、是否是可导出库 等。下面的示例中该语句的作用是 设置最终生成的库的名称,还有其它功能,如设置库的版本号等

 其基本语法是:

set_target_properties(<target1> <target2> ... PROPERTIES <prop1> <value1> <prop2> <value2> ...)
参数说明
<target1> <target2> ...一个或多个目标(可执行、库等)
PROPERTIES <prop1> <value1> <prop2> <value2> ...列出要设置的属性名与对应的值

 常见属性及作用

属性名作用示例值
RUNTIME_OUTPUT_DIRECTORY可执行文件输出目录${CMAKE_BINARY_DIR}/bin
LIBRARY_OUTPUT_DIRECTORY动态库 .so/.dll 输出目录${CMAKE_BINARY_DIR}/lib
ARCHIVE_OUTPUT_DIRECTORY静态库 .a/.lib 输出目录${CMAKE_BINARY_DIR}/lib
OUTPUT_NAME最终目标名称(自定义输出文件名)mylib_custom
VERSION库版本号(一般用于共享库)1.2.3
SOVERSION库的 API 版本(与 VERSION 搭配使用)1
POSITION_INDEPENDENT_CODE是否编译为位置无关代码(PIC),通常用于构建共享库ON / OFF
LINKER_LANGUAGE指定链接语言(通常自动推断)CXXC

1.3 项目结构 与 示例源码

|
|—build
|—CMakeLists.txt
|—lib
|—testFunc|—testFunc.cpp|—testFunc.h

 我们会在 build 目录下运行 cmake,并把生成的库文件存放到 lib 目录下。

// CMakeLists.txt
cmake_minimum_required (VERSION 3.5)project (demo)set (SRC_LIST ${PROJECT_SOURCE_DIR}/testFunc/testFunc.cpp)add_library (testFunc_shared SHARED ${SRC_LIST})
add_library (testFunc_static STATIC ${SRC_LIST})set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "testFunc")set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
  • LIBRARY_OUTPUT_PATH 是一个 CMake 内置变量,表示 库文件的 默认输出路径,这里设置为工程目录下的 lib 目录。

使用 set_target_properties 重新定义了库的输出名称,如果不使用 set_target_properties 也可以,那么库的名称就是 add_library 里定义的名称,只是连续2次使用 add_library 指定库名称时(第一个参数),这个名称不能相同,而 set_target_properties 可以把名称设置为相同,只是最终生成的库文件后缀不同(一个是 .so,一个是 .a),这样相对来说会好看点。

1.4 运行查看

cd build/
cmake ..
make
cd ../lib/
ls

 然后输出如下图所示,.a 是静态库,.so 是动态库:
在这里插入图片描述

2. 链接库文件

 既然我们已经生成了库,那么就进行链接测试下。

2.1 新指令 find_library

find_library() 是 CMake 用来 查找本地或系统中已存在的库文件,如 .so.a.lib,的命令。它常用于 查找系统预装库或第三方安装库的位置,并 将路径保存到变量 中以供 target_link_libraries() 使用。
 其基本语法如下:

find_library(<VAR> name1 [name2 ...][PATHS path1 path2 ...][HINTS hint1 hint2 ...][PATH_SUFFIXES suffix1 suffix2 ...][DOC "description"][NO_DEFAULT_PATH | NO_CMAKE_PATH | NO_SYSTEM_ENVIRONMENT_PATH | ...])
参数含义
<VAR>用来 保存搜索结果 的变量名
name1 name2 ...要查找的库名(不包含前缀 lib 和扩展名 .so/.a/.lib
PATHS指定搜索路径
HINTS提示路径(比 PATHS 更优先)
PATH_SUFFIXES搜索路径的后缀,比如 lib, lib64
DOC文档说明,主要用于 cmake-gui 中的说明
NO_DEFAULT_PATH禁用默认搜索路径(更严格控制搜索位置)
NO_CMAKE_PATH禁用 CMAKE_INSTALL_PREFIX/lib 等路径
NO_SYSTEM_ENVIRONMENT_PATH禁用系统环境变量路径搜索

2.2 新指令 target_link_libraries

target_link_libraries在 CMake 中用于 指定某个 target 需要链接的库文件。它是现代 CMake 推荐的做法,因为它能很好地控制依赖关系,支持作用域 (PUBLIC/PRIVATE/INTERFACE)。
 其基本语法如下:

target_link_libraries(<target> [<scope>] <lib1> <lib2> ...)
参数说明
<target>需要链接库的目标(可执行文件或库)
<scope>可选,作用域关键字(PUBLIC / PRIVATE / INTERFACE
<lib1> <lib2> ...需要链接的库,可以是 库名变量路径

 作用域的含义:

作用域含义
PRIVATEtarget 需要 lib,但不会影响其他依赖它的 target
PUBLICtarget 需要 lib,依赖 target 的其他 target 也需要 lib
INTERFACEtarget 不需要 lib,但依赖 target 的其他 target 也需要 lib

2.3 项目结构 与 示例源码

 重新建一个工程目录,然后把上节生成的库 拷贝 过来,然后在在工程目录下新建 src 目录和 bin 目录,在 src 目录下添加一个 main.cpp,整体结构如下:

|
|—bin
|—build
|—CMakeLists.txt
|—src
| |—main.cpp
|—testFunc|—inc| |—testFunc.h|—lib|—libtestFunc.a|—libtestFunc.so
// main.cpp
#include <iostream>
#include "testFunc.h"int main()
{func(100);return 0;
}
// CMakeList.cpp
cmake_minimum_required (VERSION 3.5)project (demo)set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)# find testFunc.h
include_directories (${PROJECT_SOURCE_DIR}/testFunc/inc)find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)add_executable (main ${SRC_LIST})target_link_libraries (main ${TESTFUNC_LIB})

2.4 运行查看

cd build/
cmake ..
make
cd ../bin/
./main

输出如下图所示:
在这里插入图片描述

lib 目录下有 testFunc 的静态库和动态库,find_library(TESTFUNC_LIB testFunc… 默认 是查找 动态库
如果想直接指定使用动态库还是静态库,可以写成 find_library(TESTFUNC_LIB libtestFunc.so … 或者 find_library(TESTFUNC_LIB libtestFunc.a …

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com