项目目录结构
第一个项目,肯定是大家都懂的“hello world”了。那就先来看一下这个“庞大”的项目结构吧。
| [study@leoox hello]$ tree . |-- CMakeLists.txt |-- build `-- main.c 1 directory, 2 files |
哈哈,其实就只有一个代码文件 main.c。源码内容嘛,程序员都知道。
|
#include <stdio.h>
int
main(int
argc,
char**
argv)
{
printf("hello
world\n");
return
0;
}
|
至于CMakeLists.txt嘛,那当然就是今天的主角了。换句话说,以前的Makefile(makefile)已经被CMakeLists.txt取代了。稍后再重点介绍。
还有一个空文件夹build,干嘛用的呢。它就相当于一个垃圾桶,我们实用cmake的外部构建的方式的时候,编译过程中产生的一些中间文件,比如.o文件,cmake本身的中间文件等等都会放到build里面。而我们的源码目录干干净净,是不是很适合有代码洁癖的你呢。
撸起袖子写cmake
按照以前,我就得去找其他项目的Makefile过来改,然后凑合的用了。可现在,我可以“骄傲”的说,我可以白手起家搞定CMakeLists.txt。一起见证奇迹!
| project(hello) cmake_minimum_required(VERSION 2.8) add_executable(hello main.c) |
哈哈,就是这么简单。就3行cmake语法。其实前面2行可以不写,你只写一行就可以了。既然写了,就稍微解释一下语法吧(太深入,我也不懂)。
PROJECT(projectname [CXX] [C] [JAVA])
用于指定工程名字,[]为可选内容,默认表示支持所有语言。注意这条指令还隐式定义了另外两个变量<projectName>_BINARY_DIR 和<projectName>_SOURCE_DIR。我们这里的project定义为了hello,所以这两个变量就是${hello_BINARY_DIR} 和 ${hello_SOURCE_DIR}。什么意思呢,可以用message命令打印出来看看他的值。
${hello_BINARY_DIR} :就是cmake要(构建)编译我们的项目(main.c)的具体路径。这里当然就是build。
${hello_SOURCE_DIR} :就是我们项目的源码的具体路径,这里当然是项目的根目录。
如果采用的是内部构建的方式,即直接在项目根目录下运行cmake,那这两个变量的值是一样的。不过一般很少使用这两个变量。大家都比较喜欢用 ${CMAKE_SOURCE_DIR} 和 ${CMAKE_BINARY_DIR}.
cmake_minimum_required
这个就比较好理解了,就是这个项目要求的cmake版本不能低于2.8版本。当使用新版本的cmake才有的特性的时候,就需要加上这个了。
add_executable
顾名思义,就是要生成一个可执行程序hello呗。注意这里的hello和project里面的hello是没有关系的。这里的hello,是说最终编译出来的二进制文件名字叫hello。你可以改成你喜欢的名字。那hello当然是通过main.c来编译的了。如果有多个.c文件,一并在后面加入就行。但是如果你深入学习了cmake,其实是不用一个一个手工写.c文件的。这里只有一个main.c就无所谓了。
加上message打印cmake调试信息后的cmake如下:
|
project(hello)
cmake_minimum_required(VERSION
2.8)
message(STATUS
"src dir = ${hello_SOURCE_DIR}")
message(STATUS
"binary dir = ${hello_BINARY_DIR}")
message(STATUS
"leoox src dir = ${CMAKE_SOURCE_DIR}")
message(STATUS
"leoox binary dir = ${CMAKE_BINARY_DIR}")
add_executable(hello
main.c)
|
愉快的编译项目吧
运行cmake的方式就是 :
cmake CMakeLists.txt所在的路径
我们采用外部构建的方式。到build文件夹里面(cd build)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | [study@leoox build]$ cmake .. -- The C compiler identification is GNU 4.1.2 -- The CXX compiler identification is GNU 4.1.2 -- 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 -- 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 -- src dir = /home/study/program/cmake/hello -- binary dir = /home/study/program/cmake/hello/build -- leoox src dir = /home/study/program/cmake/hello -- leoox binary dir = /home/study/program/cmake/hello/build -- Configuring done -- Generating done -- Build files have been written to: /home/study/program/cmake/hello/build [study@Thrift build]$ ls CMakeCache.txt CMakeFiles Makefile cmake_install.cmake [study@leoox build]$ ls .. CMakeLists.txt build main.c [study@leoox build]$ |
哈哈,太好了。cmake帮我生成了Makefile。而代码外面还是非常干净的,就一个mian.c。通过message打印出来的信息看,果然验证了上面的解释。
那接下来就可以开心的make了
|
[study@leooxbuild]$
make
Scanning
dependencies
of
target
hello
[100%]
Building
C
object
CMakeFiles/hello.dir/main.c.o
Linking
C
executable
hello
[100%]
Built
target
hello
[study@Thrift
build]$
ls
..
CMakeLists.txt build main.c
[study@leoox
build]$
ls
CMakeCache.txt CMakeFiles Makefile cmake_install.cmake hello
[study@leoox
build]$
./hello
hello
world
|
让make更透明些
make顺利的执行成功了,也得到了我们期待的“hello world”。但是make的信息太简单了,感觉空落落的。以前的Makefile可都是打印出gcc 等详细编译过程的哦。
不要担心,make的时候加个参数就行了。
make VERBOSE=1
这样你就可以在编译信息里面看到你想要的详细的gcc/g++的编译参数了。比如:
[100%] Building C object CMakeFiles/hello.dir/main.c.o
/usr/bin/cc -o CMakeFiles/hello.dir/main.c.o -c /home/study/program/cmake/hello/main.c
Linking C executable hello
什么,要在make的时候写参数。太不友好了。cmake知道你懒,所以也帮你搞定了。在CMakeLists.txt里面加上这句指令就可以了。
set(CMAKE_VERBOSE_MAKEFILE ON)
|
project(hello)
cmake_minimum_required(VERSION
2.8)
set(CMAKE_VERBOSE_MAKEFILE
ON)
message(STATUS
"src dir = ${hello_SOURCE_DIR}")
message(STATUS
"binary dir = ${hello_BINARY_DIR}")
message(STATUS
"leoox src dir = ${CMAKE_SOURCE_DIR}")
message(STATUS
"leoox binary dir = ${CMAKE_BINARY_DIR}")
add_executable(hello
main.c)
|
真爽,睡觉~~