[CMake] RPATH for pkg-config

Don Hinton hintonda at gmail.com
Thu Jan 4 15:49:05 EST 2018


This is mostly an ordering problem -- you need to setup everything before
calling add_executable.  Also, I was wrong about using ';' in RPATH
variables.  They should use ':' as in your original since they are used
verbatim.

Here's an example that works:

$ cat ../CMakeLists.txt
cmake_minimum_required(VERSION 3.7)
project(main)

enable_language(CXX)
find_package(MPI REQUIRED)

find_package(PkgConfig REQUIRED)
pkg_check_modules(PETSc REQUIRED PETSc)

# RPATH variables must be set, and link_directories called. before calling
add_executable.
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH
"${CMAKE_INSTALL_RPATH}:$ORIGIN/../lib:${PETSc_LIBRARY_DIRS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}
-Wl,--enable-new-dtags")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}
-Wl,--enable-new-dtags")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}
-Wl,--enable-new-dtags")
link_directories(${PETSc_LIBRARY_DIRS})

add_executable(main main.cpp)

target_include_directories(main PUBLIC ${MPI_CXX_INCLUDE_PATH}
${PETSc_INCLUDE_DIRS})
target_link_libraries(main PUBLIC ${MPI_CXX_LIBRARIES} ${PETSc_LIBRARIES})

install(TARGETS main RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)

$ make VERBOSE=1
/usr/local/bin/cmake -H/home/dhinton/test -B/home/dhinton/test/build
--check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/bin/cmake -E cmake_progress_start
/home/dhinton/test/build/CMakeFiles
/home/dhinton/test/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/dhinton/test/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/depend
make[2]: Entering directory '/home/dhinton/test/build'
cd /home/dhinton/test/build && /usr/local/bin/cmake -E cmake_depends "Unix
Makefiles" /home/dhinton/test /home/dhinton/test /home/dhinton/test/build
/home/dhinton/test/build
/home/dhinton/test/build/CMakeFiles/main.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/dhinton/test/build'
make -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/build
make[2]: Entering directory '/home/dhinton/test/build'
make[2]: Nothing to be done for 'CMakeFiles/main.dir/build'.
make[2]: Leaving directory '/home/dhinton/test/build'
[100%] Built target main
make[1]: Leaving directory '/home/dhinton/test/build'
/usr/local/bin/cmake -E cmake_progress_start
/home/dhinton/test/build/CMakeFiles 0

$ objdump -x main | grep PATH
  RUNPATH              :$ORIGIN/../lib:/home/dhinton/usr/lib

$ make install
[100%] Built target main
Install the project...
-- Install configuration: ""
-- Installing: /home/dhinton/petsc-test/bin/main

$ objdump -x ~/petsc-test/bin/main | grep PATH
  RUNPATH              :$ORIGIN/../lib:/home/dhinton/usr/lib

hth...
don

On Thu, Jan 4, 2018 at 9:13 AM, Franck Houssen <franck.houssen at inria.fr>
wrote:

