CMake是什么

文章目录

  • 一.什么是CMake
  • 二.CMake安装
  • 三.CMake一个HelloWord-的语法介绍
    • 3.1 PROJECT关键字
    • 3.2 SET关键字
    • 3.3 MESSAGE关键字
    • 3.4 ADD_EXECUTABLE关键字
    • 3.5 include_directories关键字
    • 3.6 aux_source_directory
  • 四.语法的基本原则
    • 4.1 语法注意事项
  • 五.内部构建和外部构建
    • 5.1 外部构建方式举例
  • 六.编译多个源文件
    • 6.1 将目标文件放入构建目录的 bin 子目录
      • 6.1.1 ADD_SUBDIRECTORY 指令
      • 6.1.2 更改二进制的保存路径
  • 七.安装
    • 7.1 安装一个Helloworld
      • 7.1.1 安装文件COPYRIGHT和README
      • 7.1.2 安装脚本runhello.sh
      • 7.1.3 安装 doc 中的 hello.txt
      • 7.1.4 安装过程
  • 八.静态库和动态库的构建
    • 8.1 构建实例
      • 8.1.1 ADD_LIBRARY
      • 8.1.2 同时构建静态和动态库
      • 8.1.3 SET_TARGET_PROPERTIES
      • 8.1.4 动态库的版本号
      • 8.1.5 安装共享库和头文件
      • 8.1.6 使用外部共享库和头文件

CMake

DATE : 2023/12.9

一.什么是CMake

CMake是一个跨平台的开源构建工具,用于管理和构建软件项目。它采用一种声明式的语法来描述项目的构建过程,并生成适应不同平台和编译器的构建系统文件,如Makefile或Visual Studio项目文件。

CMake的设计目标是提供一个独立于特定编译器和操作系统的构建系统。它允许开发者使用统一的方式来描述项目的构建需求,并生成适应不同环境的构建系统文件。这使得开发者可以在不同平台和编译器上轻松地构建和管理项目。

使用CMake,开发者需要编写一个名为CMakeLists.txt的配置文件,其中包含了项目的源文件、库依赖、编译选项、链接选项等信息。CMake会根据这个配置文件生成相应的构建系统文件,然后使用生成的构建系统文件来构建项目。

CMake编译流程图如下图所示:
在这里插入图片描述

CMake具有以下特点和优势:

  • 跨平台性:CMake可以生成适应不同操作系统和编译器的构建系统文件,使得项目能够在多个平台上进行构建和运行。

  • 可扩展性:CMake支持自定义模块和函数,开发者可以编写CMake脚本来实现更复杂的构建逻辑,满足特定项目的需求。

  • 高效性:CMake使用高效的生成系统,能够并行编译多个目标,提高构建速度。

  • 广泛的应用:CMake被广泛应用于各种类型的项目,包括开源软件、商业软件、嵌入式系统等。

  • 社区支持:CMake拥有庞大的社区支持和活跃的开发者社区,有大量的文档、教程和示例可供参考。

二.CMake安装

  1. 绝大多数的linux系统已经安装了CMake

  2. Windows或某些没有安装过的linux系统,去http://www.cmake.org/HTML/Download.html 可以下载安装

三.CMake一个HelloWord-的语法介绍

一个CMakeLists.txt文件

#CMakeLists.txtPROJECT (HELLO)SET(SRC_LIST main.cpp)MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})ADD_EXECUTABLE(hello ${SRC_LIST})

3.1 PROJECT关键字

可以用来指定工程的名字和支持的语言,默认支持所有语言

PROJECT (HELLO) 指定了工程的名字,并且支持所有语言—建议

PROJECT (HELLO CXX) 指定了工程的名字,并且支持语言是C++

PROJECT (HELLO C CXX) 指定了工程的名字,并且支持语言是C和C++

该指定隐式定义了两个CMAKE的变量

_BINARY_DIR,本例中是 HELLO_BINARY_DIR

_SOURCE_DIR,本例中是 HELLO_SOURCE_DIR

MESSAGE关键字就可以直接使用者两个变量,当前都指向当前的工作目录,后面会讲外部编译

