目标:使用CMake构建多级的目录的C++项目,包含动态库的引用。
文件结构:
.
├── CMakeLists.txt # 1
├── build
├── lib # 这里存放动态库
│ ├── CMakeLists.txt # 2
│ ├── lib-bye
│ │ ├── CMakeLists.txt # 3
│ │ └── bye.cc # 4
│ └── lib-hello
│ ├── CMakeLists.txt # 5
│ └── hello.cc # 6
└── src
├── CMakeLists.txt # 7
├── MyClass.cc # 8
├── MyClass.h # 9
├── MyFile
│ ├── SubMyClass.cc # 10
│ └── SubMyClass.h # 11
├── bye.h # 12 仅仅提供符号链接
├── hello.h # 13
└── main.cc # 14
先给出编译的效果:
1
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
PROJECT(MAIN)
MESSAGE(STATUS "This is bin dir: " ${PROJECT_BINARY_DIR})
MESSAGE(STATUS "This is src dir:" ${PROJECT_SOURCE_DIR})
ADD_SUBDIRECTORY(lib) # 先编译动态链接库
ADD_SUBDIRECTORY(src) # 最后编译工程,工程依赖动态链接
2
ADD_SUBDIRECTORY(lib-hello) # 单独编译hello的动态链接库
ADD_SUBDIRECTORY(lib-bye) # 单独编译bye的动态链接库
3
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin/lib) # 设置.so的输出路径
FILE(GLOB_RECURSE SRC_LIST *.h *.cc *cc *hpp) # 递归地寻找目录下所有的匹配目录
ADD_LIBRARY(bye SHARED ${SRC_LIST}) # 创建bye动态链接库,不加SHARED是静态库
MESSAGE(STATUS "finish build lib-bye") # 成功编译地消息
4
#include <iostream>
// 这里仅仅用了一个简单地函数,作为说明示例。
void bye() {
std::cout << "bye" << std::endl;
}
5
# 同lib-bye
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin/lib)
FILE(GLOB_RECURSE SRC_LIST *.h *.cc)
ADD_LIBRARY(hello SHARED ${SRC_LIST})
MESSAGE(STATUS "finish build lib-hello")
6
#include <iostream>
void hello() {
std::cout << "hello" << std::endl;
}
7
FILE(GLOB_RECURSE SRC_LIST *.h *.cc *.hpp *.cpp) # 递归的找当前CMakeLists.txt下所有匹配的文件
MESSAGE(STATUS "finish get all file")
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) # 设置二进制目录存储文件
MESSAGE(STATUS "finish set executable file: " ${EXECUTABLE_OUTPUT_PATH})
ADD_EXECUTABLE(main ${SRC_LIST}) # 编译工程目录
MESSAGE("finish build project")
LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/bin/lib) # 链接数据
TARGET_LINK_LIBRARIES(main hello bye) # 注意这里,链接的名称要和lib中声明的名称一致,不要有其它的
MESSAGE(STATUS "finish link lib")
8
#include "MyClass.h"
#include <iostream>
void MyClass::foo() {
std::cout << "MyClass::foo" << std::endl;
}
9
#ifndef MY_CLASS_H
#define MY_CLASS_H
class MyClass {
public:
void foo();
};
#endif
10
#include "SubMyClass.h"
#include <iostream>
void SubMyClass::foo() {
std::cout << "SubMyClass::foo" << std::endl;
}
11
#ifndef SUB_MY_CLASS_H
#define SUB_MY_CLASS_H
class SubMyClass {
public:
void foo();
};
#endif
12
#ifndef BYE_H
#define BYE_H
void bye(); // 声明,仅仅提供符号链接
#endif
13
#ifndef HELLO_H
#define HELLO_H
void hello(); // 声明,仅仅提供符号链接
#endif
14
#include <iostream>
#include "MyClass.h"
#include "./MyFile/SubMyClass.h"
#include "hello.h"
#include "bye.h"
int main() {
std::cout << "Hello, World !" << std::endl;
MyClass mc;
mc.foo();
SubMyClass smc;
smc.foo();
hello();
bye();
return 0;
}