> not working with the last cmakelist I have which is:
>
> >> more ../CMakeLists.txt
> cmake_minimum_required(VERSION 3.7)
> enable_language(CXX)
>
> find_package(MPI REQUIRED)
> find_package(PkgConfig REQUIRED) # Get pkg_check_modules.
> pkg_check_modules(PETSc REQUIRED PETSc)
>
> project(main)
> add_executable(main main.cpp)
>
> target_include_directories(main PUBLIC ${MPI_CXX_INCLUDE_PATH})
> target_link_libraries(main PUBLIC ${MPI_CXX_LIBRARIES})
>
> target_include_directories(main PUBLIC ${PETSc_INCLUDE_DIRS})
> foreach(lib ${PETSc_LDFLAGS})
>   target_link_libraries(main PUBLIC ${lib})
>   message("target_link_libraries - lib is ${lib}")
> endforeach(lib)
>
> # 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 TRUE)
> SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;$
> {CMAKE_INSTALL_RPATH}")
> # 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)
> # the RPATH to be used when installing, but only if it's not a system
> directory
> LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
> "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
> IF("${isSystemDir}" STREQUAL "-1")
>    SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;$
> {CMAKE_INSTALL_RPATH}")
> ENDIF("${isSystemDir}" STREQUAL "-1")
> foreach(dir ${PETSc_LIBRARY_DIRS})
>   link_directories(main PUBLIC ${dir})
>   message("link_directories - dir is ${dir}")
>   set(CMAKE_INSTALL_RPATH "${dir};${CMAKE_INSTALL_RPATH}")
> endforeach(dir)
> message("CMAKE_INSTALL_RPATH: ${CMAKE_INSTALL_RPATH}")
>
> include(CTest)
> enable_testing()
> add_test(NAME main COMMAND "mpirun -n 2 ./main" WORKING_DIRECTORY
> "${CMAKE_CURRENT_BINARY_DIR}")
>
> ------------------------------
>
> *De: *"Don Hinton" <hintonda at gmail.com>
> *À: *"Franck Houssen" <franck.houssen at inria.fr>
> *Cc: *"Andreas Naumann" <Andreas-Naumann at gmx.net>, "CMake Mail List" <
> cmake at cmake.org>
> *Envoyé: *Jeudi 4 Janvier 2018 17:47:19
>
> *Objet: *Re: [CMake] RPATH for pkg-config
>
> Are you still doing this at the end?  You are overwriting here, not adding.
>
> IF("${isSystemDir}" STREQUAL "-1")
>    SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
> ENDIF("${isSystemDir}" STREQUAL "-1")
>
> Also, do not use ':', use ';' instead as a separator.  Or use 'list(APPEND
> ...), to add to a list.
>
> On Thu, Jan 4, 2018 at 8:34 AM, Franck Houssen <franck.houssen at inria.fr>
> wrote:
>
>> nope !... :D
>>
>> ------------------------------
>>
>> *De: *"Don Hinton" <hintonda at gmail.com>
>> *À: *"Franck Houssen" <franck.houssen at inria.fr>
>> *Cc: *"Andreas Naumann" <Andreas-Naumann at gmx.net>, cmake at cmake.org
>> *Envoyé: *Jeudi 4 Janvier 2018 16:52:53
>> *Objet: *Re: [CMake] RPATH for pkg-config
>>
>>
>> On Thu, Jan 4, 2018 at 3:57 AM Franck Houssen <franck.houssen at inria.fr>
>> wrote:
>>
>>> ------------------------------
>>>
>>> *De: *"Don Hinton" <hintonda at gmail.com>
>>> *À: *"Franck Houssen" <franck.houssen at inria.fr>
>>> *Cc: *"Andreas Naumann" <Andreas-Naumann at gmx.net>, cmake at cmake.org
>>> *Envoyé: *Jeudi 4 Janvier 2018 10:43:28
>>>
>>>
>>> *Objet: *Re: [CMake] RPATH for pkg-config
>>>
>>> The cmake rpath settings handle build/install directories more or less
>>> automatically, but you need to add a completely different path.
>>>
>>>
>>> Yes. That's the problem: I need to add a completely different path.
>>>
>>>
>>> Try adding the additional path (pretty much every -L you added) to
>>> CMAKE_INSTALL_RPATH, and set CMAKE_BUILD_WITH_INSTALL_RPATH=TRUE.
>>>
>>>
>>> See does not work
>>>
>>> >> more ../CMakeLists.txt
>>> ...
>>>
>>> foreach(dir ${PETSc_LIBRARY_DIRS})
>>>   link_directories(main PUBLIC ${dir})
>>>   message("link_directories - dir is ${dir}")
>>>   set(CMAKE_INSTALL_RPATH "${dir}:${CMAKE_INSTALL_RPATH}")
>>> endforeach(dir)
>>>
>>
>> s/:/;/
>>
>>
>>> You need to use a semicolon instead is a colon as a cmake list separator.
>>
>>
>>
>> I wish it could have worked. Don't understand.
>>
>> I added a message
>>
>> >> cmake ..; make VERBOSE=1
>> ...
>> target_link_libraries - lib is -L/home/fghoussen/Documents/
>> INRIA/petsc/local/lib
>> target_link_libraries - lib is -lpetsc
>> link_directories - dir is /home/fghoussen/Documents/INRIA/petsc/local/lib
>> CMAKE_INSTALL_RPATH: /home/fghoussen/Documents/
>> INRIA/petsc/local/lib;/usr/local/lib;/usr/local/lib;
>> ...
>> >> ldd main
>>     linux-vdso.so.1 (0x00007ffdec8e8000)
>>     libmpi_cxx.so.20 => /usr/lib/x86_64-linux-gnu/libmpi_cxx.so.20
>> (0x00007f429a28a000)
>>     libmpi.so.20 => /usr/lib/x86_64-linux-gnu/libmpi.so.20
>> (0x00007f4299f94000)
>>     libpetsc.so.3.8 => not found
>>
>>
>>
>>> ...
>>> SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
>>> ...
>>>
>>> >> cmake ..; make VERBOSE=1
>>> ...
>>> target_link_libraries - lib is -L/home/fghoussen/Documents/
>>> INRIA/petsc/local/lib
>>> target_link_libraries - lib is -lpetsc
>>> link_directories - dir is /home/fghoussen/Documents/
>>> INRIA/petsc/local/lib
>>> ...
>>> [ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
>>> /usr/bin/c++   -I/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi
>>> -I/usr/lib/x86_64-linux-gnu/openmpi/include/openmpi/opal/
>>> mca/event/libevent2022/libevent -I/usr/lib/x86_64-linux-gnu/
>>> openmpi/include/openmpi/opal/mca/event/libevent2022/libevent/include
>>> -I/usr/lib/x86_64-linux-gnu/openmpi/include -I/home/fghoussen/Documents/INRIA/petsc/local/include
>>> -o CMakeFiles/main.dir/main.cpp.o -c /home/fghoussen/Downloads/
>>> cmake/rpath-pkgconfig/main.cpp
>>> [100%] Linking CXX executable main
>>> /usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt
>>> --verbose=1
>>> /usr/bin/c++     CMakeFiles/main.dir/main.cpp.o  -o main
>>> -Wl,-rpath,/usr/lib/x86_64-linux-gnu/openmpi/lib
>>> /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_cxx.so
>>> /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so
>>> -L/home/fghoussen/Documents/INRIA/petsc/local/lib -lpetsc
>>> make[2]: Leaving directory '/home/fghoussen/Downloads/
>>> cmake/rpath-pkgconfig/BUILD'
>>> [100%] Built target main
>>> make[1]: Leaving directory '/home/fghoussen/Downloads/
>>> cmake/rpath-pkgconfig/BUILD'
>>> /usr/bin/cmake -E cmake_progress_start /home/fghoussen/Downloads/
>>> cmake/rpath-pkgconfig/BUILD/CMakeFiles 0
>>>
>>> >> ldd main
>>>     linux-vdso.so.1 (0x00007ffcd876b000)
>>>     libmpi_cxx.so.20 => /usr/lib/x86_64-linux-gnu/libmpi_cxx.so.20
>>> (0x00007f9eaba1f000)
>>>     libmpi.so.20 => /usr/lib/x86_64-linux-gnu/libmpi.so.20
>>> (0x00007f9eab729000)
>>>     libpetsc.so.3.8 => not found
>>>
>>>
>>> Then run cmake with the ‘-v’ option and look at the link command to
>>> verify rpath was passed correctly.
>>>
>>> You can also examine it in a library or executable with ‘objdump-x’.
>>>
>>> You may want to customize this for your project, but this should get you
>>> started.
>>>
>>> hth...
>>> don
>>>
>>> On Thu, Jan 4, 2018 at 1:25 AM Franck Houssen <franck.houssen at inria.fr>
>>> wrote:
>>>
>>>> My understanding is that you need a local copy of FindPETSc.cmake: if
>>>> this changes, you don't know it.
>>>> That's why I tried to go with the pc file.
>>>>
>>>> ----- Mail original -----
>>>> > De: "Andreas Naumann" <Andreas-Naumann at gmx.net>
>>>> > À: cmake at cmake.org
>>>> > Envoyé: Mercredi 3 Janvier 2018 21:41:51
>>>> > Objet: Re: [CMake] RPATH for pkg-config
>>>> >
>>>> > What about using a FindPETSC-Module? Some hints are
>>>> >      *http://jacobmerson.com/2016/01/17/cmake-petsc2.html
>>>> >      *http://www.mcs.anl.gov/petsc/documentation/faq.html#cmake
>>>> >
>>>> > Regards,
>>>> > Andreas
>>>> >
>>>> > Am 03.01.2018 um 21:35 schrieb Alexander Neundorf:
>>>> > > On 2018 M01 3, Wed 10:08:09 CET Franck Houssen wrote:
>>>> > >> Hello,
>>>> > >>
>>>> > >> How to ask cmake to add a library path (coming from pc file) to
>>>> rpath ?
>>>> > >>
>>>> > >> I checked this https://cmake.org/Wiki/CMake_RPATH_handling, but
>>>> still not
>>>> > >> working. Can somebody help ?
>>>> > >>>> more main.cpp
>>>> > >> #include <petsc.h>
>>>> > >>
>>>> > >> int main(int argc, char ** argv) {
>>>> > >> PetscInitialize(&argc, &argv, NULL, "");
>>>> > >> PetscFinalize();
>>>> > >> return 0;
>>>> > >> }
>>>> > >>
>>>> > >>>> more CMakeLists.txt
>>>> > >> cmake_minimum_required(VERSION 3.7)
>>>> > >> enable_language(CXX)
>>>> > >>
>>>> > >> find_package(MPI REQUIRED)
>>>> > >> find_package(PkgConfig REQUIRED) # Get pkg_check_modules.
>>>> > >> pkg_check_modules(PETSc REQUIRED PETSc)
>>>> > >>
>>>> > >> project(main)
>>>> > >> add_executable(main main.cpp)
>>>> > >>
>>>> > >> target_include_directories(main PUBLIC ${MPI_CXX_INCLUDE_PATH})
>>>> > >> target_link_libraries(main PUBLIC ${MPI_CXX_LIBRARIES})
>>>> > >>
>>>> > >> target_include_directories(main PUBLIC ${PETSc_INCLUDE_DIRS})
>>>> > >> foreach(lib ${PETSc_LDFLAGS})
>>>> > >> target_link_libraries(main PUBLIC ${lib})
>>>> > >> endforeach(lib)
>>>> > > How does each ${lib} look like ?
>>>> > > Is it "-lpetsc" or does it have the full path to the libraries ?
>>>> > > You should use the full path to the libraries, otherwise cmake
>>>> doesn't know
>>>> > > where they are and the RPATH computation will not work.
>>>> > >
>>>> > >> foreach(dir ${PETSc_LIBRARY_DIRS})
>>>> > >> link_directories(main PUBLIC ${dir}) # Not sure: is this needed ?
>>>> > >> endforeach(dir)
>>>> > > no, link_directories() in general should not be used.
>>>> > >
>>>> > >> # 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 "${CMAKE_INSTALL_PREFIX}/lib")
>>>> > > If the automatic computation fails, you could add the petsc lib dir
>>>> here as
>>>> > > INSTALL_RPATH
>>>> > >
>>>> > > Alex
>>>> > >
>>>> >
>>>> > --
>>>> >
>>>> > Powered by www.kitware.com
>>>> >
>>>> > Please keep messages on-topic and check the CMake FAQ at:
>>>> > http://www.cmake.org/Wiki/CMake_FAQ
>>>> >
>>>> > Kitware offers various services to support the CMake community. For
>>>> more
>>>> > information on each offering, please visit:
>>>> >
>>>> > CMake Support: http://cmake.org/cmake/help/support.html
>>>> > CMake Consulting: http://cmake.org/cmake/help/consulting.html
>>>> > CMake Training Courses: http://cmake.org/cmake/help/training.html
>>>> >
>>>> > Visit other Kitware open-source projects at
>>>> > http://www.kitware.com/opensource/opensource.html
>>>> >
>>>> > Follow this link to subscribe/unsubscribe:
>>>> > https://cmake.org/mailman/listinfo/cmake
>>>> >
>>>> --
>>>>
>>>> Powered by www.kitware.com
>>>>
>>>> Please keep messages on-topic and check the CMake FAQ at:
>>>> http://www.cmake.org/Wiki/CMake_FAQ
>>>>
>>>> Kitware offers various services to support the CMake community. For
>>>> more information on each offering, please visit:
>>>>
>>>> CMake Support: http://cmake.org/cmake/help/support.html
>>>> CMake Consulting: http://cmake.org/cmake/help/consulting.html
>>>> CMake Training Courses: http://cmake.org/cmake/help/training.html
>>>>
>>>> Visit other Kitware open-source projects at http://www.kitware.com/
>>>> opensource/opensource.html
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> https://cmake.org/mailman/listinfo/cmake
>>>>
>>>
>>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180104/22709c3d/attachment-0001.html>


More information about the CMake mailing list