**问题:**如果改了工程名,这两个变量名也会改变

**解决:**又定义两个预定义变量:PROJECT_BINARY_DIRPROJECT_SOURCE_DIR,这两个变量和HELLO_BINARY_DIR,HELLO_SOURCE_DIR是一致的。所以改了工程名也没有关系

3.2 SET关键字

在CMake中,set是一个重要的关键字,用于设置变量的值。它的语法如下:

set(<variable> <value> [CACHE <type> <docstring> [FORCE]])

其中,<variable>是要设置的变量名,<value>是要赋给变量的值。<variable>可以是已存在的变量,也可以是新创建的变量。

set关键字还支持一些可选参数:

  • CACHE:指定变量为缓存变量,可以在构建过程中通过命令行或图形界面进行设置。缓存变量的值会被保存在CMake缓存中,下次运行CMake时会使用缓存中的值。

  • type:指定缓存变量的类型,可以是STRINGPATHFILEBOOL等。

  • docstring:对变量的描述,会在命令行或图形界面中显示。

  • FORCE:强制设置变量的值,即使变量已经存在。

下面是一些示例:

# 设置普通变量
set(SOURCE_FILES main.cpp)# 设置缓存变量
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type")# 设置路径变量
set(LIBRARY_PATH /path/to/library)# 强制设置变量的值
set(SOURCE_FILES main.cpp FORCE)# 设置一个变量的值
set(my_var "Hello, World!")

通过使用set关键字,可以在CMake中创建和设置变量,并根据需要指定变量的类型和属性。这些变量可以用于控制项目的构建过程,例如指定源文件、库路径、编译选项等。

3.3 MESSAGE关键字

在CMake中,MESSAGE关键字用于输出消息到CMake的生成过程中。它可以用于调试、显示变量的值、输出提示信息等。

MESSAGE关键字的语法如下:

MESSAGE([<mode>] "message" ...)

其中,<mode>是可选参数,用于指定消息的类型。常用的消息类型包括:

  • STATUS:输出一条状态消息,通常用于显示进度信息或提示信息。
  • WARNING:输出一条警告消息,表示可能存在问题,但不会导致构建失败。
  • AUTHOR_WARNING:输出一条作者警告消息,表示可能存在重要问题,可能导致构建失败。
  • SEND_ERROR:输出一条错误消息,并停止构建过程。
  • FATAL_ERROR:输出一条致命错误消息,并停止构建过程。

下面是一些示例用法:

MESSAGE("This is a status message")MESSAGE(STATUS "This is a status message")MESSAGE(WARNING "This is a warning message")MESSAGE(AUTHOR_WARNING "This is an author warning message")MESSAGE(SEND_ERROR "This is an error message")MESSAGE(FATAL_ERROR "This is a fatal error message")

在这些示例中,MESSAGE关键字被用于输出不同类型的消息。你可以根据需要选择适当的消息类型来输出相应的信息。

通过使用MESSAGE关键字,你可以在CMake生成过程中输出消息,帮助你了解构建的进展、调试问题以及向用户提供必要的提示和警告信息。

3.4 ADD_EXECUTABLE关键字

在CMake中,ADD_EXECUTABLE关键字用于定义一个可执行文件的构建规则。它将源代码文件编译为可执行文件,并指定可执行文件的名称和依赖项。

ADD_EXECUTABLE关键字的语法如下:

ADD_EXECUTABLE(<target> [source1] [source2] ...)

其中,<target>是指定的目标名称,用于指定生成的可执行文件的名称。source1source2等是源代码文件的路径,用于指定构建可执行文件所需的源代码文件。

以下是一个示例用法:

# 定义可执行文件的构建规则
ADD_EXECUTABLE(my_app main.cpp utils.cpp)# 添加可执行文件的依赖项
TARGET_LINK_LIBRARIES(my_app my_library)

在这个示例中,ADD_EXECUTABLE关键字定义了一个名为my_app的目标,它由main.cpputils.cpp两个源代码文件构建而成。你可以根据实际情况指定更多的源代码文件。

