On a project of mine using c++ and cmake, I include several third party libraries, including SDL2. As many before me, I'm struggling to get the application to find the libraries correctly to run. So, as usual, if the libraries are installed in the system, SDL2 is found with find_package, and everything proceeds as normal.
( EDIT )This is 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 **********")
(EDIT) This is the full 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()
This works of for building. The first time I run cmake, it builds all the dependencies, but not the main project. The second time I run it, it correctly finds the libraries, and builds the main project. If I look into the output folder and inside lib, all the third party libraries are correctly copied inside there. All is well on that part. The main problem comes with linking. When I try to run the test application, I get this...
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
Of course, this works if I specify DYLD_LIBRARY_PATH pointing to THIRD_PARTY_OUTPUT_PATH/lib, but that prevents me from running this on the IDE, and will also not work under Windows... I intend to make this build process work under Linux, OSX, Windows, Android and IOS, so I have that restriction to think ahead of. So, since in Windows I need to have the DLL's and libs all together, I might as well copy everything into the same directory. As a small test, I copied the test executable into the libs folder, where everything is put. This is what I get:
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
And this is the part I honestly do not understand. Why is it looking for libassimp in the wrong folder? (EDIT) The correct path where the file was copied from is /Users/joao.pincho/Programming/Illusion_deps/ThirdParty/Darwin/lib/libassimp.3.dylib
What can I do to just make this work? Why is it looking for the libs in the wrong place? Why did it stop complaining about libSDL2 when I moved the executable, but not about libassimp?