David Ekermann
David Ekermann

Reputation: 87

RPath not working with Make Install generated from CMake

I got a smal example project where I'm trying to link a dynamic library in to an executeable.

File structure as follows:

-project

cmake_minimum_required (VERSION 3.3.2)

# Project
# --------------
project (cmakefun)

# Subdirectories
# --------------
add_subdirectory(dlibs)
add_subdirectory(exes)

# Target
# --------------
set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/cmakefun")

--dlibs

----engine.h

#pragma once
#include <iostream>

class Engine {
public:
    Engine();
    void Function();
};

----engine.cpp

#include "engine.h"

using namespace std;
Engine::Engine(){}
void Engine::Function() {
    cout << "Function" << endl;
}

----CMakeLists.txt

# Project
# --------------
project(engine)

# Headers and Sources
# --------------
set(${PROJECT_NAME}_headers engine.h)
set(${PROJECT_NAME}_sources engine.cpp)

# Create Binaries
# --------------
add_library (${PROJECT_NAME} SHARED ${${PROJECT_NAME}_headers} ${${PROJECT_NAME}_sources})

# Target
# --------------
install(TARGETS ${PROJECT_NAME}
            RUNTIME DESTINATION bin
            LIBRARY DESTINATION lib
            ARCHIVE DESTINATION lib/static)

--exe

----main.h

#pragma once
#include <iostream>

----main.cpp

#include "main.h"
#include "../dlibs/engine.h"

int main( int argc, char* args[] ) {
    Engine a;
    a.Function();
    return 0;
}

----CMakeLists.txt

# Project
# --------------
project(exe)


set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)


# Headers and Sources
# --------------
set(${PROJECT_NAME}_headers "")
set(${PROJECT_NAME}_sources main.cpp)

# Create Binaries
# --------------
add_executable (${PROJECT_NAME} ${${PROJECT_NAME}_headers} ${${PROJECT_NAME}_sources})

# Linker
# --------------
target_link_libraries(${PROJECT_NAME} engine)

# Target
# --------------
install(TARGETS ${PROJECT_NAME}
            RUNTIME DESTINATION bin
            LIBRARY DESTINATION lib
            ARCHIVE DESTINATION lib/static)

This is what I do to run it:

mkdir build
cd build
cmake ..
make install
../cmakefun/bin/exe

The Error I get:

dyld: Library not loaded: @rpath/libengine.dylib
Referenced from: *absolute path*/cmakefun/bin/exe
Reason: image not found
Trace/BPT trap: 5

The generated file inside of the build folder however works. As far as I know I need to set the relative RPath if I'm using 'make install' and I've tried this:

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

Inside of the CMakteLists.txt (exe folder), but with the same results.

I've tried several other ways of setting the RPath, but to no avail.

Any help is greatly appreciated.

Best Regards

Upvotes: 2

Views: 2489

Answers (1)

Tsathoggua
Tsathoggua

Reputation: 819

I just had the same problem and in the end I could solve my problem using this topic CMAKE RPATH with packaging and the wiki https://cmake.org/Wiki/CMake_RPATH_handling .

In the executable CMakeLists.txt, you need

# Project
projet(exe)

# set all you waft to set...
# get your sources...

# set RPATH according to the wiki
# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH  FALSE)

# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 

SET(CMAKE_INSTALL_RPATH "${my_install_path}")

# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# Create binaries
add_executable(my_exe ${my_sources})
# add your libraries...

# Install target
install(TARGET my_exe ${my_options})

Upvotes: 0

Related Questions