此外,你可以使用TARGET_LINK_LIBRARIES关键字将可执行文件与其他库进行链接。在示例中,TARGET_LINK_LIBRARIES用于将my_app与名为my_library的库进行链接。

通过使用ADD_EXECUTABLE关键字,你可以定义可执行文件的构建规则,并指定它的源代码文件和依赖项。这样,在构建过程中,CMake将根据定义生成相应的可执行文件。

3.5 include_directories关键字

在编译项目源文件的时候,很多时候都需要将源文件对应的头文件路径指定出来,这样才能保证在编译过程中编译器能够找到这些头文件,并顺利通过编译。在CMake中设置要包含的目录也很简单,通过一个命令就可以搞定了,他就是include_directories:

include_directories(headpath)

举例说明,有源文件若干,其目录结构如下:

$ tree
.
├── build
├── CMakeLists.txt
├── include
│   └── head.h
└── src├── add.cpp├── div.cpp├── main.cpp├── mult.cpp└── sub.cpp3 directories, 7 files

CMakeLists.txt文件内容如下:

cmake_minimum_required(VERSION 3.0)
project(CALC)
set(CMAKE_CXX_STANDARD 11)
set(HOME /home/robin/Linux/calc)
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin/)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
add_executable(app  ${SRC_LIST})

其中,第六行指定就是头文件的路径,PROJECT_SOURCE_DIR宏对应的值就是我们在使用cmake命令时,后面紧跟的目录,一般是工程的根目录。

3.6 aux_source_directory

aux_source_directory是CMake中的一个命令,用于将指定目录中的源文件自动添加到当前CMakeLists.txt文件的源文件列表中。

该命令的语法如下:

aux_source_directory(<dir> <variable>)

其中,<dir>是要搜索的目录路径,<variable>是存储搜索到的源文件列表的变量名。

使用aux_source_directory命令后,CMake会自动扫描指定目录中的源文件,并将其添加到当前CMakeLists.txt文件的源文件列表中。这样,在构建过程中,这些源文件就会被编译和链接到最终的可执行文件或库中。

以下是一个示例:

aux_source_directory(src DIR_SRCS)
add_executable(MyApp ${DIR_SRCS})

在上述示例中,aux_source_directory命令将目录src中的所有源文件自动添加到变量DIR_SRCS中。然后,通过add_executable命令将DIR_SRCS中的源文件编译为可执行文件MyApp

需要注意的是,aux_source_directory命令会自动将指定目录中的所有源文件添加到列表中,包括子目录中的源文件。如果希望只添加指定目录下的源文件,可以使用file(GLOB ...)命令结合正则表达式来筛选文件。

总之,aux_source_directory命令是CMake中用于自动添加指定目录中的源文件到源文件列表的命令。它可以简化项目的配置,使得源文件的管理更加方便。

四.语法的基本原则

  • 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名

  • 指令(参数 1 参数 2…) 参数使用括弧括起,参数之间使用空格或分号分开。 以上面的 ADD_EXECUTABLE 指令为例,如果存在另外一个 func.cpp 源文件

    就要写成:ADD_EXECUTABLE(hello main.cpp func.cpp)或者ADD_EXECUTABLE(hello main.cpp;func.cpp)

  • 指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令

4.1 语法注意事项

  • SET(SRC_LIST main.cpp) 可以写成 SET(SRC_LIST “main.cpp”),如果源文件名中含有空格,就必须要加双引号
  • ADD_EXECUTABLE(hello main) 后缀可以不行,他会自动去找.c和.cpp,最好不要这样写,可能会有这两个文件main.cpp和main

五.内部构建和外部构建

  • 上述例子就是内部构建,他生产的临时文件特别多,不方便清理
  • 外部构建,就会把生成的临时文件放在build目录下,不会对源文件有任何影响强烈使用外部构建方式

5.1 外部构建方式举例

当使用CMake进行外部构建时,你需要创建一个独立的构建目录,并在该目录中运行CMake来配置构建过程。这样做的好处是将构建过程的产物(如编译生成的文件、中间文件等)与源代码分开,保持项目目录的整洁。

