简体   繁体   中英

CMake/CMakeLists.txt: how to list files explicitly (to avoid the use of GLOB)

I am a newbie with CMake. Today, I use in my Android/Java/JNI/CMake project, the following code in my CMakeLists.txt file:

include_directories(lib1)
file(GLOB_RECURSE LIB1_SOURCES
"bund.cc"
"bund.h"
"bund_io.cc"
"bund_io.h"
"cam.cc"
"cam.h"
"defines.h"
)

include_directories(lib2)
file(GLOB_RECURSE LIB2_SOURCES
"allocator.h"
"memory.h"
"arguments.cc"
"arguments.h"
"defines.h"
)

add_library(native-lib SHARED ${LIB1_SOURCES} ${LIB2_SOURCES} native-lib.cpp)
find_library(log-lib log)
target_link_libraries(native-lib ${log-lib})

As CMake documentation 'do not recommend using GLOB to collect a list of source files from your source tree', I wonder what is the recommended way to replace this code in my CMakeLists.txt. Note that I have a 'defines.h' in both lib1 and lib2 directory, maybe some specific precautions have to be taken.

My project structure is :

-cpp (with mib-native.cpp and CMakeLists.txt inside)
--lib1 (with .h and .cc files mixed inside)
--lib2 (with .h and .cc files mixed inside)

I would be grateful if you could provide the detailed code I have to put in my Android project.

Assuming you have some dependencies that are shared between libraries, why not create a separate dependency and use it in the two other targets?

Also, explicit source specification is probably the best practice out there. In big projects, globs are discouraged and rather smaller targets are created and then added to bigger ones. In your case I would create two libraries (as you do) but explicitly list sources.

I would do it like this: (first try to split code into directories for the libraries, best create a folder for shared headers)

# put all finds in one place
find_library(LOG_LIB log)

add_libary(LIB_1 STATIC
           ${CMAKE_CURRENT_LIST_DIR}/"bund.cc"
           ${CMAKE_CURRENT_LIST_DIR}/"bund_io.cc"
           ${CMAKE_CURRENT_LIST_DIR}/"cam.cc")

target_include_directories(LIB_1 
                           ${CMAKE_CURRENT_SOURCE_DIR}/lib1_includes
                           ${CMAKE_CURRENT_SOURCE_DIR}/common_includes)

add_libary(LIB_2 STATIC
           ${CMAKE_CURRENT_LIST_DIR}/"arguments.cc")

target_include_directories(LIB_2 
                           ${CMAKE_CURRENT_SOURCE_DIR}/lib2_includes
                           ${CMAKE_CURRENT_SOURCE_DIR}/common_includes)

add_library(NATIVE_LIB SHARED
            ${CMAKE_CURRENT_LIST_DIR}/native-lib.cpp)

target_link_libraries(NATIVE_LIB
                      PRIVATE 
                      ${LIB_1} ${LIB_2} ${LOG_LIB}) # I also prefer to use upper case for targets, otherwise you can have nasty to spot linking errors 

Another idea is to create the separate directory trees for the libraries and create CMakeFiles.txt for them and just use them as targets. Look at how it is done in here and the accompanying blog post .

You will also learn meaning of the PRIVATE keyword name there (in short it does not expose the symbols from linked to libraries outside the library you created.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM