CMake接口库的文件可见性设置
我在研究接口库中文件集合的可见性时有一个问题。若我有一个接口库,它有一个头文件集合且其可见性为接口可见,那么使用这个库的消费者能看到的内容就很清楚。可是当我把可见性改为 PRIVATE 时,消费者仍然可以看到头文件的内容,这点让我困惑。
下面有一个示例。请看 CMakeLists.txt 中标注的1.与 2.的注释。共有两个接口库 ggg 和 ggg1。ggg 包含 include/g.h。ggg1 包含 ggg 和 include/g1.h。主目标链接到 ggg1。如果这些文件集合的可见性为 INTERFACE,主目标可以访问 include/g.h 和 include/g1.h。但如果第二个文件集合被设为 PRIVATE(见下文),我原本以为会失败。不过构建却成功了。
项目根目录包含 CMakeLists.txt,以及子目录 src 和 build。以下是 CMakeLists.txt:
# file: CMakeLists.txt
cmake_minimum_required(VERSION 3.30)
project(test20 VERSION 1.0 LANGUAGES CXX)
add_library(ggg INTERFACE)
target_sources(ggg
INTERFACE
FILE_SET ggg_headers
TYPE HEADERS
BASE_DIRS include
FILES
include/g.h
)
add_library(ggg1 INTERFACE)
target_sources(ggg1
PRIVATE
FILE_SET ggg1_headers
TYPE HEADERS
BASE_DIRS include
FILES
include/g1.h
)
target_link_libraries(ggg1
INTERFACE ggg
)
add_executable(main)
target_sources(main
PRIVATE
src/main.cpp
)
target_link_libraries(main
PRIVATE ggg1
)
以下是主C++源文件:
// file: src/main.cpp
#include <iostream>
#include "g.h"
#include "g1.h"
int main()
{
g();
g1();
return 0;
}
包含目录中有两个文件,g.h 和 g1.h。
// file: include/g.h
#ifndef G_H
#define G_H
#include <iostream>
inline void g()
{
std::cout << "g()\n";
}
#endif
以下是 include/g1.h
// file: include/g1.h
#ifndef G1_H
#define G1_H
#include <iostream>
inline void g1()
{
std::cout << "g1()\n";
}
#endif
解决方案
这是预期的行为。
- 因为
include/g.h与include/g1.h位于同一个基础目录, ggg是ggg1的一个接口依赖,ggg1获得ggg的-Iinclude,ggg1是main的一个依赖,main继承ggg的-Iinclude,- 构建成功。
如果将文件位置改为 include/g/g.h 和 include/g1/g1.h,则构建会失败,因为 main 会获得 -Iinclude/g,而得不到 -Iinclude/g1。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。