下面是外部构建的详细步骤:

  1. 创建一个独立的构建目录:

    mkdir build
    cd build
    
  2. 在构建目录中运行CMake命令来配置构建过程。你需要指定项目源代码的路径,可以是相对路径或绝对路径:

    cmake /path/to/source 或者cmake .. //返回项目源代码路径
    

    在配置过程中,CMake会读取项目的CMakeLists.txt文件,并生成构建系统所需的Makefile或其他构建脚本。

  3. 进行构建。使用适合你的构建系统的命令,如make

    make
    

    这将根据生成的构建系统文件执行实际的构建过程。构建结果(如可执行文件、库文件等)将生成在构建目录中。

当使用CMake进行内部构建时,你直接在项目源代码目录中运行CMake命令,而不需要创建额外的构建目录。这种方式更简单,但可能会导致项目目录的混乱。

下面是内部构建的详细步骤:

  1. 进入项目源代码目录:

    cd /path/to/source
    
  2. 在项目源代码目录中运行CMake命令来配置构建过程。使用.表示当前目录:

    cmake .
    

    CMake将读取当前目录下的CMakeLists.txt文件,并生成构建系统所需的Makefile或其他构建脚本。

  3. 进行构建。使用适合你的构建系统的命令,如make

    make
    

    这将根据生成的构建系统文件执行实际的构建过程。构建结果将生成在项目源代码目录中。

注意外部构建的两个变量

  1. HELLO_SOURCE_DIR 还是工程路径
  2. HELLO_BINARY_DIR 编译路径 也就是 /root/cmake/bulid

六.编译多个源文件

  • 为工程添加一个子目录 src,用来放置工程源代码
  • 添加一个子目录 doc,用来放置这个工程的文档 hello.txt
  • 在工程目录添加文本文件 COPYRIGHT, README
  • 在工程目录添加一个 runhello.sh 脚本,用来调用 hello 二进制
  • 将构建后的目标文件放入构建目录的 bin 子目录
  • 将 doc 目录 的内容以及 COPYRIGHT/README 安装到/usr/share/doc/cmake/

6.1 将目标文件放入构建目录的 bin 子目录

每个目录下都要有一个CMakeLists.txt说明

[root@localhost cmake]# tree
.
├── build
├── CMakeLists.txt
└── src├── CMakeLists.txt└── main.cpp

外层CMakeLists.txt

PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)

src下的CMakeLists.txt

ADD_EXECUTABLE(hello main.cpp)

6.1.1 ADD_SUBDIRECTORY 指令

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

  • 这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置

  • EXCLUDE_FROM_ALL函数是将写的目录从编译中排除,如程序中的example

  • ADD_SUBDIRECTORY(src bin)

    将 src 子目录加入工程并指定编译输出(包含编译中间结果)路径为bin 目录

    如果不进行 bin 目录的指定,那么编译结果(包括中间结果)都将存放在build/src 目录

6.1.2 更改二进制的保存路径

SET 指令重新定义 EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH 变量 来指定最终的目标二进制的位置

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

思考:加载哪个CMakeLists.txt当中

哪里要改变目标存放路径,就在哪里加入上述的定义,所以应该在src下的CMakeLists.txt下写

七.安装

INSTALL命令是CMake中用于指定安装规则的命令。它允许你将项目构建生成的文件复制到指定的目录中,以便在安装过程中将这些文件提供给用户或其他项目使用。

INSTALL命令的基本语法如下:

INSTALL([CODE <code>][SCRIPT <script>][TARGETS <targets>...][FILES <files>...][DIRECTORY <dir>...][PROGRAMS <programs>...][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>...][DESTINATION <dir>][PERMISSIONS <permissions>...][CONFIGURATIONS [Debug|Release|...]][OPTIONAL][SET_DESTINATION][USE_SOURCE_PERMISSIONS][DIRECTORY_PERMISSIONS <permissions>...][RENAME <name>] [...])

INSTALL命令可以使用多个选项来指定要安装的文件和目录,以及安装的目标路径、权限等。

