【发布时间】:2021-09-27 19:14:12
【问题描述】:
如何将lib0 路径添加到lib1,以便从header1.h 可以#include <header0.h>?
| CMakeLists.txt
+---lib0
| CMakeLists.txt
| header0.c
| header0.h
+---lib1
| CMakeLists.txt
| header1.c
| header1.h
\---main
CMakeLists.txt
main.c
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(c_multilib C)
foreach (sub "lib0" "lib1" "main")
add_subdirectory("${sub}")
endforeach ()
lib0/CMakeLists.txt
add_library(lib0 "header0.h" "header0.c")
set_target_properties(lib0 PROPERTIES LINKER_LANGUAGE C)
include(GenerateExportHeader)
set(_generated_export_header "${CMAKE_CURRENT_SOURCE_DIR}/lib0_export.h")
generate_export_header(lib0 EXPORT_FILE_NAME "${_generated_export_header}")
target_include_directories(lib0
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<INSTALL_INTERFACE:include>"
)
install(FILES "header0.h" "${_generated_export_header}" DESTINATION "include")
lib0/header0.h
#ifndef C_MULTILIB_HEADER0_H
#define C_MULTILIB_HEADER0_H
#include "lib0_export.h"
int LIB0_EXPORT sum(int, int);
#endif /* C_MULTILIB_HEADER0_H */
lib0/header0.c
#include "header0.h"
int sum(int a, int b) {return a+b;}
lib1/CMakeLists.txt
add_library(lib1 "header1.h" "header1.c")
set_target_properties(lib1 PROPERTIES LINKER_LANGUAGE C)
include(GenerateExportHeader)
set(_generated_export_header "${CMAKE_CURRENT_SOURCE_DIR}/lib1_export.h")
generate_export_header(lib1 EXPORT_FILE_NAME "${_generated_export_header}")
target_include_directories(lib1
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${${PROJECT_NAME}_SOURCE_DIR}/lib0>"
"$<INSTALL_INTERFACE:include>"
)
install(FILES "header1.h" "${_generated_export_header}" DESTINATION "include")
lib1/header1.h
#ifndef C_MULTILIB_HEADER1_H
#define C_MULTILIB_HEADER1_H
#include <header0.h>
#include "lib1_export.h"
int LIB1_EXPORT add1(int);
#endif /* C_MULTILIB_HEADER1_H */
lib1/header1.c
#include <header1.h>
int add1(int a) {return sum(a, 1);}
main/CMakeLists.txt
add_executable("main" "main.c")
target_link_libraries("main" "lib0" "lib1")
target_include_directories(
"main"
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${${PROJECT_NAME}_SOURCE_DIR}/lib0>"
"$<BUILD_INTERFACE:${${PROJECT_NAME}_SOURCE_DIR}/lib1>"
"$<INSTALL_INTERFACE:include>"
)
main/main.c
#include <header0.h>
#include <header1.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("sum(1,5) =\t%d\n"
"add1(5) =\t%d\n", sum(1,5), add1(6));
return EXIT_SUCCESS;
}
尝试:
# lib1/CMakeLists.txt
target_include_directories(
lib1
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
#"$<BUILD_INTERFACE:lib0>"
#"$<BUILD_INTERFACE:../../lib0>"
#"$<BUILD_INTERFACE:${${PROJECT_NAME}_SOURCE_DIR}/src/lib0>"
"$<INSTALL_INTERFACE:include>"
)
install(FILES "header1.h" DESTINATION "include")
错误范围:
致命错误 C1083:无法打开包含文件:'header0.h':没有这样的文件或目录
到:
目标在其 INTERFACE_INCLUDE_DIRECTORIES 中包含相对路径
还给get_target_property(LIB0_INCLUDES "lib0" INCLUDE_DIRECTORIES):
使用不存在的目标“lib0”调用get_target_property()。
【问题讨论】:
-
您没有提供足够的信息来说明问题所在。请根据 Stack Overflow 指南提供minimal reproducible example。具体来说,请显示
lib1/CMakeLists.txt文件的其余部分,以及其他 CMake 文件的内容,以便为您如何设置目标 lib0 和 lib1 以及它们的设置顺序提供上下文... -
@squareskittles 好的,我添加了一个完整的示例。这有点冗长:(
-
谢谢,还请提供您收到的所提供代码的完整错误,包括周围的日志和编译消息,以便为构建链中发生此错误的where提供上下文.
-
实际上并不清楚您希望通过您的代码实现什么。例如。假设
header0.cincludes 标头header0.h,带有该标头的目录应该使用 PRIVATE 或 PUBLIC 关键字添加,但不能使用 INTERFACE 关键字。 (您知道 CMake 中关键字 PUBLIC/PRIVATE/INTERFACE 的含义吗?)。在给定的假设下,lib0的代码完全是错误的,您需要在编写使用lib0的lib1的代码之前修复它。 -
不确定为什么要在可执行文件中使用
INTERFACE包含目录;您不能将可执行文件链接到另一个目标,并且INTERFACE...属性的全部要点将通过链接目标来使用。这就是为什么我的约定是在设置可执行文件的属性时简单地使用PRIVATE可见性;这也意味着您无需费心使用生成器表达式来区分构建/安装界面;您只是不为可执行文件提供任何标头; all 已经是你的二进制文件的一部分了。
标签: cmake target cmake-language