赞
踩
虽然 Make 和 Makefile 简化了手动构建的过程,但是编写 Makefile 文件仍然是一个麻烦的工作,因此就有了 CMake 工具。CMake 工具用于生成 Makefile 文件,而如何生成 Makefile 文件,则由 CMakeLists.txt 文件指定。
make、Makefile、cmake、CMakeList.txt的关系如下图所示:
先创建个工程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
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
# 生成动态库文件
#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.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
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})
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
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站视频看,很棒
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。