以下是一些常用的选项:

  • TARGETS:指定要安装的目标(可执行文件、库等)。
  • FILES:指定要安装的文件。
  • DIRECTORY:指定要安装的目录。
  • DESTINATION:指定安装的目标路径。
  • PERMISSIONS:指定安装文件的权限。
  • COMPONENT:指定安装的组件。
  • OPTIONAL:指定安装文件是否是可选的。
  • RENAME:指定安装文件的新名称。

下面是一个示例,展示如何使用INSTALL命令安装一个可执行文件和一个配置文件:

# 定义可执行文件和配置文件
SET(EXECUTABLE_NAME myapp)
SET(CONFIG_FILE myconfig.conf)# 添加可执行文件
ADD_EXECUTABLE(${EXECUTABLE_NAME} main.cpp)# 指定安装目标
INSTALL(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)# 指定安装文件
INSTALL(FILES ${CONFIG_FILE} DESTINATION etc)

在这个示例中,我们首先定义了可执行文件的名称(EXECUTABLE_NAME)和配置文件的名称(CONFIG_FILE)。然后,使用ADD_EXECUTABLE命令创建可执行文件。接下来,使用INSTALL命令分别指定可执行文件和配置文件的安装路径。

在构建项目时,可以使用以下命令将可执行文件和配置文件安装到指定的目录中:

cmake .
make
make install

这将构建项目并将可执行文件和配置文件复制到安装路径中。

请注意,安装路径可以根据你的需求进行调整。你可以根据项目的结构和约定来选择合适的安装路径,并在INSTALL命令中进行相应的修改。

总之,通过使用CMake的INSTALL命令,你可以指定要安装的文件和目录,并将它们复制到指定的目录中,以供其他项目或系统使用。

7.1 安装一个Helloworld

// 目录树结构
[root@localhost cmake]# tree
.
├── build
├── CMakeLists.txt
├── COPYRIGHT
├── doc
│   └── hello.txt
├── README
├── runhello.sh
└── src├── CMakeLists.txt└── main.cpp3 directories, 7 files

7.1.1 安装文件COPYRIGHT和README

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/)

FILES:文件

DESTINATION:

1、写绝对路径

2、可以写相对路径,相对路径实际路径是:${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>

CMAKE_INSTALL_PREFIX 默认是在 /usr/local/

cmake -DCMAKE_INSTALL_PREFIX=/usr 在cmake的时候指定CMAKE_INSTALL_PREFIX变量的路径

7.1.2 安装脚本runhello.sh

PROGRAMS:非目标文件的可执行程序安装(比如脚本之类)

INSTALL(PROGRAMS runhello.sh DESTINATION bin)

说明:实际安装到的是 /usr/bin

7.1.3 安装 doc 中的 hello.txt

  • 一、是通过在 doc 目录建立CMakeLists.txt ,通过install下的file

  • 二、是直接在工程目录通过

    INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake)

DIRECTORY 后面连接的是所在 Source 目录的相对路径

注意:abc 和 abc/有很大的区别

目录名不以/结尾:这个目录将被安装为目标路径下的

目录名以/结尾:将这个目录中的内容安装到目标路径

7.1.4 安装过程

cmake …

make

make install

八.静态库和动态库的构建

任务:

1,建立一个静态库和动态库,提供 HelloFunc 函数供其他程序编程使用,HelloFunc 向终端输出 Hello World 字符串。

2,安装头文件与共享库。

静态库和动态库的区别

  • 静态库的扩展名一般为“.a”或“.lib”;动态库的扩展名一般为“.so”或“.dll”。
  • 静态库在编译时会直接整合到目标程序中,编译成功的可执行文件可独立运行
  • 动态库在编译时不会放到连接的目标程序中,即可执行文件无法单独运行。

8.1 构建实例

[root@localhost cmake2]# tree
.
├── build
├── CMakeLists.txt
└── lib├── CMakeLists.txt├── hello.cpp└── hello.h

hello.h中的内容

#ifndef HELLO_H
#define Hello_Hvoid HelloFunc();#endif

hello.cpp中的内容

#include "hello.h"
#include <iostream>
void HelloFunc(){std::cout << "Hello World" << std::endl;
}

