How do I add lib0
path to lib1
such that from header1.h
I can #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;
}
Attempts:
# 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")
Errors range from:
fatal error C1083: Cannot open include file: 'header0.h': No such file or directory
to:
Target contains relative path in its INTERFACE_INCLUDE_DIRECTORIES
Also get_target_property(LIB0_INCLUDES "lib0" INCLUDE_DIRECTORIES)
gave:
get_target_property() called with non-existent target "lib0".
The src/lib0/CMakeLists.txt
should look something like this
add_library(lib0 INTERFACE)
target_include_directories(lib0 INTERFACE ${CMAKE_CURRENT_LIST_DIR})
The word INTERFACE
tells Cmake that there is nothing to compile.
The src/lib1/CMakeLists.txt
should look something like this
add_library(lib1 INTERFACE)
target_include_directories(lib1 INTERFACE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(lib1 INTERFACE lib0)
The src/CMakeLists.txt
should look something like
add_subdirectory(lib0)
add_subdirectory(lib1)
# Assuming that your src target is called my_proj:
target_link_libraries(my_proj PRIVATE lib0 lib1)
EDIT:
I can confirm that the code that you provide compiles if you change all of the includes from lib1_export...
to header1
and modify the following 3 CMakeLists.txt files:
lib0/CMakeLists.txt
:
add_library(lib0 header0.c)
target_include_directories(lib0 PUBLIC ${CMAKE_CURRENT_LIST_DIR})
lib1/CMakeLists.txt
:
add_library(lib1 header1.c)
target_include_directories(lib1 PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(lib1 PUBLIC lib0)
main/CMakeLists.txt
:
add_executable(main main.c)
target_link_libraries(main PRIVATE lib0 lib1)
It is not clear to me what you are trying to achieve with the generator expressions (the angle brackets). If you explain what you are trying to accomplish, then we can suggest the proper fixes.