cmake动态库子项目

时间:2016-11-08 17:05:34

标签: c++ cmake

在我使用c ++和cmake的项目中,我包含了几个第三方库,包括SDL2。 在我之前,我很难让应用程序正确地找到正确运行的库。 因此,像往常一样,如果在系统中安装了库,则会找到带有find_package的SDL2,并且一切都正常进行。

(编辑)这是ThirdParty.cmake:

cmake_minimum_required(VERSION 2.8)
include ( "ExternalProject" )

message ( STATUS "********** Starting third party dependency checks **********")
set ( THIRD_PARTY_OUTPUT_PATH "${CMAKE_CURRENT_LIST_DIR}/${CMAKE_SYSTEM_NAME}" )

list ( APPEND CMAKE_PREFIX_PATH ${THIRD_PARTY_OUTPUT_PATH} )
set ( THIRD_PARTY_DEPENDENCIES_OK TRUE )

# GLM
find_package ( GLM QUIET )
if ( NOT GLM_FOUND )
    ExternalProject_Add ( ThirdParty_GLM
        #GIT_REPOSITORY "https://github.com/g-truc/glm"
        URL "https://github.com/g-truc/glm/archive/0.9.7.6.zip"
        INSTALL_DIR ${THIRD_PARTY_OUTPUT_PATH}
        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
        )

    set ( THIRD_PARTY_DEPENDENCIES_OK FALSE )
    #add_subdirectory ( ThirdParty/glm )
    #set ( GLM_INCLUDE_DIR "ThirdParty/glm" )
endif()

# SDL2
find_package ( SDL2 QUIET )
if ( NOT SDL2_FOUND )
    ExternalProject_Add ( ThirdParty_SDL2
        URL "https://www.libsdl.org/release/SDL2-2.0.5.zip"
        INSTALL_DIR ${THIRD_PARTY_OUTPUT_PATH}
        CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
        )
    set ( THIRD_PARTY_DEPENDENCIES_OK FALSE )

#    set ( SDL_SHARED_ENABLED_BY_DEFAULT FALSE )
#    add_subdirectory ( ThirdParty/SDL2 )
#    set ( SDL2_INCLUDE_DIR "ThirdParty/SDL2/include" )
#    set ( SDL2_LIBRARY sdl2-static )
endif()

# FreeImage
find_package ( FreeImage QUIET )
if ( NOT FREEIMAGE_FOUND )
    ExternalProject_Add ( ThirdParty_FreeImage
        GIT_REPOSITORY "gitrepo:Misc/FreeImage"
        INSTALL_DIR ${THIRD_PARTY_OUTPUT_PATH}
        CMAKE_ARGS -DSDL_SHARED_ENABLED_BY_DEFAULT=FALSE -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
        )
    set ( THIRD_PARTY_DEPENDENCIES_OK FALSE )
#    add_subdirectory ( ThirdParty/FreeImage )
#    set ( FREEIMAGE_INCLUDE_DIR "ThirdParty/FreeImage/src" )
#    set ( FREEIMAGE_LIBRARY freeimage )
endif()

# Assimp
find_package ( Assimp QUIET )
if ( NOT ASSIMP_FOUND )
    ExternalProject_Add ( ThirdParty_Assimp
        GIT_REPOSITORY "https://github.com/assimp/assimp"
        GIT_TAG "v3.2"
        INSTALL_DIR ${THIRD_PARTY_OUTPUT_PATH}
        CMAKE_ARGS -DCMAKE_C_FLAGS=-fPIC -DCMAKE_CXX_FLAGS=-fPIC -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> "-DASSIMP_BUILD_TESTS=OFF"
        )
    set ( THIRD_PARTY_DEPENDENCIES_OK FALSE )
#    set ( ASSIMP_BUILD_ASSIMP_TOOLS FALSE)
#    set ( ASSIMP_BUILD_TESTS FALSE )
#    set ( BUILD_SHARED_LIBS FALSE )
#    add_subdirectory ( ThirdParty/Assimp )
#    set ( ASSIMP_INCLUDE_DIR "ThirdParty/assimp/include" )
#    set ( ASSIMP_LIBRARIES "assimp" )
endif()