项目中的cmake内容

PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)

lib中CMakeLists.txt中的内容

SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

8.1.1 ADD_LIBRARY

ADD_LIBRARY是CMake中用于添加库的关键字。它用于定义和构建静态库或共享库。

ADD_LIBRARY的基本语法如下:

ADD_LIBRARY(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL]source1 [source2 ...])

其中:

  • <name>是要创建的库的名称。
  • STATIC表示创建一个静态库(.a文件),它在链接时被静态地链接到可执行文件中。
  • SHARED表示创建一个共享库(.so文件或.dylib文件),它在运行时动态加载。
  • MODULE表示创建一个模块库(.so文件或.dylib文件),它类似于共享库,但在某些平台上具有不同的用途。
  • EXCLUDE_FROM_ALL表示将库排除在构建过程之外,不会在默认构建目标中包含。
  • source表示源文件,这里可以指很多源文件。

接下来是一个示例,展示如何使用ADD_LIBRARY创建一个静态库:

# 添加名为mylib的静态库
ADD_LIBRARY(mylib STATIC source1.cpp source2.cpp)

这将创建一个名为mylib的静态库,其中包含source1.cppsource2.cpp两个源文件。

类似地,你也可以创建共享库或模块库。只需将STATIC替换为SHAREDMODULE即可。

# 添加名为mylib的共享库
ADD_LIBRARY(mylib SHARED source1.cpp source2.cpp)# 添加名为mylib的模块库
ADD_LIBRARY(mylib MODULE source1.cpp source2.cpp)

使用ADD_LIBRARY创建库后,你可以使用TARGET_LINK_LIBRARIES命令将库链接到其他目标(如可执行文件)中。这样可以在构建过程中解析库的依赖关系。

# 将mylib库链接到myapp可执行文件中
ADD_EXECUTABLE(myapp main.cpp)
TARGET_LINK_LIBRARIES(myapp mylib)

这个示例中,myapp可执行文件将链接到名为mylib的库。

ADD_LIBRARY是CMake中用于创建静态库、共享库或模块库的关键字。它允许你指定库的名称、类型和源文件,并可通过TARGET_LINK_LIBRARIES命令将库链接到其他目标中。

8.1.2 同时构建静态和动态库

// 如果用这种方式,只会构建一个动态库,不会构建出静态库,虽然静态库的后缀是.a
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})// 修改静态库的名字,这样是可以的,但是我们往往希望他们的名字是相同的,只是后缀不同而已
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})

8.1.3 SET_TARGET_PROPERTIES

SET_TARGET_PROPERTIES是CMake中用于设置目标属性的命令。通过这个命令,你可以修改目标(如可执行文件、库)的各种属性,如输出路径、编译选项、链接选项、名称等。

SET_TARGET_PROPERTIES的基本语法如下:

SET_TARGET_PROPERTIES(target1 target2 ...PROPERTIES prop1 value1 prop2 value2 ...)

其中:

  • target1 target2 ...是要设置属性的目标名称列表。
  • PROPERTIES关键字用于指定要设置的属性。
  • prop1 value1 prop2 value2 ...是要设置的属性及其对应的值。

这里,我们来修改一下库的名称,将静态库和动态库的名称修改一致

SET(LIBHELLO_SRC hello.cpp)ADD_LIBRARY(hello_static STATIC ${source})//对hello_static的重名为hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES  OUTPUT_NAME "hello")
//cmake 在构建一个新的target 时,会尝试清理掉其他使用这个名字的库,因为,在构建 libhello.so 时, 就会清理掉 libhello.a
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)ADD_LIBRARY(hello SHARED ${source})SET_TARGET_PROPERTIES(hello PROPERTIES  OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)

8.1.4 动态库的版本号

一般动态库都有一个版本号的关联

libhello.so.1.2
libhello.so ->libhello.so.1
libhello.so.1->libhello.so.1.2

CMakeLists.txt 插入如下

SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

VERSION 指代动态库版本,SOVERSION 指代 API 版本。

8.1.5 安装共享库和头文件

本例中我们将 hello 的共享库安装到/lib目录,

