What I want is a main library, based on an interface (in the future more than one). That interface must be used by other libs, like lib1 and lib2. The idea is to create lib1 and lib2 as static, and then link both to the mainLib, which must be a shared library.
For this example, let's imagine I'm only using lib1, because the process would be the same for lib2.
My problem is that I don't really know how to link the libraries correctly. First I need to link the interface library with lib1, so it becomes a new static library and this one has to be linked with the mainlib shared library.
I'm trying to make a project with the following structure:
mainLib
|-------> CMakeLists.txt
|-------> include
| |----> mainlib.h
|-------> src
| |----> mainlib.cpp
|
|-------> interface
| |----> CMakeLists.txt
| |----> include
| |----> interface.hpp
| |----> src
| |----> interface.cpp
| |----> lib1
| |----> CMakeLists.txt
| |----> include
| |----> lib1.hpp
| |----> src
| |----> lib1.cpp
| |----> lib2
| |----> CMakeLists.txt
| |----> include
| |----> lib2.hpp
| |----> src
| |----> lib2.cpp
Here's a version of the code I'm using in my cmakelists:
mainLib
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/interface ${CMAKE_CURRENT_BINARY_DIR}/interface)
set(EXPORTABLE_HEADERS include/mainlib.hpp)
set(SOURCES src/mainlib.cpp)
set(HEADERS ${EXPORTABLE_HEADERS})
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS} $<TARGET_OBJECTS:lib1>)
target_include_directories(${PROJECT_NAME}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
INTERFACE $<INSTALL_INTERFACE:include>)
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${EXPORTABLE_HEADERS}")
install(TARGETS ${PROJECT_NAME} EXPORT ${PRODUCT_TARGET}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include/${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} lib1)
install(DIRECTORY interface/include/
DESTINATION "include/${PROJECT_NAME}/interface")
install(DIRECTORY interface/lib1/include/
DESTINATION "include/${PROJECT_NAME}/interface/lib1")
interface
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib1 ${CMAKE_CURRENT_BINARY_DIR}/lib1)
add_library(${PROJECT_NAME} INTERFACE)
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
install(TARGETS ${PROJECT_NAME} EXPORT ${PRODUCT_TARGET})
lib1
set(EXPORTABLE_HEADERS include/lib1.hpp)
set(SOURCES src/lib1.cpp)
set(HEADERS ${EXPORTABLE_HEADERS})
add_library(${PROJECT_NAME} OBJECT ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE $<TARGET_PROPERTY:interface,INTERFACE_INCLUDE_DIRECTORIES>)
install(TARGETS ${PROJECT_NAME} EXPORT ${PRODUCT_TARGET})
target_link_libraries(${PROJECT_NAME} INTERFACE interface)
So, I need to install all the headers, at the ${PRODUCT_TARGET} defined. But I need to do it following the same estructure of the project. Right now, all the hpp are installed in the same folder (${PRODUCT_TARGET}).
The interface is not linked with my lib1 because it needs a target 'interface' that is not in the export set, and I don't know how to solve it because I'm not able to set the install properties in the interface due to lot's of errors.
Once lib1 includes the interface. I want to link it with the mainlib. I'm just doing a target_link_libraries with it, but I'm not sure this is the correct way of linking shared with static libraries.
EDIT: I can generate de shared library with this code, but when I try using it, and I include the lib.hpp, it can't find the headers of the interface. I don't really know where the problem is...
All advices are appreciated.