roboticslab-uc3m / questions-and-answers

A place for general debate and question&answer
https://robots.uc3m.es/developer-manual/appendix/repository-index.html
2 stars 0 forks source link

Libraries being installed to /usr/local/lib/x86_64-linux-gnu #39

Closed PeterBowman closed 6 years ago

PeterBowman commented 6 years ago

Branching this out from roboticslab-uc3m/kinematics-dynamics#103. I've replicated that behavior in latest yarp-devices and Ubuntu 16.04 64 bits, upon the addition of YCM in the build process (roboticslab-uc3m/yarp-devices@891df8f). This is apparently triggered by using both YCM (v0.2.2) and older CMake versions (tested: v2.8.9, v2.8.11). As a result, library binaries are compiled into build/lib/x86_64-linux-gnu. Inside this directory, exported header files are copied into Headers/.

PeterBowman commented 6 years ago

I was wrong, this has nothing to do with YCM. I added lines like these at root CMakeLists.txt:

# Standard installation directories.
include(GNUInstallDirs)

# Control where libraries and executables are placed during the build.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})

CMAKE_INSTALL_LIBDIR evaluates to lib/x86_64-linux-gnu on Linux 64 bits. CMake locates the file /etc/debian_version and therefore thinks that we are using a Debian system, see https://github.com/Kitware/CMake/blob/v2.8.9/Modules/GNUInstallDirs.cmake#L71-L100.

PeterBowman commented 6 years ago

Might have been solved upstream in CMake v3.4, see https://cmake.org/cmake/help/latest/release/3.4.html#modules. Needs testing on Trusty with CMake v2.8.12 (apt package cmake, ref) and v3.5.1 (apt backport package cmake3, ref).

PeterBowman commented 6 years ago

Confirmed, Trusty users may install cmake3 (and cmake3-curses-gui for ccmake) to get lib/ as the default install path (regardless of the architecture). However, I doubt this was ever a bug - looks like the linker would have located shared libs and headers both in ${CMAKE_INSTALL_PREFIX}/lib and ${CMAKE_INSTALL_PREFIX}/lib/x86_64-linux-gnu, anyway:

$ ld --verbose | grep SEARCH_DIR
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");

That is, installed .so files should be found when compiling and on runtime. This is the output in Xenial:

$ ld --verbose | grep SEARCH_DIR
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib");

Nothing to do here, closing!

PeterBowman commented 6 years ago

It turns out that YCM actually does help to prevent this from happening: if configuring on a system with pre-v3.4 CMake, YCM fetches GNUInstallDirs.cmake from upstream and actually uses that file instead (ref), applying the improved CMAKE_INSTALL_LIBDIR path. However, to make that happen YCM must be bootstrapped before doing almost anything else in root CMakeLists.txt. See where this code is placed in kinematics-dynamics/CMakeLists.txt with respect to the include(GNUInstallDirs) statement. It is therefore a good practice to follow the next schema for any CMake list file on top of the project tree:

# Set required CMake version.
cmake_minimum_required(VERSION x.x.x FATAL_ERROR)

# Set project name.
project(my_project_name)

# Policies, internal variables, etc., nothing that requires a call to include().
# ...

# Pick up local CMake modules, plus YCMBootstrap and IncludeUrl.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)

# Bootstrap YCM.
include(YCMBootstrap)

# Anything that comes next.
# ...