将 hello.h 安装到/include/hello 目录

//文件放到该目录下
INSTALL(FILES hello.h DESTINATION include/hello)//二进制,静态库,动态库安装都用TARGETS
//ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME 特指可执行目标二进制。
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

注意:

安装的时候,指定一下路径,放到系统下

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

8.1.6 使用外部共享库和头文件

准备工作,新建一个目录来使用外部共享库和头文件

[root@MiWiFi-R4CM-srv cmake3]# tree
.
├── build
├── CMakeLists.txt
└── src├── CMakeLists.txt└── main.cpp

main.cpp

#include <hello.h>int main(){HelloFunc();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/219428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dialog 在xml文件进行了自适应宽,但是失效了

如下图 讲述了为什么已经设置好了dialog的宽高 到了显示的时候就会失效的原因 解决方式 &#xff1a; 在自定的dialog中的onstart()方法中进行重新设置宽高 Window window getWindow();WindowManager.LayoutParams lp window.getAttributes();lp.height LinearLayout.La…

【操作系统的IO模型有哪些?】

操作系统的IO模型有哪些&#xff1f; 操作系统中的IO模型逐一拓展同步阻塞IO模型同步非阻塞IO模型IO复用模型信号驱动IO模型异步IO模型 操作系统中的IO模型 为了保护操作系统的安全&#xff0c;通过缓存加快系统读写&#xff0c;会将内存分为用户空间和内存空间两个部分。如果…

想学精MySQL,得先捋一捋高可用架构

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

ARM day8

1.题目&#xff1a;主机获取从机里面的温湿度数据&#xff0c;并打印出来 结果&#xff1a; 代码&#xff1a; main.c #include "iic.h"#include "si7006.h"void delay(int ms){int i,j;for(i0;i<ms;i){for(j0;j<2000;j);}}int main(){short tem;…

关于“Python”的核心知识点整理大全11

目录 ​编辑 6.2.4 修改字典中的值 6.2.5 删除键—值对 注意 删除的键—值对永远消失了。 6.2.6 由类似对象组成的字典 6.3 遍历字典 6.3.1 遍历所有的键—值对 6.3.2 遍历字典中的所有键 往期快速传送门&#x1f446;&#xff08;在文章最后&#xff09;&#xff1a; 6.…

【网络编程之初出茅庐】

前言&#xff1a;本章主要先讲解一些基本的网络知识&#xff0c;先把基本的知识用起来&#xff0c;后续会更深入的讲解底层原理。 网络编程的概念 网络编程&#xff0c;指网络上的主机&#xff0c;通过不同的进程&#xff0c;以编程的方式实现网络通信&#xff08;或称为网络数…

网络基础(九):VLAN的概述及配置

目录 前言 一、分割广播域的方法 二、VLAN 1、VLAN的概述及优势 1.1VLAN的概述 1.2VLAN的优势 2、VLAN的种类 3、VLAN的三种端口类型 4、VLAN 的工作原理 4.1VLAN数据帧 4.2VLAN的范围 4.2VLAN的access类型工作原理 4.3VLAN的trunk类型工作原理 4.4VLAN的Hybird类…

CentOS7安装MySQL8.0

一、使用Yum安装 1. 使用wget下载MySQL的rpm包 wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm2. 安装下载好的rpm包 yum localinstall mysql80-community-release-el7-3.noarch.rpm 3. 安装mysql&#xff08;该步可能出现问题&#xff09; yum…

JAVAEE-8-线程池

池 我们之前也接触过,比如说常量池,数据库连接池,线程池,进程池,内存池等等, 池的共性: 1.提前把要用的对象准备好 2.把用完的对象也不要立即释放,先留着以备下次使用 来提高效率!!! 最开始,进程能够解决并发编程的问题,因为频繁创建销毁进程的开销成本太大了,所以我们引…

新版Spring Security6.2案例 - Basic HTTP Authentication

前言&#xff1a; 书接上文&#xff0c;翻译官网Authentication的Username/Password这页&#xff0c;接下来继续翻译basic的这页&#xff0c;因为官网说的都是原理性的&#xff0c;这边一个小案例关于basic http authentication。 Basic Authentication 本节介绍 HTTP 基本身…

