cmake 是一个跨平台的自动构建工具(除了 cmake 之外,还有一些其它的自动构建工具,常用的譬如 automake、autoconf 等),cmake 的诞生主要是为了解决直接使用 make+Makefile 这种方式无法实现跨平台的问题,所以 cmake 是可以实现跨平台的编译工具,这是它最大的特点 。
sudo apt-get install cmake
安装完成之后可以通过 cmake --version 命令查看 cmake的版本号。cmake 官方也给大家提供相应教程,链接地址如下所示:
文档总链接地址: https://cmake.org/documentation/
培训教程:https://cmake.org/cmake/help/latest/guide/tutorial/index.html
main.c
#include
int main()
{
printf("Hello World!\n");
return 0;
}
CMakeList.txt
project(HELLO) #project 是一个命令,命令的使用方式有点类似于 C 语言中的函数,因为命令后面需要提供一对括号,并且通常需要我们提供参数,多个参数使用空格分隔而不是逗号“,”。project 命令用于设置工程的名称,括号中的参数 HELLO 便是我们要设置的工程名称;设置工程名称并不是强制性的,但是最好加上。
add_executable(hello ./main.c) #add_executable 同样也是一个命令,用于生成一个可执行文件,在本例中传入了两个参数,第一个参数表示生成的可执行文件对应的文件名,第二个参数表示对应的源文件
执行命令:
cmake ./ #生成Makefile
make
./hello
cmake 生成的文件以及最终的可执行文件 hello 与工程的源码文件 main.c 混在了一起,这使得工程看起来非常乱,当我们需要清理 cmake 产生的文件时将变得非常麻烦,这不是我们想看到的;我们需要将构建过程生成的文件与源文件分离开来,不让它们混杂在一起,也就是使用 out-of-source 方式构建
mkdir build
cd build
cmake ../
make
./hello
cd ..
rm -rf build #删除编译的结果(很关键)
#ifndef __TEST_HELLO_
#define __TEST_HELLO_
void hello(const char *name);
#endif //__TEST_HELLO_
hello.c:
#include
#include "hello.h"
void hello(const char *name)
{
printf("Hello %s!\n", name);
}
main.c:
#include "hello.h"
int main(void)
{
hello("World");
return 0;
}
CMakeList.txt:
project(HELLO)
set(SRC_LIST main.c hello.c)
add_executable(hello ${SRC_LIST}) #使用到了 set 命令,set 命令用于设置变量,如果变量不存在则创建该变量并设置它
project(HELLO)
add_library(libhello hello.c) #生成静态库.a文件
add_executable(hello main.c)
target_link_libraries(hello libhello) #target_link_libraries 命令为目标指定依赖库,在本例中,hello.c 被编译为库文件,并将其链接进 hello 程序。
如果要生成动态库文件,可以这样做:
add_library(libhello SHARED hello.c) #生成动态库文件
add_library(libhello STATIC hello.c) #生成静态库文件
add_library(hello hello.c) #不能修改生成库的名称,因为不能直接修改 add_library 命令的参数
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello") #用于设置目标的属性,这里通过 set_target_properties 命令对 libhello 目标的OUTPUT_NAME 属性进行了设置,将其设置为 hello
CMakeList.txt:
cmake_minimum_required(VERSION 3.5) #要求的最低的版本
project(HELLO)
add_library(libhello SHARED hello.c) #动态库
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello") #"hello" 属性
add_executable(hello main.c)
target_link_libraries(hello libhello) #参考上文,应用程序名称
# tree
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.16.3
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ ├── CMakeCCompilerId.c
│ │ │ │ └── tmp
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ ├── CMakeCXXCompilerId.cpp
│ │ │ └── tmp
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ └── TargetDirectories.txt
│ ├── cmake_install.cmake
│ ├── libhello
│ │ ├── CMakeFiles
│ │ │ ├── CMakeDirectoryInformation.cmake
│ │ │ ├── libhello.dir
│ │ │ │ ├── build.make
│ │ │ │ ├── C.includecache
│ │ │ │ ├── cmake_clean.cmake
│ │ │ │ ├── cmake_clean_target.cmake
│ │ │ │ ├── DependInfo.cmake
│ │ │ │ ├── depend.internal
│ │ │ │ ├── depend.make
│ │ │ │ ├── flags.make
│ │ │ │ ├── hello.c.o
│ │ │ │ ├── link.txt
│ │ │ │ └── progress.make
│ │ │ └── progress.marks
│ │ ├── cmake_install.cmake
│ │ ├── libhello.a
│ │ └── Makefile
│ ├── Makefile
│ └── src
│ ├── CMakeFiles
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── hello.dir
│ │ │ ├── build.make
│ │ │ ├── C.includecache
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── DependInfo.cmake
│ │ │ ├── depend.internal
│ │ │ ├── depend.make
│ │ │ ├── flags.make
│ │ │ ├── link.txt
│ │ │ ├── main.c.o
│ │ │ └── progress.make
│ │ └── progress.marks
│ ├── cmake_install.cmake
│ ├── hello
│ └── Makefile
├── CMakeLists.txt #顶层CMakeLists.txt
├── libhello
│ ├── CMakeLists.txt #CMakeLists.txt,在src文件夹中
│ ├── hello.c
│ └── hello.h
└── src
├── CMakeLists.txt #CMakeList.txt,在libhello文件夹中
└── main.c
16 directories, 56 files
cmake_minimum_required(VERSION 3.5)
project(HELLO)
add_subdirectory(libhello) #子目录
add_subdirectory(src) #子目录
include_directories(${PROJECT_SOURCE_DIR}/libhello) #新增加了 include_directories 命令用来指明头文件所在的路径,并且使用到了 PROJECT_SOURCE_DIR 变量,该变量指向了一个路径,从命名上可知,该变量表示工程源码的目录。
add_executable(hello main.c)
target_link_libraries(hello libhello)
add_library(libhello hello.c)
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")
include_directories(${PROJECT_SOURCE_DIR}/libhello)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) #设置bin文件夹
add_executable(hello main.c)
target_link_libraries(hello libhello)
(2)对 libhello 目录下的 CMakeList.txt 文件进行修改:
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
add_library(libhello hello.c)
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")
文件结构:
#tree
.
├── build
│ ├── bin
│ │ └── hello
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.16.3
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ ├── CMakeCCompilerId.c
│ │ │ │ └── tmp
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ ├── CMakeCXXCompilerId.cpp
│ │ │ └── tmp
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ └── TargetDirectories.txt
│ ├── cmake_install.cmake
│ ├── lib
│ │ └── libhello.a
│ ├── libhello
│ │ ├── CMakeFiles
│ │ │ ├── CMakeDirectoryInformation.cmake
│ │ │ ├── libhello.dir
│ │ │ │ ├── build.make
│ │ │ │ ├── C.includecache
│ │ │ │ ├── cmake_clean.cmake
│ │ │ │ ├── cmake_clean_target.cmake
│ │ │ │ ├── DependInfo.cmake
│ │ │ │ ├── depend.internal
│ │ │ │ ├── depend.make
│ │ │ │ ├── flags.make
│ │ │ │ ├── hello.c.o
│ │ │ │ ├── link.txt
│ │ │ │ └── progress.make
│ │ │ └── progress.marks
│ │ ├── cmake_install.cmake
│ │ └── Makefile
│ ├── Makefile
│ └── src
│ ├── CMakeFiles
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── hello.dir
│ │ │ ├── build.make
│ │ │ ├── C.includecache
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── DependInfo.cmake
│ │ │ ├── depend.internal
│ │ │ ├── depend.make
│ │ │ ├── flags.make
│ │ │ ├── link.txt
│ │ │ ├── main.c.o
│ │ │ └── progress.make
│ │ └── progress.marks
│ ├── cmake_install.cmake
│ └── Makefile
├── CMakeLists.txt
├── libhello
│ ├── CMakeLists.txt
│ ├── hello.c
│ └── hello.h
└── src
├── CMakeLists.txt
└── main.c
18 directories, 56 files