将两个库链接到主程序时,CMake错误(已使用二进制目录)

时间:2019-05-20 15:22:42

标签: c++ cmake

我有一个名为main的项目,其中包括两个库lib_Alib_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之前。

0 个答案:

没有答案