Unity 通过鼠标控制模拟人物移动和旋转视角

要通过鼠标控制并模拟人物移动和转换视角&#xff0c;将会使用射线检测、鼠标点击和鼠标水平移动&#xff0c;配合物体旋转和移动方法共同实现。 首先搭建个由一个Plane地板和若干cube组成的简单场景&#xff1a; 其次创建一个Capsule作为移动物体&#xff0c;并把摄像头拉到该…

腾讯云优惠券领取指南

腾讯云优惠券是降低云服务成本的有效手段&#xff0c;无论是新用户还是老用户&#xff0c;都可以通过下面方法领取到适合自己的优惠券。 1、腾讯云优惠券领取 领取入口&#xff1a;txy.ink 2、腾讯云优惠券介绍 腾讯云优惠券包括代金券和折扣券&#xff0c;代金券可以在结算…

【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline 0.71 CNN 部分

【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline 0.71 CNN 部分 概述CNN 简介数据预处理查看数据格式加载数据集 图像处理限定图像范围图像转换加载数据 CNN 模型Inception 网络ResNet 残差网络总结参数设置 训练 Train模型初始化数据加载训练超参数训练循环 验证…

Python 从入门到精通 学习笔记 Day04

Python 从入门到精通 第四天 今日目标 数据类型-又见str、数据类型-又见list 列表切片&排序&反转&循环、字典 数据类型 - 又见str 字符串定义 字符串是一个有序的字符的集合&#xff0c;用于在计算机里存储和表示文本信息 创建 a "Hello ,my name is Ha…

Android---Kotlin 学习005

substring 字符串截取。相加与 java&#xff0c;kt 里面的 substring 函数支持 IntRange 类型&#xff08;表示一个整数范围的类型&#xff09;的参数&#xff0c;until 创建的范围不包括上限值。 const val NAME "Jimmys friend" fun main(){val index NAME.ind…

TrustGeo代码理解(二)test.py

代码链接&#xff1a;https://github.com/ICDM-UESTC/TrustGeo 一、加载检查点&#xff08;checkpoint&#xff09;并进行测试 # -*- coding: utf-8 -*-"""load checkpoint and then test """ 该脚本的目的是加载之前训练过的模型的检查点&am…

【Linux】基于sed正则指令修改application.properties属性值

文章目录 背景sed介绍演示结果 背景 服务器上搭建了SpringCloud微服务&#xff0c;每个服务中都有application.properties文件&#xff0c;在部署过程中需要修改每个微服务的redis.ip和redis.port。如果手动去修改会很麻烦&#xff0c;所以下面写了一个shell脚本&#xff08;基…

idea的快捷键

1.调整字体的大小 文件夹的循序:setting-Editor-Font 界面: 2.删除当前行 文件夹的循序:setting-Keymap-DeleteLine 界面: 3.导入该行需要的类 文件夹的循序:setting-Editor-General-Auto import 界面: 4.格式化代码 文件夹的循序:setting-keymap-Reformat 界面: 5.快速…

大模型微调方法:冻结方法 Freeze、P-Tuning 系列、LoRA、QLoRA

大模型微调方法 冻结方法 FreezeP-Tuning 系列Prefix-TuningPrompt TuningP-Tuning v1P-Tuning v2 LoRAQLoRA 冻结方法 Freeze 方法意思是&#xff0c;只用少部分参数训练&#xff0c;把模型的大部分参数冻结。 只要设置微调层的参数&#xff1a; # 遍历模型的所有参数和名称…

程序员的养生之道:延寿健康的十大秘诀(下)

程序员的养生之道&#xff1a;延寿健康的十大秘诀&#xff08;上&#xff09;-CSDN博客 目录 6. 心理调节&#xff0c;减轻压力 6.1 程序员常见的心理问题 6.2 压力管理的重要性 6.3 放松技巧与应对策略 6.4 积极心态与心理健康 7. 正确坐姿&#xff0c;保护颈椎腰椎 …