【Make编译控制 08】CMake动静态库

目录

一、编译动静态库

二、链接静态库

三、链接动态库


前情提示:【Make编译控制 07】CMake常用命令-CSDN博客

有些时候我们编写的源代码并不需要将他们编译生成可执行程序,而是生成一些静态库或动态库提供给第三方使用,所以我们需要用到 add_library 命令来生成库。

一、编译动静态库

add_library(库名称 库类型 源文件1 [源文件2] ...) 

# 编译动态库
add_library(库名称 SHARED 源文件1 [源文件2] ...) 
# 在Linux中,动态库名字分为三部分:lib+库名字+.so,
# 此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。

# 编译静态库
add_library(库名称 STATIC 源文件1 [源文件2] ...) 
# 在Linux中,静态库名字分为三部分:lib+库名字+.a
# 和动态库一样,只用写出库名。

# 在Windows中虽然库名和Linux格式不同,但也只需指定出名字即可。
(base) [root@localhost 10_test]# tree .
.
├── CMakeLists.txt
├── include
│   ├── add.h
│   └── sub.h
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

2 directories, 6 files
(base) [root@localhost 10_test]#
# CMakeLists.txt 文件

cmake_minimum_required(VERSION 2.8)
project(MATH)
set(CMAKE_CXX_STANDARD 11)

include_directories(${PROJECT_SOURCE_DIR}/include)

aux_source_directory(${CMAKE_SOURCE_DIR}/src SRC_LIST)
list(REMOVE_ITEM SRC_LIST ${CMAKE_SOURCE_DIR}/src/main.cpp)

# ----------------- 编译静态库 -----------------
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
# EXECUTABLE_OUTPUT_PATH 用于指定输出路径
# 在Linux下生成的动态库默认是有执行权限的,所以可以直接用 EXECUTABLE_OUTPUT_PATH 宏
# Linux下生成的静态库默认不具有可执行权限,所以需要用 LIBRARY_OUTPUT_PATH 宏
# LIBRARY_OUTPUT_PATH 宏对静态库和动态库都适用

add_library(myaddsub STATIC ${SRC_LIST})
# add_library(myaddsub SHARED ${SRC_LIST})
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# make
Scanning dependencies of target myaddsub
[ 50%] Building CXX object CMakeFiles/myaddsub.dir/src/add.cpp.o
[100%] Building CXX object CMakeFiles/myaddsub.dir/src/sub.cpp.o
Linking CXX static library ../lib/libmyaddsub.a
[100%] Built target myaddsub
(base) [root@localhost build]# tree ..
..
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 2.8.12.2
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   └── CMakeCCompilerId.c
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       └── CMakeCXXCompilerId.cpp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── myaddsub.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── cmake_clean_target.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       ├── add.cpp.o
│   │   │       └── sub.cpp.o
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   └── Makefile
├── CMakeLists.txt
├── include
│   ├── add.h
│   └── sub.h
├── lib
│   └── libmyaddsub.a
└── src
    ├── add.cpp
    ├── main.cpp
    └── sub.cpp

11 directories, 38 files

二、链接静态库

link_libraries( [...])
# 参数1:指定出要链接的静态库的名字,可以是完整库名,也可以是去掉前后缀的库名
# 参数2-N:要链接的其它静态库的名字
cmake_minimum_required(VERSION 2.8)
project(MATH)
set(CMAKE_CXX_STANDARD 11)

include_directories(${PROJECT_SOURCE_DIR}/include)

aux_source_directory(${CMAKE_SOURCE_DIR}/src SRC_LIST)
list(REMOVE_ITEM SRC_LIST ${CMAKE_SOURCE_DIR}/src/main.cpp)

# ----------------- 编译静态库 -----------------
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
# EXECUTABLE_OUTPUT_PATH 用于指定输出路径
# 在Linux下生成的动态库默认是有执行权限的,所以可以直接用 EXECUTABLE_OUTPUT_PATH 宏
# Linux下生成的静态库默认不具有可执行权限,所以需要用 LIBRARY_OUTPUT_PATH 宏
# LIBRARY_OUTPUT_PATH 宏对静态库和动态库都适用

add_library(myaddsub STATIC ${SRC_LIST})
# add_library(myaddsub SHARED ${SRC_LIST})

