任务
- 建⽴⼀个静态库和动态库,提供 HelloFunc 函数供其他程序编程使⽤,HelloFunc 向终端输出 Hello World 字
符串。 - 安装头⽂件与共享库。
构建过程
构建动态库
目录结构
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01$ tree
.
├── build #在一个build文件中进行外部构建
├── CMakeLists.txt
└── lib
├── CmakeLists.txt
├── hello.cpp
└── hello.h
hello.h
#ifndef HELLO_H
#define Hello_H
void HelloFunc();
#endif
hello.cpp
#include "hello.h"
#include <iostream>
void HelloFunc(){
std::cout << "Hello World" << std::endl;
}
cmake01/CMakeLists.txt
PROJECT(HELLO)
ADD_SUBDIRECTORY(lib bin)
cmake01/lib/CMakeLists.txt
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) 解释:
用${LIBHELLO_SRC}生成动态库,生成的动态库名字为libhello.so
生成的动态库存放在cmake01/build/bin 目录下,这是
cmake01/CMakeLists.txt
中代码导致的。
开始构建
- 进入build目录,并执行cmake生成makefile文件,最后再执行make生成动态库文件
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/lib$ cd ../build/
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ cmake ..
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ make
- 得到的结果,可以看到bin目录下有
libhello.so
这个动态库文件:
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build/bin$ ls
CMakeFiles cmake_install.cmake libhello.so Makefile
同时构建动态库和静态库
只需要修改cmake01/lib/CMakeLists.txt
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
#对hello_static进行重命名为hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
#表示在执行make clean时会删除名为hello_static的目标文件
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
开始构建
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ cmake ..
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ make
安装共享库和使用外部共享库及头文件
修改cmake01/lib/CMakeLists.txt
SET(LIBHELLO_SRC hello.cpp)
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
#对hello_static进行重命名为hello
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
#表示在执行make clean时会删除名为hello_static的目标文件
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
#安装头文件
INSTALL(FILES hello.h DESTINATION include/hello)
#⼆进制,静态库,动态库安装都⽤TARGETS
#ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME 特指可执⾏⽬标⼆进制。
INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
开始构建动态库和静态库并安装
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ cmake -DCMAKE_INSTALL_PREFIX=/usr .. #指定安装路径的前缀
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ make
jyhlinux@ubuntu:~/share/makefile_cmake/cmake01/build$ sudo make install
使用外部共享库及头文件
新建一个项目,结构如下
jyhlinux@ubuntu:~/share/makefile_cmake/cmake02$ tree
.
├── build
├── CMakeLists.txt
└── src
├── CMakeLists.txt
└── main.cpp
main.cpp
#include <hello.h>
int main(){
HelloFunc();
}
cmake02/CMakeLists.txt
PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)
cmake02/src/CMakeLists.txt
ADD_EXECUTABLE(hello main.cpp)
开始编译
jyhlinux@ubuntu:~/share/makefile_cmake/cmake02/build$ cmake ..
jyhlinux@ubuntu:~/share/makefile_cmake/cmake02/build$ make
此时会出现如下错误
表示找不到这个头文件,原因是:
这个头文件在 /usr/include/hello
中,而系统默认只会在/usr/include/
目录下查找头文件。所以得添加该目录,即修改cmake02/src/CMakeLists.txt
INCLUDE_DIRECTORIES(/usr/include/hello) #注意位置
ADD_EXECUTABLE(hello main.cpp)
之后再次编译,又会出现如下错误:undefined reference to
.
这个错误一般是缺失库文件,解决办法就是**添加需要连接的共享库。**在cmake02/src/CMakeLists.txt
进行修改
INCLUDE_DIRECTORIES(/usr/include/hello)
ADD_EXECUTABLE(hello main.cpp)
TARGET_LINK_LIBRARIES(hello libhello.so) #添加需要连接的共享库 /usr/lib/libhello.so
如果要连接静态库,就改变为TARGET_LINK_LIBRARIES(hello libhello.a)
再次编译后可以通过,并生成目标可执行文件 hello,存放在cmake/02/build/bin
目录下,并可以成功执行
参考资料
- 从零开始详细介绍CMake