当前位置:   article > 正文

二、使用cmake生成.so文件_cmake 生成so

cmake 生成so

二、使用cmake生成.so文件

虽然 Make 和 Makefile 简化了手动构建的过程,但是编写 Makefile 文件仍然是一个麻烦的工作,因此就有了 CMake 工具。CMake 工具用于生成 Makefile 文件,而如何生成 Makefile 文件,则由 CMakeLists.txt 文件指定。

make、Makefile、cmake、CMakeList.txt的关系如下图所示:

在这里插入图片描述

1、cmake生成库文件

先创建个工程1.projectV1,目录结构如下

1.projectV1/
├── build
├── CMakeLists.txt
├── include
│   ├── add.h
│   ├── devide.h
│   ├── multi.h
│   └── sub.h
├── lib
├── main.c
└── src
    ├── add.c
    ├── devide.c
    ├── multi.c
    └── sub.c

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

1.1 生成静态库文件

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

project(compute)

# 依赖的头文件
include_directories(${PROJECT_SOURCE_DIR}/include)

# 文件搜索
file(GLOB SRC "${PROJECT_SOURCE_DIR}/src/*.c")

# 设置生成库文件的路径(静态库\动态库都可行)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

MESSAGE("PROJECT_NAME:${PROJECT_NAME}")
MESSAGE("SRC:${SRC}")
MESSAGE("LIBRARY_OUTPUT_PATH:${LIBRARY_OUTPUT_PATH}")

# 生成静态库文件
add_library(${PROJECT_NAME} STATIC ${SRC})

# 生成动态库文件
#add_library(${PROJECT_NAME} SHARED ${SRC})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

make编译

# cd build/
# cmake ..
# make
  • 1
  • 2
  • 3

生成静态库文件 libcompute.a

在这里插入图片描述

1.2 生成动态库文件

# 生成动态库文件
#add_library(${PROJECT_NAME} SHARED ${SRC})
  • 1
  • 2

生成动态库文件 libcompute.so

在这里插入图片描述


注:Makefile文件内容

执行cmake,在build目录下会生成Makefile等文件
在这里插入图片描述

CMake是一个构建系统生成器。将描述构建系统(如:Unix Makefile、Ninja、Visual Studio等)应当如何操作才能编译代码。然后,CMake为所选的构建系统生成相应的指令。默认情况下,在GNU/Linux和macOS系统上,CMake使用Unix Makefile生成器。Windows上,Visual Studio是默认的生成器。

GNU/Linux上,CMake默认生成Unix Makefile来构建项目:

  • Makefile: make将运行指令来构建项目。
  • CMakefile:包含临时文件的目录,CMake用于检测操作系统、编译器等。此外,根据所选的生成器,它还包含特定的文件。
  • cmake_install.cmake:处理安装规则的CMake脚本,在项目安装时使用。
  • CMakeCache.txt:如文件名所示,CMake缓存。CMake在重新运行配置时使用这个文件。

另外,CMake生成的目标比构建可执行文件的目标要多。可以使用make help查看

在这里插入图片描述

  • all(或Visual Studio generator中的ALL_BUILD)是默认目标,将在项目中构建所有目标。

  • clean,删除所有生成的文件。

  • rebuild_cache,将调用CMake为源文件生成依赖(如果有的话)。

  • edit_cache,这个目标允许直接编辑缓存。

tips:

创建build目录后,在项目根目录通过以下命令,也可执行cmake

$ cmake -H. -Bbuild
  • 1

该命令是跨平台的,使用了-H-B为CLI选项。-H表示当前目录中搜索根CMakeLists.txt文件。-Bbuild告诉CMake在一个名为build的目录中生成所有的文件。


2、cmake生成可执行文件

目录结构

2.projectV2/
├── bin
├── build
├── CMakeLists.txt
├── include
│   ├── add.h
│   ├── devide.h
│   ├── multi.h
│   └── sub.h
├── lib
├── main.c
└── src
    ├── add.c
    ├── devide.c
    ├── multi.c
    └── sub.c
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.1 直接包含依赖的源文件

main依赖include头文件,依赖src下的c文件,生成main的可执行文件app.

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

project(compute)

# 依赖的头文件
include_directories(${PROJECT_SOURCE_DIR}/include)

# 文件搜索
file(GLOB SRC "${PROJECT_SOURCE_DIR}/src/*.c")

# 设置生成库文件的路径(静态库\动态库都可行)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

# 设置生成可执行文件的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

