c++cmakedynamicsfmlrpath

How to force my built binary to use .so files in that binaries folder, when compiling using CMake?


I am working on a simple snake clone using SFML, and I am porting it from VS on Win10, to CMake on Linux. I have manged to compile my program using CMake, and the program runs okay. However, my program uses .so files that are already installed on the computer (for example in usr/ib). I want my program to behave like in Win10, where it looks for .so files in the programs directory.

I want to do this, as I am using an old version of SFML for my project, and I want to avoid conflicts with other versions already installed.

Below is my CMakeLists.txt file:

cmake_minimum_required(VERSION 3.28)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED YES)

project(sfmlsnake)

add_executable(${PROJECT_NAME}
    sources/<file.cpp>
    )

target_link_libraries(${PROJECT_NAME} sfml-graphics sfml-window sfml-system)
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/SFML/lib)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/SFML/include)

add_subdirectory(tinyfiledialogs)
target_link_libraries(${PROJECT_NAME} tinyfiledialogs)

After checking the built binary rpath with: objdump -x snake |grep 'R.*PATH', I get this message in the console:

/home/name/Desktop/sfmlsnake/snake/SFML/lib

This is where my SFML .so files are located, the ones that I got when I was downloading SFML from their website.

This is my file structure:

snake
-build
--<this is where the built program appears, i run cmake and make from here>
-tinyfiledialogs
-SFML
--lib
---<SFML .so, .a Files, this is where the built programs rpath points to>
--include
-source
--<source.cpp files>
-CMakeLists.txt

I used numerous solutions from the internet which claimed to do what I wanted my program to do, however, all of them resulted with the program still linking to the .so files in the SFML/lib directory.

When I put: set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'") inside my CMakeLists.txt file, right below the other set commands.

The command: objdump -x sfmlsnake |grep 'R.*PATH'.

Returned this: RUNPATH $ORIGIN:/home/hubert/Desktop/Pendrive/sfmlsnake/snake/SFML/lib.

This was the case with all other solutions I have found.

PS: My project is open-source on Github, if for some reason you need to look at how it is made. Make sure to look at the cmake-port branch, though.

https://github.com/xtrel/sfmlsnake/tree/cmake-port


Solution

  • If you want to package your game for redistribution you will want to use CPack/CInstall mechanism. This mechanism allows you to just specify the RPATH:

    set_property(TARGET ${PROJECT_NAME} PROPERTY INSTALL_RPATH $ORIGIN)
    

    You can do the same for your build tree by setting BUILD_RPATH, but the default is usually what you want.

    You could also consider setting BUILD_WITH_INSTALL_RPATH so it always uses the INSTALL_RPATH. Your choice!