一、使用方法
一般把CMakeLists.txt文件放在工程目录下,使用时,先创建一个叫build的文件夹(这个并非必须,只是生成的Makefile等文件放在build里比较整齐),然后执行下列操作:
cd build
cmake ..
make
其中cmake .. 在build里生成Makefile,make应当在有Makefile的目录下,根据Makefile生成可执行文件。
二、编写方法
-
# 声明要求的cmake最低版本
-
cmake_minimum_required( VERSION 2.8 )
-
-
# 添加c++11标准支持
-
set( CMAKE_CXX_FLAGS
"-std=c++11" )
-
-
# 声明一个cmake工程
-
project( 工程名 )
-
-
MESSAGE(STATUS
"Project: SERVER")
#打印相关消息消息
-
-
# 找到后面需要库和头文件的包
-
find_package(包的名称及最低版本)
-
# 例如find_package(OpenCV 2.4.3 REQUIRED)
-
-
-
# 头文件
-
include_directories(
"路径")
-
# 例如
-
#include_directories(
-
# ${PROJECT_SOURCE_DIR}
-
# ${PROJECT_SOURCE_DIR}/include
-
# ${EIGEN3_INCLUDE_DIR}
-
)
-
-
# 设置路径(下面生成共享库的路径)
-
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/lib)
-
# 即生成的共享库在工程文件夹下的lib文件夹中
-
-
# 创建共享库(把工程内的cpp文件都创建成共享库文件,方便通过头文件来调用)
-
add_library(
${PROJECT_NAME} SHARED
-
src/cpp文件名
-
……
-
)
-
# 这时候只需要cpp,不需要有主函数
-
# ${PROJECT_NAME}是生成的库名 表示生成的共享库文件就叫做 lib工程名.so
-
# 也可以专门写cmakelists来编译一个没有主函数的程序来生成共享库,供其它程序使用
-
-
# 链接库
-
# 把刚刚生成的${PROJECT_NAME}库和所需的其它库链接起来
-
target_link_libraries(
${PROJECT_NAME}
-
/usr/lib/i386-linux-gnu/libboost_system.so
-
)
-
-
# 编译主函数,生成可执行文件
-
-
# 先设置路径
-
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/bin)
-
-
# 可执行文件生成
-
add_executable(要生成的可执行文件名 从工程目录下写起的主函数文件名)
-
-
# 这个可执行文件所需的库(一般就是刚刚生成的工程的库咯)
-
target_link_libraries(可执行文件名
${PROJECT_NAME})
cmake中一些预定义变量
- PROJECT_SOURCE_DIR 工程的根目录
- PROJECT_BINARY_DIR 运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build
- CMAKE_INCLUDE_PATH 环境变量,非cmake变量
- CMAKE_LIBRARY_PATH 环境变量
- CMAKE_CURRENT_SOURCE_DIR 当前处理的CMakeLists.txt所在的路径
- CMAKE_CURRENT_BINARY_DIR target编译目录
使用ADD_SURDIRECTORY(src bin)可以更改此变量的值
SET(EXECUTABLE_OUTPUT_PATH <新路径>)并不会对此变量有影响,只是改变了最终目标文件的存储路径 - CMAKE_CURRENT_LIST_FILE 输出调用这个变量的CMakeLists.txt的完整路径
- CMAKE_CURRENT_LIST_LINE 输出这个变量所在的行
- CMAKE_MODULE_PATH 定义自己的cmake模块所在的路径
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块 - EXECUTABLE_OUTPUT_PATH 重新定义目标二进制可执行文件的存放位置
- LIBRARY_OUTPUT_PATH 重新定义目标链接库文件的存放位置
- PROJECT_NAME 返回通过PROJECT指令定义的项目名称
- CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 用来控制IF ELSE语句的书写方式
假设当前的项目代码在src 目录。 src 下有子目录:server, utility, lib, bin, build
server ----- 存放项目的主功能类文件
utility ----- 存放项目要用到相关库文件,便已成为库文件存放到子目录lib 中
lib ----- 存放utility 生成的库
bin ----- 存放association 生成的二进制文件
build ----- 编译目录,存放编译生成的中间文件
cmake 要求工程主目录和所有存放源代码子目录下都要编写CMakeLists.txt 文件,注意大小写(cm 大写,list中l 大写且落下s).
src/CMakeLists.txt 文件如下:
-
#cmake file for project association #表示注释
-
-
#author:>---double__song
-
-
#created:>--2011/03/01
-
-
-
CMAKE_MINIMUM_REQUIRED(VERSION
2.8)
#cmake 最低版本要求,低于2.6 构建过程会被终止。
-
-
-
PROJECT(server_project)
#定义工程名称
-
-
-
MESSAGE(STATUS
"Project: SERVER")
#打印相关消息消息
-
-
MESSAGE(STATUS
"Project Directory: ${PROJECT_SOURCE_DIR}")
-
-
-
-
SET(
CMAKE_C_FLAGS_DEBUG
"-g -Wall")
#指定编译器
-
-
-
ADD_SUBDIRECTORY(utility)
#添加子目录
-
-
ADD_SUBDIRECTORY(server)
相关解释:
1. CMakeLists.txt 文件中不区分大小写
2. PROJECT(project_name) 定义工程名称
语法:project(projectname [cxx] [c] [java])
可以指定工程采用的语言,选项分别表示:C++, C, java, 如不指定默认支持所有语言
3. MESSAGE(STATUS, "Content") 打印相关消息
输出消息,供调试CMakeLists.txt 文件使用。
4. SET(CMAKE_BUILE_TYPE DEBUG) 设置编译类型debug 或者release。 debug 版会生成相关调试信息,可以使用GDB 进行
调试;release不会生成调试信息。当无法进行调试时查看此处是否设置为debug.
5. SET(CMAKE_C_FLAGS_DEBUG "-g -Wall") 设置编译器的类型
CMAKE_C_FLAGS_DEBUG ---- C 编译器
CMAKE_CXX_FLAGS_DEBUG ---- C++ 编译器
6. ADD_SUBDIRECTORY(utility) 添加要编译的子目录
为工程主目录下的存放源代码的子目录使用该命令,各子目录出现的顺序随意。
如上便是工程server_project 主目录src 下的CMakeLists.txt 文件,下一篇我们解释子目录utiltiy中的CMakeLists.txt 文件。
子目录utility 下的CMakeLists.txt 文件如下:
-
#Cmake file for library utility.a
-
-
#Author: double__song
-
-
#Created: 2011/3/3
-
-
-
SET(SOURCE_FILES
#设置变量,表示所有的源文件
-
-
ConfigParser.cpp
-
-
StrUtility.cpp
-
-
)
-
-
INCLUDE_DIRECTORIES(
#相关头文件的目录
-
-
/usr/
local/include
-
-
${PROJET_SOURCE_DIR}/utility
-
-
)
-
-
-
LINK_DIRECTORIES(
#相关库文件的目录
-
-
/usr/
local/lib
-
-
)
-
-
-
ADD_LIBRARY(association ${SOURCE_FILES})
#生成静态链接库libassociation.a
-
-
TARGET_LINK_LIBRARY(association core)
#依赖的库文件
-
-
-
SET_TARGET_PROPERTIES(utility PROPERTIES
#表示生成的执行文件所在路径
-
-
RUNTIME_OUTPUT_DIRECTORY>
"${PROJECT_SOURCE_DIR}/lib")
相关解释:
1. SET(SOURCE_FILES .....)
表示要编译的源文件,所有的源文件都要罗列到此处。set 设置变量,变量名SOURCE_FILES自定义。
2. INCLUDE_DIRECTORY(...)
include头文件时搜索的所有目录
变量PROJECT_SOURCE_DIR 表示工程所在的路径,系统默认的变量
3. LINK_DIRECTORIES(...)
库文件存放的目录,在程序连接库文件的时候要再这些目录下寻找对应的库文件
4. ADD_LIBRARY(...)
表示生成静态链接库libassociaiton.a,由${PROJECT_SOURCE_DIR}代表的文件生成。
语法:ADD_LIBRARY(libname [SHARED|STATIC]
SHARED 表示生成动态库, STATIC表示生成静态库。
5. TARGET_LINK_LIBRARY(association core)
表示库association 依赖core库文件
6. SET_TARGET_PROPERTIES
设置编译的库文件存放的目录,还可用于其他属性的设置。如不指定,
生成的执行文件在当前编译目录下的各子目录下的build目录下,好拗口!简单一点:
如指定在: ./src/lib 下
不指定在: ./src/build/utility/build 目录下
生成的中间文件在./src/build/utilty/build 目录下,不受该命令额影响
子目录server 下的CMakeLists.txt 文件:
-
--------------------------------------------------------------------------------------------
-
-
SET(SOURCE_FILES
-
-
Gassociation.cpp
-
-
ConfigurationHandler.cpp
-
-
)
-
-
INCLUDE_DIRECTORIES(
-
-
/usr/
local/
include
-
-
${PROJECT_SOURCE_DIR}/utility
-
-
${PROJECT_SOURCE_DIR}/association
-
-
)
-
-
LINK_LIBRARIES(
-
-
/usr/
local/lib
-
-
${PROJECT_SOURCE_DIR}/lib
-
-
)
-
-
ADD_EXECUTABLE(
server ${SOURCE_FILES})
-
-
TARGET_LINK_LIBRARIES(
server
-
-
utility
-
-
)
-
-
SET_TARGET_PROPERTIES(
server PROPERTIES #表示生成的执行文件所在路径
-
-
RUNTIME_OUTPUT_DIRECTORY
"${PROJECT_SOURCE_DIR}/bin")
相关解释:
1. ADD_EXECUTABLE() #指定要生成的执行文件的名称server
其他用法同utilty/CMakeLists.txt
2. SET_TARGET_PROPERTIES
设置生成的执行文件存放的路径,
注意:
执行文件server 依赖的子目录utility 子目录生成的静态库libutility.a,在指定的时候要写成:
TARGET_LINK_LIBRARIES(server utility)
而不能写成:
TARGET_LINK_LIBRARIES(server libutility.a)
否则编译总会提示找不到libutility库文件。
但使用第三方的库却要指定成具体的库名,如:libACE-6.0.0.so
这一点很诡异,暂时还没找到原因。
完成对应的CMakeLists.txt 文件编写后,便可以进行编译了。
编译:
进入 ./src/build
执行cmake ..
make
configure --prefix=/:作用:
指定安装路径
不指定prefix,则可执行文件默认放在/usr /local/bin,库文件默认放在/usr/local/lib,配置文件默认放在/usr/local/etc。其它的资源文件放在/usr /local/share。你要卸载这个程序,要么在原来的make目录下用一次make uninstall(前提是make文件指定过uninstall),要么去上述目录里面把相关的文件一个个手工删掉。
指定prefix,直接删掉一个文件夹就够了。