MESSAGE("PROJECT_NAME:${PROJECT_NAME}")
MESSAGE("SRC:${SRC}")
MESSAGE("LIBRARY_OUTPUT_PATH:${LIBRARY_OUTPUT_PATH}")
MESSAGE("EXECUTABLE_OUTPUT_PATH:${EXECUTABLE_OUTPUT_PATH}")

# 生成库文件
#add_library(${PROJECT_NAME} STATIC ${SRC})
# 生成动态库文件
# add_library(${PROJECT_NAME} SHARED ${SRC})

# 生成可执行文件
add_executable(app main.c ${SRC})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

执行cmake和make, 可在bin目录下生成可执行文件app
在这里插入图片描述

执行app,ok
在这里插入图片描述

那当前是通过包含${SRC}来生成可执行文件的,那如果只有库文件,无法获取源文件时,如何通过依赖libcompute.a或者libcompute.so生成可执行文件呢?

add_executable(app main.c ${SRC})
  • 1

2.2 链接静态库

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

project(compute)

# 依赖的头文件
include_directories(${PROJECT_SOURCE_DIR}/include)

# 文件搜索
file(GLOB SRC "${PROJECT_SOURCE_DIR}/src/*.c")

# 设置生成库文件的路径(静态库\动态库都可行)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

# 设置生成可执行文件的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

MESSAGE("PROJECT_NAME:${PROJECT_NAME}")
MESSAGE("SRC:${SRC}")
MESSAGE("LIBRARY_OUTPUT_PATH:${LIBRARY_OUTPUT_PATH}")
MESSAGE("EXECUTABLE_OUTPUT_PATH:${EXECUTABLE_OUTPUT_PATH}")

# 生成静态库文件
add_library(${PROJECT_NAME} STATIC ${SRC})

# 生成动态库文件
# add_library(${PROJECT_NAME} SHARED ${SRC})

# 生成可执行文件(方式一:直接包含源文件方式)
# add_executable(app main.c ${SRC})

# 生成可执行文件(方式二:链接静态库文件)
 ## 包含静态库路径
 link_directories(${PROJECT_SOURCE_DIR}/lib)
 ## 链接静态库文件(app 依赖静态库compute)
 link_libraries(compute)
 add_executable(app main.c)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

执行cmake
在这里插入图片描述

执行app,ok
在这里插入图片描述

2.3 链接动态库

cmake_minimum_required(VERSION 3.15)

project(compute)

# 依赖的头文件
include_directories(${PROJECT_SOURCE_DIR}/include)

# 文件搜索
file(GLOB SRC "${PROJECT_SOURCE_DIR}/src/*.c")

# 设置生成库文件的路径(静态库\动态库都可行)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

# 设置生成可执行文件的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

MESSAGE("PROJECT_NAME:${PROJECT_NAME}")
MESSAGE("SRC:${SRC}")
MESSAGE("LIBRARY_OUTPUT_PATH:${LIBRARY_OUTPUT_PATH}")
MESSAGE("EXECUTABLE_OUTPUT_PATH:${EXECUTABLE_OUTPUT_PATH}")

# 生成静态库文件
#add_library(${PROJECT_NAME} STATIC ${SRC})

# 生成动态库文件
add_library(${PROJECT_NAME} SHARED ${SRC})

# 生成可执行文件(方式一:直接包含源文件方式)
# add_executable(app main.c ${SRC})

# 生成可执行文件(方式二:链接静态库文件)
 ## 包含静态库路径
 # link_directories(${PROJECT_SOURCE_DIR}/lib)
 ## 链接静态库文件(app 依赖静态库compute)
 # link_libraries(compute)
 # add_executable(app main.c)

# 生成可执行文件(方式三:链接动态库文件)
 ## 包含动态库路径
  link_directories(${PROJECT_SOURCE_DIR}/lib)
 ## 生成可执行文件
  add_executable(app main.c)
  ## 链接动态库文件(app 依赖动态库compute)
  target_link_libraries(app compute)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

CMake 完整入门教程(五)_cmake菜鸟教程-CSDN博客

前言 - 《CMake菜谱(CMake Cookbook中文版)》 - 书栈网 · BookStack

(很详细)

CMake 保姆级教程(上) | 爱编程的大丙 (subingwen.cn)

搭配b站视频看,很棒

9. 在程序中链接动态库-上_哔哩哔哩_bilibili

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/766837
推荐阅读
相关标签
  

闽ICP备14008679号