# ----------------- 链接静态库 -----------------
link_libraries(myaddsub)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/workspace)
add_executable(app ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# make
Scanning dependencies of target myaddsub
[ 33%] Building CXX object CMakeFiles/myaddsub.dir/src/add.cpp.o
[ 66%] Building CXX object CMakeFiles/myaddsub.dir/src/sub.cpp.o
Linking CXX static library ../lib/libmyaddsub.a
[ 66%] Built target myaddsub
Scanning dependencies of target app
[100%] Building CXX object CMakeFiles/app.dir/src/main.cpp.o
Linking CXX executable ../workspace/app
[100%] Built target app
(base) [root@localhost build]# tree ..
..
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 2.8.12.2
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   └── CMakeCCompilerId.c
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       └── CMakeCXXCompilerId.cpp
│   │   ├── app.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       └── main.cpp.o
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── myaddsub.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── cmake_clean_target.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       ├── add.cpp.o
│   │   │       └── sub.cpp.o
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   └── Makefile
├── CMakeLists.txt
├── include
│   ├── add.h
│   └── sub.h
├── lib
│   └── libmyaddsub.a
├── src
│   ├── add.cpp
│   ├── main.cpp
│   └── sub.cpp
└── warkspace
    └── app

14 directories, 49 files
(base) [root@localhost build]# ../workspace/app 
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost build]# 

三、链接动态库

target_link_libraries(
     
     ... 
    [ ...]...)

target:指定要加载动态库的文件的名字

  • 该文件可能是一个源文件
  • 该文件可能是一个动态库文件
  • 该文件可能是一个可执行文件

PRIVATE|PUBLIC|INTERFACE:动态库的访问权限,默认为PUBLIC

  • 如果各个动态库之间没有依赖关系,无需做任何设置,三者没有没有区别,一般无需指定,使用默认的 PUBLIC 即可。
  • 动态库的链接具有传递性,如果动态库 A 链接了动态库B、C,动态库D链接了动态库A,此时动态库D相当于也链接了动态库B、C,并可以使用动态库B、C中定义的方法。

动态库的链接和静态库是完全不同的:

  • 静态库会在生成可执行程序的链接阶段被打包到可执行程序中,所以可执行程序启动,静态库就被加载到内存中了。
  • 动态库在生成可执行程序的链接阶段不会被打包到可执行程序中,当可执行程序被启动并且调用了动态库中的函数的时候,动态库才会被加载到内存。

因此,在cmake中指定要链接的动态库的时候,应该将命令写到生成了可执行文件之后:

# CMakeLists.txt 文件

cmake_minimum_required(VERSION 2.8)
project(MATH)
set(CMAKE_CXX_STANDARD 11)

include_directories(${PROJECT_SOURCE_DIR}/include)

aux_source_directory(${CMAKE_SOURCE_DIR}/src SRC_LIST)
list(REMOVE_ITEM SRC_LIST ${CMAKE_SOURCE_DIR}/src/main.cpp)

# ----------------- 编译动态库 -----------------
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
# EXECUTABLE_OUTPUT_PATH 用于指定输出路径
# 在Linux下生成的动态库默认是有执行权限的,所以可以直接用 EXECUTABLE_OUTPUT_PATH 宏
# Linux下生成的静态库默认不具有可执行权限,所以需要用 LIBRARY_OUTPUT_PATH 宏
# LIBRARY_OUTPUT_PATH 宏对静态库和动态库都适用

# add_library(myaddsub STATIC ${SRC_LIST})
add_library(myaddsub SHARED ${SRC_LIST})

# ----------------- 链接动态库 -----------------
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/workspace)
add_executable(app ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)

target_link_libraries(app myaddsub pthread)
# 可以连接多个动态库
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# make
Scanning dependencies of target myaddsub
[ 33%] Building CXX object CMakeFiles/myaddsub.dir/src/add.cpp.o
[ 66%] Building CXX object CMakeFiles/myaddsub.dir/src/sub.cpp.o
Linking CXX shared library ../lib/libmyaddsub.so
[ 66%] Built target myaddsub
Scanning dependencies of target app
[100%] Building CXX object CMakeFiles/app.dir/src/main.cpp.o
Linking CXX executable ../workspace/app
[100%] Built target app
(base) [root@localhost build]# tree ..
..
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 2.8.12.2
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   └── CMakeCCompilerId.c
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       └── CMakeCXXCompilerId.cpp
│   │   ├── app.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       └── main.cpp.o
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── myaddsub.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── link.txt
│   │   │   ├── progress.make
│   │   │   └── src
│   │   │       ├── add.cpp.o
│   │   │       └── sub.cpp.o
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   └── Makefile
├── CMakeLists.txt
├── include
│   ├── add.h
│   └── sub.h
├── lib
│   └── libmyaddsub.so
├── src
│   ├── add.cpp
│   ├── main.cpp
│   └── sub.cpp
└── workspace
    └── app

14 directories, 48 files
(base) [root@localhost build]# ../workspace/app 
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost build]# 

你可能感兴趣的:(Make编译控制,makefile,linux,cmake)