文章目录
二、使用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站视频看,很棒