if ( THIRD_PARTY_DEPENDENCIES_OK )
    list ( APPEND ILLUSION_INCLUDE_DIRS ${SDL2_INCLUDE_DIR} )
    list ( APPEND ILLUSION_INCLUDE_DIRS ${GLM_INCLUDE_DIR} )
    list ( APPEND ILLUSION_INCLUDE_DIRS ${FREEIMAGE_INCLUDE_DIR} )
    list ( APPEND ILLUSION_INCLUDE_DIRS ${ASSIMP_INCLUDE_DIR} )

    list ( APPEND ILLUSION_LIBRARIES ${SDL2_LIBRARIES} )
    list ( APPEND ILLUSION_LIBRARIES ${FREEIMAGE_LIBRARY} )
    list ( APPEND ILLUSION_LIBRARIES ${ASSIMP_LIBRARIES} )

    list ( APPEND ILLUSION_LINK_DIRS ${THIRD_PARTY_OUTPUT_PATH}/lib )
    list ( APPEND ILLUSION_INCLUDE_DIRS ${THIRD_PARTY_OUTPUT_PATH}/include )
else()
    message ( STATUS "Dependencies not ready. Building")
endif()

message ( STATUS "********** Finished third party dependency checks **********")

(编辑)这是完整的CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project ( Illusion )

########## Platform and target configuration ##########
string ( TOUPPER ${CMAKE_SYSTEM_NAME} UPPERCASE_SYSTEM_NAME )
message ( STATUS "Host building system - ${CMAKE_SYSTEM}" )
set ( ILLUSION_TARGET_PLATFORM ${UPPERCASE_SYSTEM_NAME} )
list ( APPEND ILLUSION_DEFINITIONS -DILLUSION_TARGET_PLATFORM_${UPPERCASE_SYSTEM_NAME} )
message ( STATUS "Target system - ${ILLUSION_TARGET_PLATFORM}" )

set ( ILLUSION_VERSION_MAJOR 0 )
set ( ILLUSION_VERSION_MINOR 4 )
set ( ILLUSION_ROOT ${PROJECT_SOURCE_DIR})
set ( ILLUSION_BUILTIN_DATA_PATH \"/usr/local/share/Illusion/\" )
list ( APPEND ILLUSION_INCLUDE_DIRS "${ILLUSION_ROOT}" )
set ( CMAKE_MODULE_PATH "${ILLUSION_ROOT}/ThirdParty/CMakeHelpers" ${CMAKE_MODULE_PATH})
set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${ILLUSION_TARGET_PLATFORM}/lib )
set ( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${ILLUSION_TARGET_PLATFORM}/lib )
set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${ILLUSION_TARGET_PLATFORM}/bin )
set ( CMAKE_INSTALL_RPATH ${THIRD_PARTY_OUTPUT_PATH}/lib )
set ( CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE )

########## Third party libraries ##########
include ( "ThirdParty/ThirdParty.cmake" )

