上一节学习的是静态库,这里就学习如何链接动态库

一、 文件树

  1. ├── CMakeLists.txt
  2. ├── include
  3. └── shared
  4. └── Hello.h
  5. └── src
  6. ├── Hello.cpp
  7. └── main.cpp

1.1 Hello.h

/* 声明了Hello类,Hello的方法是print() */

#ifndef __HELLO_H__
#define __HELLO_H__

class Hello {
public:
    void print();
};

#endif

1.2 Hello.cpp

/* 实现了Hello::print() */

#include <iostream>
#include "shared/Hello.h"

void Hello::print()
{
    std::cout << "Hello Shared Library!" << std::endl;
}

1.3 main.cpp

#include "shared/Hello.h"

int main(int argc, char *argv[]) {
    Hello hi;
    hi.print();
    return 0;
}

1.4 CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(hello_library)

# 1.创建库,根据Hello.cpp,生成动态库hello-library
add_library(hello_library SHARED src/Hello.cpp)

# 2.给动态库hello_library换个名字hello::library
add_library(hello::library ALIAS hello_library)

# 3.为这个库添加头文件路径,PUBLIC表示包含了这个库的目标也会包含这个路径
target_include_directories(hello_library PUBLC ${PROJECT_SOURCE_DIR}/include)

# 4.创建可执行文件
add_executable(hello_binary src/main.cpp)

# 5.链接库和可执行文件,使用这个库的别名,使用PRIVATE表示
target_link_libraries(hello_binary PRIVATE hello::library)

二、CMake解析

2.1 创建动态库

add_library() 函数用于从某些源文件创建一个动态库,默认生成在构建文件夹。 写法如下:

add_library(hello_library SHARED src/Hello.cpp)

add_library 调用中包含了源文件,用于创建名称为 libhello_library.so 的动态库。

注意:如前面的示例所述,将源文件直接传递给 **add_library** 调用,这是 modern CMake 的建议。(而不是先把 Hello.cpp 赋给一个变量)

2.2 创建别名目标

顾名思义,别名目标是在只读上下文中可以代替真实目标名称的替代名称。

add_library(hello::library ALIAS hello_library)

如下所示,当您将目标链接到其他目标时,使用别名可以引用目标。

链接共享库与链接静态库相同。 创建可执行文件时,请使用 target_link_library() 函数指向您的库 。

add_executable(hello_binary src/main.cpp)

target_link_libraries(hello_binary PRIVATE hello::library)

这告诉 CMake 使用别名目标名称将 hello_library 链接到 hello_binary 可执行文件。

三、构建示例

$ mkdir build

$ cd build

$ cmake ..
-- The C compiler identification is GNU 8.4.1
-- The CXX compiler identification is GNU 8.4.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/CmakeTest/build


$ make
[ 25%] Building CXX object CMakeFiles/hello_library.dir/src/Hello.cpp.o
[ 50%] Linking CXX shared library libhello_library.so
[ 50%] Built target hello_library
[ 75%] Building CXX object CMakeFiles/hello_binary.dir/src/main.cpp.o
[100%] Linking CXX executable hello_binary
[100%] Built target hello_binary

$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  hello_binary  libhello_library.so  Makefile

$ ./hello_binary
Hello Shared Library!