参考链接🔗:
CMAKE 里PRIVATE、PUBLIC、INTERFACE属性示例详解
cmake:target_** 中的 PUBLIC,PRIVATE,INTERFACE
1. 指令说明
target_include_directories():指定目标包含的头文件路径。官方文档
target_link_libraries():指定目标链接的库。官方文档
target_compile_options():指定目标的编译选项。官方文档
目标 由 add_library() 或 add_executable() 生成。
这三个指令类似,这里以 target_include_directories() 为例进行讲解。
target_include_directories(<Target>
PUBLIC <dirs>…
PRIVATE <dirs>…
INTERFACE <dirs>…
)
那么这三种添加头文件夹的方式有什么区别呢?
假如有一个库lib,还有一个应用exe,其中exe依赖lib
lib使用:
• PUBLIC,两个项目都会添加include
• PRIVATE,只有lib会添加include
• INTERFACE,只有exe会添加include
结构:
code:
从上往下:
CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(subprojects)
add_subdirectory(sublibrary1)
add_subdirectory(sublibrary2)
add_subdirectory(subbinary)
主目录 subbinary - CMakeLists.txt
project(subbinary)
set(CMAKE_CXX_STANDARD 14)
# create the executable
add_executable(${PROJECT_NAME} main.cpp)
# link static library from subproject1 using alias sub1::lib1
# link the header only library from subproject2 using it's alias sub::lib2
target_link_libraries(
${PROJECT_NAME}
sub::lib1
sub::lib2
)
main.cpp
#include "../sublibrary1/include/sublib1/sublib1.h"
#include "../sublibrary2/include/sublib2/sublib2.h"
/*
* sublibrary1 - A static library
* sublibrary2 - A header only library
* subbinary - An executable
*/
int main(int argc, char *argv[])
{
sublib1 hi;
hi.print();
sublib2 howdy;
howdy.print();
return 0;
}
--------
子目录1 sublibrary1 - CMakeLists.txt
project(sublibrary1)
add_library(${PROJECT_NAME} src/sublib1.cpp)
add_library(sub::lib1 ALIAS ${PROJECT_NAME})
target_include_directories(
${PROJECT_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}/sublibrary1/include
)
sublib1.h
#ifndef CMAKER_LEARNING_SUBLIB1_H
#define CMAKER_LEARNING_SUBLIB1_H
class sublib1
{
public:
void print();
};
#endif //CMAKER_LEARNING_SUBLIB1_H
sublib1.cpp
#include <iostream>
#include "../include/sublib1/sublib1.h"
void sublib1::print() {
std::cout << "Hello sub-library 1!" << std::endl;
}
----
子目录2 sublibrary2 - CMakeLists.txt
project(sublibrary2)
add_library(${PROJECT_NAME} INTERFACE)
add_library(sub::lib2 ALIAS ${PROJECT_NAME})
target_include_directories(
${PROJECT_NAME}
INTERFACE
${PROJECT_SOURCE_DIR}/sublibrary2/include
)
sublib2.h, 直接头文件
#ifndef CMAKER_LEARNING_SUBLIB2_H
#define CMAKER_LEARNING_SUBLIB2_H
#include <iostream>
class sublib2
{
public:
void print()
{
std::cout << "Hello header only sub-library 2!" << std::endl;
}
};
#endif //CMAKER_LEARNING_SUBLIB2_H
运行:
(base) ➜ cmaker_learning cd build
(base) ➜ build ls
(base) ➜ build cmake ..
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/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: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/xxx/CLionProjects/cmaker_learning/build
(base) ➜ build make
[ 25%] Building CXX object sublibrary1/CMakeFiles/sublibrary1.dir/src/sublib1.cpp.o
[ 50%] Linking CXX static library libsublibrary1.a
[ 50%] Built target sublibrary1
[ 75%] Building CXX object subbinary/CMakeFiles/subbinary.dir/main.cpp.o
[100%] Linking CXX executable subbinary
[100%] Built target subbinary
(base) ➜ build cd subbinary
(base) ➜ subbinary ls
CMakeFiles Makefile cmake_install.cmake subbinary
(base) ➜ subbinary ./subbinary
Hello sub-library 1!
Hello header only sub-library 2!