几个基本指令
PROJECT 指令
用于指定工程名和支持的语言(默认支持所有语言),比如
PROJECT(NEWPROJ) 指定工程名NEWPROJ,并支持所有语言
PROJECT(NEWPROJ CXX) 指定工程名NEWPROJ,支持的语言是C++
PROJECT(NEWPROJ C CXX) 指定工程名NEWPROJ,支持的语言是C和C++
隐式定义了2个CMake变量
<projectname>_BINARY_DIR和<projectname>_SOURCE_DIR
<projectname>为指定的工程名,如果改变,上面两个变量名也会发生变化。
还可以使用PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR ,这两个变量和前两个是一致的,且不会因为工程名改变而变。
SET 指令
显示地指定变量,例如:
SET(SRC_LIST main.cpp) SRC_LIST变量包含main.cpp
SET(SRC_LIST main.cpp test1.cpp test2.cpp) SRC_LIST变量包含main.cpp test1.cpp test2.cpp
MESSAGE 指令
向终端输出用户自定义信息,主要包含三种:
- SEND_ERROR 产生错误,生成过程被跳过
- STATUS,输出一条状态信息
- FATAL_ERROR 立刻终止cmake进程
ADD_EXECUTABLE 指令
生产可执行文件
ADD_EXCUTABLE(newproj ${SRC_LIST}) 生成的可执行文件名为newproj ,源文件读取变量SRC_LIST的内容
如果SRC_LIST变量只有一个main.cpp,也可以这样写:
ADD_EXCUTABLE(newproj main.cpp)
语法基本原则
- 变量使用 ${} 方式取值,**但是在IF控制语句中直接使用变量名 **
- 指令的使用方法为: 指令(参数1 参数2…),指令不区分大小写,参数区分大小写,参数之间用空格或者分号隔开。
- 文件名作为参数时可以不加双引号,若文件名中含有空格,则必须加上双引号。
- 源文件名不加后缀在某些情况下不写不会出错,CMake会去目录下找对应的.c和.cpp文件,但最好不要这样写。
构建方法:内部构建与外部构建
内部构建
不进行目录的建立,将所有临时文件生成在源文件目录下。
简单内部构建例子:
文件目录
\NEWPROJ
|CMakeLists.txt
|main.cpp
文件内容
CMakeLists.txt:
PROJECT(NEWPROJ)
SET(SRC_LIST main.cpp)
ADD_EXECUTABLE(newproj ${SRC_LIST})
main.cpp:
#include<iostream>
using namespace std;
int main(){
cout<<"Hello World!"<<endl;
return 0;
}
在终端使用cmake:
❯ ls
CMakeLists.txt main.cpp
❯ cmake .
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/newpro
❯ make
Scanning dependencies of target newproj
[ 50%] Building CXX object CMakeFiles/newproj.dir/main.cpp.o
[100%] Linking CXX executable newproj
[100%] Built target newproj
❯ ./newproj
Hello World!
此时文件目录
├── CMakeCache.txt
├── CMakeFiles
│ ├── 3.16.3
│ │ ├── CMakeCCompiler.cmake
│ │ ├── CMakeCXXCompiler.cmake
│ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ ├── CMakeSystem.cmake
│ │ ├── CompilerIdC
│ │ │ ├── CMakeCCompilerId.c
│ │ │ ├── a.out
│ │ │ └── tmp
│ │ └── CompilerIdCXX
│ │ ├── CMakeCXXCompilerId.cpp
│ │ ├── a.out
│ │ └── tmp
│ ├── CMakeDirectoryInformation.cmake
│ ├── CMakeOutput.log
│ ├── CMakeTmp
│ ├── Makefile.cmake
│ ├── Makefile2
│ ├── TargetDirectories.txt
│ ├── cmake.check_cache
│ ├── newproj.dir
│ │ ├── CXX.includecache
│ │ ├── DependInfo.cmake
│ │ ├── build.make
│ │ ├── cmake_clean.cmake
│ │ ├── depend.internal
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ ├── main.cpp.o
│ │ └── progress.make
│ └── progress.marks
├── CMakeLists.txt
├── Makefile
├── cmake_install.cmake
├── main.cpp
└── newproj
8 directories, 32 files
最终编译出了可执行文件newproj并且可以顺利运行,但是可以看到在目录下生成了许多中间文件。而CMake并没有提供clean选项来清除这些中间文件,所以这种内部构建的方法一般只用于较简单的项目/文件的构建,对于较大的工程/项目一般不推荐用这种方法。
外部构建
把生成的临时文件放在build目录下,不会对源文件有影响。推荐使用这种构建方式。
外部构建方法
- 在当前项目的主目录下新建一个build目录,作为临时文件的存放目录。
- 进入build目录,使用命令
cmake ..
(..
表示上一级目录,如果把build放在主目录下这个…也就是表示主目录,当然,不嫌麻烦也可以使用绝对路径),这样一来生成的临时文件就都在build目录下了。 - 在build目录下,使用
make
命令来构建工程。
外部构建举例
还是使用上面那个例子,文件目录结构一致,此时新建一个build目录,文件目录为:
文件目录
\NEWPROJ
|\bulid
|.
|CMakeLists.txt
|main.cpp
在终端进入build目录并使用cmake:
❯ mkdir build && cd build
❯ cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
m-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jwchen/newpro/build
❯ make
Scanning dependencies of target newproj
[ 50%] Building CXX object CMakeFiles/newproj.dir/main.cpp.o
[100%] Linking CXX executable newproj
[100%] Built target newproj
❯ ./newproj
Hello World!
此时文件目录:
├── CMakeLists.txt
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.16.3
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── CMakeCCompilerId.c
│ │ │ │ ├── a.out
│ │ │ │ └── tmp
│ │ │ └── CompilerIdCXX
│ │ │ ├── CMakeCXXCompilerId.cpp
│ │ │ ├── a.out
│ │ │ └── tmp
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── Makefile.cmake
│ │ ├── Makefile2
│ │ ├── TargetDirectories.txt
│ │ ├── cmake.check_cache
│ │ ├── newproj.dir
│ │ │ ├── CXX.includecache
│ │ │ ├── DependInfo.cmake
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── depend.internal
│ │ │ ├── depend.make
│ │ │ ├── flags.make
│ │ │ ├── link.txt
│ │ │ ├── main.cpp.o
│ │ │ └── progress.make
│ │ └── progress.marks
│ ├── Makefile
│ ├── cmake_install.cmake
│ └── newproj
└── main.cpp
9 directories, 32 files
此时所有的中间文件便都在build目录下了,如果需要进行清理,只需要在build目录下rm -r *
即可。
TIPS 外部构建时PROJECT_SOURCE_DIR 不变但是PROJECT_BINARY_DIR会变成build目录