我有一个名为main
的项目,其中包括两个库lib_A
和lib_B
。 lib_B取决于lib_A
,而main
检查一个或两个库是否可用。如果仅lib_A
可用,则仅取决于lib_A
,如果lib_B
可用,则还取决于lib_B
。我想为库生成一个文件夹(lib /),为二进制生成一个文件夹(bin /),这两个文件夹都位于主项目文件夹中。
因此,我编写了以下CMakeList.txt
文件:
lib_A
:
# Set the name of the project and target:
CMAKE_MINIMUM_REQUIRED(VERSION 3.10.0)
set(TARGET "lib_A")
project(${TARGET} VERSION 1.0.0 DESCRIPTION "Library A")
include(GNUInstallDirs)
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -flto -fopenmp -O0 -g3 -march=native -std=gnu++14")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -flto -fopenmp -O0 -g3 -march=native -std=gnu++14")
add_library(${TARGET} SHARED
${PROJECT_SOURCE_DIR}/source/lib_A.cpp
)
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
PUBLIC_HEADER ${PROJECT_SOURCE_DIR}/include/lib_A.h)
target_include_directories(${TARGET} PRIVATE ${PROJECT_SOURCE_DIR}/include)
install(TARGETS ${TARGET}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
lib_B
:
# Set the name of the project and target:
CMAKE_MINIMUM_REQUIRED(VERSION 3.10.0)
set(TARGET "lib_B")
include(GNUInstallDirs)
project(${TARGET} VERSION 1.0.0 DESCRIPTION "Library B")
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -flto -fopenmp -O0 -g3 -march=native -std=gnu++14")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -flto -fopenmp -O0 -g3 -march=native -std=gnu++14")
set(LIB_A_SUBDIRECTORY "~/Documents/Projects/CMake_Dependency_Test/lib_A")
if(IS_DIRECTORY ${LIB_A_SUBDIRECTORY})
add_subdirectory(${LIB_A_SUBDIRECTORY} ${LIBRARY_OUTPUT_PATH})
set(LIB_A_INCLUDE_DIRS "${LIB_A_SUBDIRECTORY}/include")
find_library(LIB_A_LIBRARIES lib_A HINTS ${LIBRARY_OUTPUT_PATH})
set(LIB_A_FOUND true)
add_compile_definitions(USE_LIB_A)
endif()
add_library(${TARGET} SHARED
${PROJECT_SOURCE_DIR}/source/lib_B.cpp
)
target_compile_options(${TARGET} PRIVATE -fPIC -flto -fopenmp -O3 -g3 -march=native -std=gnu++14)
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
PUBLIC_HEADER ${PROJECT_SOURCE_DIR}/include/lib_B.h)
target_include_directories(${TARGET} PRIVATE ${PROJECT_SOURCE_DIR}/include
${LIB_A_INCLUDE_DIRS})
if(LIB_A_FOUND)
target_link_libraries(${TARGET}
${LIB_A_LIBRARIES})
endif(LIB_A_FOUND)
install(TARGETS ${TARGET}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
和main
:
# Set the name of the project and target:
CMAKE_MINIMUM_REQUIRED(VERSION 3.10.0)
set(TARGET "main")
include(GNUInstallDirs)
project(${TARGET})
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -flto -fopenmp -O0 -g3 -march=native -std=gnu++14")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -flto -fopenmp -O0 -g3 -march=native -std=gnu++14")
set(LIB_A_SUBDIRECTORY "~/Documents/Projects/CMake_Dependency_Test/lib_A")
if(IS_DIRECTORY ${LIB_A_SUBDIRECTORY})
add_subdirectory(${LIB_A_SUBDIRECTORY} ${LIBRARY_OUTPUT_PATH})
set(LIB_A_INCLUDE_DIRS "${LIB_A_SUBDIRECTORY}/include")
find_library(LIB_A_LIBRARIES lib_A HINTS ${LIBRARY_OUTPUT_PATH})
set(LIB_A_FOUND true)
add_compile_definitions(USE_LIB_A)
endif()
set(LIB_B_SUBDIRECTORY "~/Documents/Projects/CMake_Dependency_Test/lib_B")
if(IS_DIRECTORY ${LIB_B_SUBDIRECTORY} AND LIB_A_FOUND)
add_subdirectory(${LIB_B_SUBDIRECTORY} ${LIBRARY_OUTPUT_PATH})
set(LIB_B_INCLUDE_DIRS "${LIB_B_SUBDIRECTORY}/include")
find_library(LIB_B_LIBRARIES lib_B HINTS ${LIBRARY_OUTPUT_PATH})
set(LIB_B_FOUND true)
add_compile_definitions(USE_LIB_B)
endif()
add_executable(${TARGET}
${CMAKE_SOURCE_DIR}/source/main.cpp
)
target_include_directories(${TARGET} PRIVATE ${CMAKE_SOURCE_DIR}/include
${LIB_A_INCLUDE_DIRS}
${LIB_B_INCLUDE_DIRS})
set(LIBRARIES_TO_LINK "")
if(LIB_A_FOUND)
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK}
${LIB_A_LIBRARIES})
endif(LIB_A_FOUND)
if(LIB_B_FOUND)
set(LIBRARIES_TO_LINK ${LIBRARIES_TO_LINK}
${LIB_B_LIBRARIES}
)
endif(LIB_B_FOUND)
target_link_libraries(${TARGET} ${LIBRARIES_TO_LINK})
在编译库B时,库A会被同时编译,然后移入库B的库文件夹(即lib_B / lib)。与main
一起编译所有内容时,在注释掉与库B相关的所有内容时都可以使用。如果包含了库B(并且库A的第一行带有add_subdirectory()
,则排除了错误)>
CMake Error at ~/Documents/Projects/CMake_Dependency_Test/lib_B/CMakeLists.txt:18 (add_subdirectory):
The binary directory
~/Documents/Projects/CMake_Dependency_Test/main/lib
is already used to build a source directory. It cannot be used to build
source directory
~/Documents/Projects/CMake_Dependency_Test/lib_A
Specify a unique binary directory name.
-- Configuring incomplete, errors occurred!
为什么会这样,我该如何规避/解决该问题?
以及如何设置编译顺序?仅从干净文件夹中的库A进行编译时,CMake尝试先编译main
,然后再编译lib_A
,但是即使我列出了{{ 1}}在lib_A
之前。