一. CMake Hello World
- 首先,建立第一个练习目录 t1文件夹,用来存放 CMake Hello word 项目
cd cmake
mkdir t1
cd t1
- 在 t1 目录建立 hello.c 和 CMakeLists.txt(注意文件名大小写):
hello.c 文件内容如下:
//main.c
#include<stdio.h>
int main(){
printf("Hello World from t1 Main!\n");
return 0;
}
CmakeLists.txt 文件内容如下所示:
PROJECT (HELLO)
ADD_EXECUTABLE(hello hello.c)
- 外部构建:内部编译会产生一些无法自动删除的中间文件。out-of-source对原有的工程没有任何影响,所有动作全部发生在编译目录。
mkdir build # 建立 build 目录
cd build
cmake .. # 生成 编译 Makefile 以及其他中间文件
make # 构建工程
./hello
二. 构建大型文件结构
- 新建一个 t2 目录。将 t1 工程的 main.c 和 CMakeLists.txt 拷贝到 t2 目录中。添加子目录 src,并将对应的main 移动到src中
mkdir src
mv main.c src
现在的工程看起来是这个样子:一个子目录 src,一个 CMakeLists.txt。
- 进入子目录 src,编写 CMakeLists.txt 如下:
ADD_EXECUTABLE(hello main.c)
- 将 t2 工程的 CMakeLists.txt 修改为:
PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)
- 然后建立 build 目录,进入 build 目录进行外部编译。
cmake ..
make
构建完成后,你会发现生成的目标文件 hello 位于 build/bin 目录中。
我们都可以通过 SET 指令重新定义 EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH 变量来指定最终的目标二进制的位置(指最终生成的 hello 或者最终的共享库,不包含编译生成的中间文件)。
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
可执行二进制的输出路径为 build/bin 和库的输出路径为 build/lib.问题是,我应该把这两条指令写在工程的 CMakeLists.txt 还是 src 目录下的CMakeLists.txt,把握一个简单的原则,在哪里 ADD_EXECUTABLE 或 ADD_LIBRARY,如果需要改变目标存放路径,就在哪里加入上述的定义。
- 我们可以使用INSTALL 指令进行安装,对于不同的文件类型,安装的指令不同
# 目标文件的安装
INSTALL(TARGETS myrun mylib mystaticlib
RUNTIME DESTINATION bin # 可执行二进制 myrun
LIBRARY DESTINATION lib # 动态库 libmylib
ARCHIVE DESTINATION libstatic # 静态库libmystaticlib
)
# 文件的安装
INSTALL(FILES hello.h DESTINATION include/hello)
# 目录的安装
INSTALL(DIRECTORY icons DESTINATION share/myproj)
三. 生成动态链接库和静态链接库
- 建立一个练习目录 t3 文件夹,用来存放 CMake Library 项目
mkdir t3
cd t3
mkdir lib
- 在 t3 目录下建立 CMakeLists.txt 和 lib 目录, 内容如下:
PROJECT(HELLOLIB)
ADD_SUBDIRECTORY(lib)
- 在 lib 目录下建立两个源文件 hello.c 与 hello.h, 和一个 CMakeLists.txt 文件。
hello.c 内容如下:
#include “hello.h”
void HelloFunc()
{
printf(“Hello World\n”);
}
hello.h 内容如下所示:
#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
void HelloFunc();
#endif
在 lib 目录下建立 CMakeLists.txt,内容如下:
SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
# 类型有三种:
# SHARED,动态库
# STATIC,静态库
# MODULE,在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。
- 然后建立 build 目录,进入 build 目录进行外部编译。
cmake ..
make
- 安装共享库和头文件
INSTALL(TARGETS hello LIBRARY DESTINATION lib) # 静态库 替换为 ARCHIVE
INSTALL(FILES hello.h DESTINATION include) # 对应的头文件
- 通过如下命令,我们就可以将头文件和共享库安装到系统目录/usr/lib 和/usr/include中了。
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
make install
四. 使用动态链接库和静态链接库
- 建立一个练习目录 t4 文件夹, 用来存 cmake_call_lab project项目。
mkdir t4
cd t4
建立 src 目录和 CMakeLists 文件。在src 中新建一个 CMakeLists 和 main.c 文件
MakeLists 的内容如下所示:
# CMakeLists.txt
PROJECT(NEWHELLO)
ADD_SUBDIRECTORY(src)
src 中的main文件内容如下所示:
int main()
{
HelloFunc();
return 0;
}
src/CMakeLists.txt 内容如下所示:
INCLUDE_DIRECTORIES(/usr/include) # 添加头文件搜索路径
ADD_EXECUTABLE(main main.c)
TARGET_LINK_LIBRARIES(main libhello.so) # link 到共享库 libhello.so 上
- 执行外部构建
mkdir build
cd build
cmake ..
make
小结一下:
- 首先我们需要实现
.cpp
和.h
两个文件。其中.h
为接口文件,.h
为实现 - 然后用编写CMakeLists 文件。将
.cpp
编译为动态链接库*.so
,放入/usr/lib
。并将*.h
放入/usr/include
。 - 新建一个文件,对动态链接库进行调用。在
*.cpp
中导入对应的*.h
文件 。并在对应的CMakeLists
中添加对应的头文件搜索路径。并链接共享库。
参考书籍: 《cmake 实战》