二、使用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.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})

make编译

# cd build/
# cmake ..
# make

生成静态库文件 libcompute.a

在这里插入图片描述

1.2 生成动态库文件

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

生成动态库文件 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

该命令是跨平台的,使用了-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

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})

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

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

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

add_executable(app main.c ${SRC})

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)

执行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)

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

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

(很详细)

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

搭配b站视频看,很棒

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值