CMakeLists使用:使用cmake构建工程的详细过程
CMake是一个跨平台的程序构建工具,通过编写cmakelist.txt文件然后通过cmake和make命令就可以编译工程。下面主要介绍一下cmakelist.txt的编写规则以及过程。先从简单的工程说起。
第一:首先构建比较简单的工程
1.构建一个工程的时候,需要做的几件事情(如果下面几件事你知道怎么做了,多大的工程就都不是问题了):
源代码在什么位置?
头文件在哪里?
怎么生成静态或者动态库?
程序链接的静态库在哪里?
如果工程的代码存放在很多地方,那又该怎么找到它们呢?
第二:下面从一个最简单的HelloWorld开始,然后一步一步构建一个比较复杂的工程:
A.工程文件如下(只有一个helloworld.cpp源文件):
#include<iostream>
int main()
{
std::cout<<"hello, world"<<std::endl;
return 0;
}
B.这时候,我们要写一个CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
PROJECT(sayhello) #定义整个CMake的工程名
FILE(GLOB SOURCE "./*.cpp") #告诉CMake:工程的源文件在哪里?
ADD_EXECUTABLE(sayhello ${SOURCE}) #告诉CMake:我们要生成可执行文件(sayhello)
使用cmake . && make 就可以在目录下生成一个hello可执行文件了。
如果要添加编译选项,可以通过下面的方法添加:
cmake_minimum_required(VERSION 2.8)
PROJECT(sayhello) #定义整个CMake的工程名
FILE(GLOB SOURCE "./*.cpp") #告诉CMake:工程的源文件在哪里?
ADD_DEFINITIONS("-Wall -std=c++11") # 新增的编译选项
ADD_EXECUTABLE(sayhello ${SOURCE}) #告诉CMake:我们要生成可执行文件(sayhello)
第三:构建包含头文件和源文件的工程
A.代码分布如下(main.cpp是main函数,里面调用了hello.h声明的SayHello,定义在hello.cpp中):
B.main的代码:
#include"hello.h"
int main()
{
SayHello();
return 0;
}
C.CMakeLists.txt内容
cmake_minimum_required(VERSION 2.8)
PROJECT(sayhello)
FILE(GLOB SOURCE_1 "${CMAKE_SOURCE_DIR}/src/*.cpp") //程序必须链接到hello.cpp里面的函数
FILE(GLOB SOURCE_2 "${CMAKE_SOURCE_DIR}/main/*.cpp") //告诉源文件地址
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include/") //头文件
ADD_EXECUTABLE(${PROJECT_NAME} ${SOURCE_1} ${SOURCE_2}) //生成可执行文件,可执行文件名sayhello
第四:更高级一点工程的构建过程,生成库文件
A.工程描述:该工程在上一个工程的基础上将hello函数编译成一个动态链接库(.so文件,类似于Windows下的.dll文件)
B.CMakeLists.txt内容
cmake_minimum_required(VERSION 2.8)
PROJECT(hello)
FILE(GLOB SOURCE_1 "${CMAKE_SOURCE_DIR}/src/*.cpp")
FILE(GLOB SOURCE_2 "${CMAKE_SOURCE_DIR}/main/*.cpp")
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include/")
ADD_LIBRARY(hello SHARED ${SOURCE_1}) //告诉cmake生成一个动态链接库libhello.so
LINK_LIBRARIES(hello) //链接生成
ADD_EXECUTABLE(sayhello ${SOURCE_2}) //根据main.cpp生成可执行文件
TARGET_LINK_LIBRARIES(sayhello ${hello})//将libhello.so链接到可执行文件
最后编译一下就可以自动生成一个libhello.so文件和sayhello的可执行文件。如果要生成静态链接库(.a文件)的话,只需要将上面的 SHARED 参数换成 STATIC 就可以了。
整个编译的过程就是这样了,最主要的是记住上面”构建一个工程的时候,需要做的几件事情:头文件,源文件,库文件这个元素“,再复杂的工程都是这样一步一步的构建出来的。