CMKAE总结
cmake:生成一个makefile文件。
make:根据这个makefile文件的内容编译整个工程。
cmake . :在当前目录调用cmake进行分析
mkdir build
cd build
cmake ..:对上一称文件夹,也就是代码所在的文件夹进行编译.这样cmake产生的中间文件就会在build文件夹中,与源代码分开。
cy.cpp
#include <iostream>
using namespace std;
int main()
{
cout<<"hello cy"<<endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(cy)
#add_executa(程序名 源代码文件)
add_executable(cy cy.cpp)
使用库
在一个c++工程中,并不是所有代码都会编译成可执行文件。只有带main函数的文件才会生成可执行程序,而另一些代码,我们只想把他们打包成一个东西,供其他程序调用,这个东西就是库。
//下面这个是库文件,没有main函数
#include <iostream>
using namespace std;
void printcy()
{
cout<<"uselib"<<endl;
//return 0;
}
在CMakeLists.txt加入以下命令即可。
#这条命令告诉cmake,我们想把这个文件编译成一个叫做“libcy"的库。.a为后缀名。
add_library(libcy libcy.cpp)
add_library(libcy_shared SHARED libcy.cpp)
#共享库,.so为后缀名。
静态库每次被调用都会生成一个副本,而共享库则只有一个副本。
实例
库文件是一个压缩包,里面有编译好的二进制函数。为了让别人使用这个库,需要提供一个头文件,只要拿到了头文件和库文件,就可以调用这个库了。
#ifndef LIBCY_H
#define LIBCY_H
void printcy();
#endif
uselib.cpp
#include "libcy.h"
using namespace std;
int main()
{
printcy();
return 0;
}
#target_link_libraries(程序名 库文件名)
add_executable(uselib uselib.cpp)
target_link_libraries(uselib libcy)
cmake practice
1,准备工作:
首先,在/backup 目录建立一个 cmake 目录,用来放置我们学习过程中的所有练习。
mkdir -p /backup/cmake
以后我们所有的 cmake 练习都会放在/backup/cmake 的子目录下(你也可以自行安排目录,
这个并不是限制,仅仅是为了叙述的方便)
然后在 cmake 建立第一个练习目录 t1
cd /backup/cmake
mkdir t1
cd t1
在 t1 目录建立 main.c 和 CMakeLists.txt(注意文件名大小写):
main.c 文件内容:
//main.ca
#include <stdio.h>
int main()
{
printf(“Hello World from t1 Main!\n”);
return 0;
}
CmakeLists.txt 文件内容:
PROJECT (HELLO)
//PROJECT(projectname [CXX] [C] [Java]),默认情况表示支持所有语言。这个指令隐式的定义了变量:<projectname>_BINARY_DIR 以及<projectname>_SOURCE_DIR,这里就是HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR(所以后面 MESSAGE指令可以直接使用了这两个变量),因为采用的是内部编译,两个变量目前指的都是工程所在路径/backup/cmake/t1,与外部编译所指代的内容会有所不同。
SET(SRC_LIST main.c)
//SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]),如果有多个源文件,也可以定义成:SET(SRC_LIST main.c t1.c t2.c)。
//SET(SRC_LIST main.c)也可以写成 SET(SRC_LIST “main.c”)
MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})
//MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...)
这个指令用于向终端输出用户定义的信息,包含了三种类型:
SEND_ERROR,产生错误,生成过程被跳过。
SATUS ,输出前缀为 — 的信息。FATAL_ERROR,立即终止所有 cmake 过程.
我们在这里使用的是 STATUS 信息输出,演示了由 PROJECT 指令定义的两个隐式变量
HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR。
在本例我们使用了${}来引用变量,这是 cmake 的变量应用方式,但是,有一些例外,比
如在 IF 控制语句,变量是直接使用变量名引用,而不需要${}。如果使用了${}去应用变
量,其实 IF 会去判断名为${}所代表的值的变量,那当然是不存在的了。
ADD_EXECUTABLE(hello SRC_LIST)
//定义了这个工程会生成一个文件名为 hello 的可执行文件,相关的源文件是 SRC_LIST 中定义的源文件列表, 本例中你也可以直接写成 ADD_EXECUTABLE(hello main.c)。
ADD_EXECUTABLE(t1 main.c)编译后会生成一个 t1 可执行文件。
可以忽略掉 source 列表中的源文件后缀,比如可以写成ADD_EXECUTABLE(t1 main),cmake 会自动的在本目录查找 main.c 或者 main.cpp
等,当然,最好不要偷这个懒,以免这个目录确实存在一个 main.c 一个 main.
make clean
即可对构建结果进行清理。
外部构建
对于 cmake,内部编译上面已经演示过了,它生成了一些无法自动删除的中间文件,所以,
引出了我们对外部编译的探讨,外部编译的过程如下:
1,首先,请清除 t1 目录中除 main.c CmakeLists.txt 之外的所有中间文件,最关键
的是 CMakeCache.txt。
2,在 t1 目录中建立 build 目录,当然你也可以在任何地方建立 build 目录,不一定必
须在工程目录中。
3,进入 build 目录,运行 cmake ..
4,运行 make 构建工程,就会在当前目录(build 目录)中获得目标文件 hello。
通过外部编译进行工程构建,HELLO_SOURCE_DIR 仍然指代工程路径,即
/backup/cmake/t1
而 HELLO_BINARY_DIR 则指代编译路径,即/backup/cmake/t1/build
指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令。
在ubuntu主目录建立一个文件夹cy。