add_definitions ( ${ILLUSION_DEFINITIONS} )
include_directories ( ${ILLUSION_INCLUDE_DIRS} )
if ( THIRD_PARTY_DEPENDENCIES_OK )
    message ( STATUS "All dependencies present. Building Illusion")
    ########## Compiler configuration ##########
    if ( "${CMAKE_BUILD_TYPE}" STREQUAL "" )
        set ( CMAKE_BUILD_TYPE Debug )
        message ( STATUS "Setting build type to debug as default" )
    endif()

    include ( "ThirdParty/CMakeHelpers/Macros.cmake" )
    enable_all_warnings()
    use_cpp11()

    ########## Choose graphics backend ##########
    include ( "Graphics/Graphics.cmake" )

    ########## Main library ##########
    configure_file (
      "${PROJECT_SOURCE_DIR}/IllusionConfig.h.in"
      "${PROJECT_SOURCE_DIR}/IllusionConfig.h"
      )

    file ( GLOB Illusion_Sources "*.cpp" "*.h" "Graphics/*.cpp" "Graphics/*.h" "Material/*.cpp" "Material/*.h" "Camera/*.cpp" "Camera/*.h" "Model/*.cpp" "Model/*.h" "Asset/*.cpp" "Asset/*.h " "FileSystem/*.cpp" "FileSystem/*.h" )
    file ( GLOB_RECURSE Pipeline_Sources "Pipelines/*" )
    file ( GLOB_RECURSE DataFiles "Data/*" FindIllusion.cmake TODO.txt )
    add_library ( WindowSystem "WindowSystem/WindowSystem.cpp" "WindowSystem/WindowSystem.h" )
    add_library ( Illusion
        ${Illusion_Sources}
        ${DataFiles}
        ${Pipeline_Sources}
        )

    ########## Submodules ##########
    add_subdirectory ( StringFunctions )
    add_subdirectory ( ValueFileParser )

    list ( APPEND ILLUSION_LIBRARIES ${GraphicsBackendLibraries} WindowSystem ${SDL2_LIBRARIES} ValueFileParser StringFunctions )

    # add a target to generate API documentation with Doxygen
    find_package ( Doxygen )
    if ( DOXYGEN_FOUND )
        configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY )
        add_custom_target ( doc
            ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
            COMMENT "Generating API documentation with Doxygen" VERBATIM
            )
    endif ()

    target_link_libraries ( Illusion ${ILLUSION_LIBRARIES} )

    # Just to check if i have a parent
    get_directory_property ( hasParent PARENT_DIRECTORY )
    if ( hasParent )
        message ( STATUS "Passing Illusion variables to parent project" )
        set ( ILLUSION_INCLUDE_DIRS ${ILLUSION_INCLUDE_DIRS} PARENT_SCOPE )
        set ( ILLUSION_LIBRARIES Illusion ${ILLUSION_LIBRARIES} PARENT_SCOPE )
        set ( ILLUSION_LINK_DIRS ${ILLUSION_LINK_DIRS} PARENT_SCOPE )
        set ( ILLUSION_DEFINITIONS ${ILLUSION_DEFINITIONS} PARENT_SCOPE )
    endif()

    option ( ILLUSION_BUILD_TESTS "Builds tests" TRUE )
    if ( ILLUSION_BUILD_TESTS )
        message ( STATUS "Building tests" )
        file ( GLOB Test_Sources "Tests/*.cpp" "Tests/*.h" )
        add_executable ( Test ${Test_Sources} )
        target_link_libraries ( Test Illusion )

        add_executable ( WindowSystemTest WindowSystem/WindowSystemTest.cpp )
        target_link_libraries ( WindowSystemTest WindowSystem ${SDL2_LIBRARY} )

        add_custom_command ( TARGET Test POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_directory "${THIRD_PARTY_OUTPUT_PATH}/lib" ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} )
    endif()
#    include ( "Package.cmake" )
endif()

这是建筑的工作。我第一次运行cmake时,它会构建所有依赖项,但不会构建主项目。第二次运行它,它正确地找到了库,并构建了主项目。如果我查看输出文件夹和lib内部,所有第三方库都在那里被正确复制。一切都很顺利。主要问题是链接。当我尝试运行测试应用程序时,我得到了这个......

dyld: Library not loaded: libSDL2-2.0.1.dylib
  Referenced from: /Users/joao.pincho/Programming/build-Illusion_deps-Desktop_Qt_5_7_0_clang_64bit-Default/DARWIN/bin/./Test
  Reason: image not found
Trace/BPT trap: 5

当然,如果我指定指向THIRD_PARTY_OUTPUT_PATH / lib的DYLD_LIBRARY_PATH,这会起作用,但这会阻止我在IDE上运行它,并且在Windows下也无法运行... 我打算让这个构建过程在Linux,OSX,Windows,Android和IOS下运行,所以我有限制提前考虑。 所以,因为在Windows中我需要将DLL和lib放在一起,我不妨将所有内容复制到同一目录中。 作为一个小测试,我将测试可执行文件复制到libs文件夹中,其中包含所有内容。 这就是我得到的:

dyld: Library not loaded: /Users/joao.pincho/Programming/Illusion_deps/ThirdParty/Darwin//libassimp.3.dylib
  Referenced from: /Users/joao.pincho/Programming/build-Illusion_deps-Desktop_Qt_5_7_0_clang_64bit-Default/DARWIN/lib/./Test
  Reason: image not found
Trace/BPT trap: 5

这是我老实说不明白的部分。为什么在错误的文件夹中查找libassimp? (编辑)从中复制文件的正确路径是/Users/joao.pincho/Programming/Illusion_deps/ThirdParty/Darwin/ lib /libassimp.3.dylib

我能做些什么才能让这项工作成功?为什么在错误的地方寻找libs?当我移动可执行文件时,为什么它不再抱怨libSDL2,而不是关于libassimp?

0 个答案:

没有答案