1

I use CMake to build a project that consists of multiple nested static libraries .A similar but simple structure is shown in the figure below:

TestProject:
|-CMakeLists.txt
|-Main.cpp
|-level2
|    | - level2.cpp
|    | - level2.h
|    | - CMakeLists.txt
|    | - level1
|    |     |-level1.cpp
|    |     |-level1.h
|    |     |-CMakeLists.txt
|    |     |-third_party.lib-------(When I build level1.lib, I need to add dependence of this library.)

I use CMake to build static libraries for each level separately.I want to combine it with the library referenced by the previous layer when the static library of each layer is generated. For example, I build the static lib of level1 first, which depend on the existed third_party.lib.Then, in the CMakeLists.txt of level 2, I create the static library of level 2 depend on the static library of level 1 ( target_link_libraries(${PROJECT_NAME} LEVEL1) ), and then, I wanted to merge the libraries of level 2 and level 1 and third_party.lib together to a new static lib file named as level1_2.lib.

According to another similar question but different at the third_partyl.lib(CMake linking static libraries in different subdirectories into one single static library), I used object library, and get the merged static library.Here's my code:

#CMakeLists.txt in level1

cmake_minimum_required(VERSION 3.20.3)

#projcet name
project(LEVEL1 LANGUAGES CXX)


# Generate lib
add_library( LEVEL1obj OBJECT add.cpp)


# Add the include directories of user-written sources.
target_include_directories(LEVEL1obj PUBLIC ${PROJECT_SOURCE_DIR})

add_library(${PROJECT_NAME})

add_dependencies(${PROJECT_NAME} LEVEL1obj)

target_link_libraries(${PROJECT_NAME} PUBLIC LEVEL1obj)

And this is the CMakelists.txt of level2.

#CMakeLists.txt in level2
cmake_minimum_required(VERSION 3.20.3)

#projcet name
project(LEVEL2 LANGUAGES CXX)


add_subdirectory(level1)

add_library( LEVEL2obj OBJECT addplus.cpp addplus.h)

# Add the include directories of user-written sources.
target_include_directories(LEVEL2obj PUBLIC ${PROJECT_SOURCE_DIR})

target_link_libraries(LEVEL2obj PUBLIC LEVEL1obj)


add_library( ${PROJECT_NAME})

add_dependencies(${PROJECT_NAME} LEVEL1obj LEVEL2obj)

target_link_libraries(${PROJECT_NAME} PUBLIC LEVEL1obj LEVEL2obj)

This is the top level CMakeLists.txt in test project

cmake_minimum_required(VERSION 3.20.3)

project(TestCppLib)

file(GLOB SRC "${PROJECT_SOURCE_DIR}/*.cpp")

add_subdirectory(level2)

add_executable(${PROJECT_NAME} ${SRC})

target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR})

add_dependencies(${PROJECT_NAME} LEVEL2)

target_link_libraries(${PROJECT_NAME} PRIVATE LEVEL2)

Now, I completed the compilation of level1-level2 projects with help. However, one problem is overlooked:I don't know how to deal with third-party libraries in level1.I don't know how to use the Object Library method to merge the third-party library with level1.lib.. I cannot use the method of building the object library first and then merging them. Because as far as I know, CMake may not have a method to convert a static library into an OBJECT library.

So, when I merge libraries, how should I deal with this third-party library problem?

Any help would be appreciated.

YuhaoQiu
  • 63
  • 5
  • If you have actual files `.lib` and want to combine them into the single `.lib` fle, then you need actually **merge** them using non-CMake tool. In your previous question you use tool `lib.exe`. So, what is a problem to use this tool in the given case? – Tsyvarev Aug 21 '21 at 16:21
  • Linking to object libraries is impossible prior to 3.12, you _must_ fix your `cmake_minimum_required(VERSION ...)` to be at _least_ that version, but whatever you choose you _must **test** it_. I will be happy to help if you fix that and the other issues I mentioned on your previous question (lack of `CONFIGURE_DEPENDS` and missing visibility specifier in `target_link_libraries`). – Alex Reinking Aug 21 '21 at 16:23
  • @Tsyvarev Thanks for your reply. As I mentioned in the previous question, after calling lib.exe with the add_custom_command command, there is no corresponding level1-2.lib file generated. Among the dependencies of the main project, the level1-2.lib dependency does not exist either. Can you tell me how to use lib.exe correctly in CMake – YuhaoQiu Aug 22 '21 at 06:06
  • @AlexReinking I apologize for my negligence. Now I use ‘cmake --version’ to check my CMake version, and its version is **3.20.3**. I changed the parameters in ‘cmake_minimum_required’. At the same time, I added ‘add_dependencies’ wherever library dependencies are needed, and declared it as ‘PUBLIC’. So far, although it works,it still does not merge the external static libraries in. – YuhaoQiu Aug 22 '21 at 06:35
  • "after calling lib.exe with the add_custom_command command, there is no corresponding level1-2.lib file generated." - According to [that answer](https://stackoverflow.com/a/13492577/3440745), `lib.exe` should create the file requested in `/OUT` parameter. Are you sure that `lib.exe` is **actually** called with your `add_custom_command`? Have you tried to run `lib.exe` from a terminal (without CMake), passing it the same parameters as in your CMakeLists.txt`? – Tsyvarev Aug 22 '21 at 08:57
  • @Tsyvarev I tried run the lib.exe in windows cmd.It works well, generating the merged lib as I expected. But in CMake, it just can't work. I don't know if the command was actually executed. I want to use the **COMMENT** command to observe whether it is executed, but neither VS nor CMake gives the expected output.Here is my code: `add_custom_command( OUTPUT ${LIBNAME} COMMAND ${MSVC_LIB_TOOL} /OUT:${LIBNAME} $ $ DEPENDS LEVEL1 LEVEL2 COMMENT "merging libs" )`.Can you give me some advice? – YuhaoQiu Aug 22 '21 at 10:18
  • Have you checked [that question](https://stackoverflow.com/questions/2937128/cmake-add-custom-command-not-being-run) about non-working custom command? – Tsyvarev Aug 22 '21 at 10:21

0 Answers0