From cbdd8182db13972d80edd1825a83a41b9b1bc98f Mon Sep 17 00:00:00 2001 From: Markus Blatt <markus@dr-blatt.de> Date: Tue, 7 Jan 2014 15:41:27 +0100 Subject: [PATCH] [cmake,release] Correctly treat multiarch triplets in Debian. Debian uses multiarch-triplets (e.g. i386-gnu-linux) when installing object libraries. These are installed to lib/$multiarch-triplet and not to lib directly. In CMake this concept is partially supported by GNUInstallDirs.cmake by setting CMAKE_INSTALL_LIBDIR to lib/$multiarch-triplet. Unfortunately, this is only half the way through as we also install libraries that do not differ between architectures (e.g. our shell libraries. This patch addes multiarch support for CMake to the best of my knowledge, which might be limited, though: - All not architecture dependent libraries are installed below the variable DUNE_INSTALL_NONOBJECTLIBDIR, which defaults to lib, but might be adjusted by the user. - If the module ships an object library then the pkg-config and CMake package configuration files are installed in lib/$multiarch-triplet/pkg-config and lib/$multiarch-triplet/cmake/modules, respectively. - If not then they are installed in lib/pkg-config and lib/cmake/modules, respectively. Note that for autotool no such difference exists and always the latter approach is used. --- bin/dunecontrol | 73 ++++++++++++++++++++++++------- cmake/modules/DuneMacros.cmake | 37 ++++++++++++---- cmake/modules/DunePkgConfig.cmake | 62 +++++++++++++------------- 3 files changed, 118 insertions(+), 54 deletions(-) diff --git a/bin/dunecontrol b/bin/dunecontrol index 513ef5b0f..9ce68c1e9 100755 --- a/bin/dunecontrol +++ b/bin/dunecontrol @@ -78,17 +78,6 @@ if test "x$DEBUG" = "xyes"; then set -v fi -export PREFIX_DIR="`canonicalpath "$0"`/.." - -# create PKG_CONFIG_PATH for installed dune modules -if test -d "$PREFIX_DIR/lib/pkgconfig"; then - export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$PREFIX_DIR/lib/pkgconfig" -fi - -# Read the modules find part -. "$PREFIX_DIR/lib/dunemodules.lib" - -############################################### onbuildfailure() { echo "Terminating $(basename "$0") due to previous errors!" >&2 @@ -218,6 +207,54 @@ load_opts() { fi } +# Uses the current compiler to extract information about the +# multiarch triplets and sets the export variable MULTIARCH_LIBDIR +# according to it. +# If not compiler is specified then cc or gcc is used. +extract_multiarch(){ + local my_cxx_compiler + if test "x$MULTIARCH_LIBDIR" != "x"; then + return + fi + if test "x$USE_CMAKE" = "xyes"; then + load_opts "cmake" + my_cxx_compiler=`echo $CMAKE_FLAGS | sed "s/.*\(-DCMAKE_CXX_COMPILER[:FILEPATH]*=\"[^\"]*\"\|$i='[^']*'\|$i=[^\s^ ]*\).*/\1/"` + fi + if test "x$my_cxx_compiler" == "x"; then + load_opts "configure" + my_cxx_compiler=`echo $CONFIGURE_FLAGS | sed "s/.*\(CXX=\"[^\"]*\"\|$i='[^']*'\|$i=[^\s^ ]*\).*/\1/"` + fi + if test "x$my_cxx_compiler" == "x"; then + set +e + $(which cc &>/dev/null) + if test $? -eq "0"; then + my_cxx_compiler=cc + else + my_cxx_compiler=gcc + fi + fi + set -e + export MULTIARCH_LIBDIR="lib/$($my_cxx_compiler --print-multiarch)" +} + +export PREFIX_DIR="`canonicalpath "$0"`/.." + +extract_multiarch + +# create PKG_CONFIG_PATH for installed dune modules +for i in $MULTIARCH_LIBDIR lib64 lib32 lib; do + if test -d "$PREFIX_DIR/$i/pkgconfig"; then + export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$PREFIX_DIR/$i/pkgconfig" + break; + fi +done + +# Read the modules find part +. "$PREFIX_DIR/lib/dunemodules.lib" + +############################################### + + ############################################### ### ### Commands @@ -555,6 +592,7 @@ run_default_autogen () { } run_default_configure () { + extract_multiarch PARAMS="$CMD_FLAGS" if test "x$USE_CMAKE" = "xyes" && test -e "$(eval "echo \$PATH_$module")/CMakeLists.txt"; then LOCAL_USE_CMAKE=yes @@ -595,11 +633,14 @@ run_default_configure () { if test -d "$path/$BUILDDIR"; then CMAKE_PARAMS="$CMAKE_PARAMS \"-D""$name""_DIR=$path/$BUILDDIR\"" else - if test -d "$path/lib/cmake/$name"; then - CMAKE_PARAMS="$CMAKE_PARAMS \"-D""$name""_DIR=$path/lib/cmake/$name\"" - else - CMAKE_PARAMS="$CMAKE_PARAMS \"-D""$name""_DIR=$path\"" - fi + TMP_PARAMS="\"-D""$name""_DIR=$path\"" + for i in $MULTIARCH_LIBDIR lib lib64 lib32; do + if test -d "$path/$i/cmake/$name"; then + TMP_PARAMS="\"-D""$name""_DIR=$path/$i/cmake/$name\"" + break; + fi + done + CMAKE_PARAMS="$CMAKE_PARAMS $TMP_PARAMS" fi fi done diff --git a/cmake/modules/DuneMacros.cmake b/cmake/modules/DuneMacros.cmake index e7af3b044..cb3299e6b 100644 --- a/cmake/modules/DuneMacros.cmake +++ b/cmake/modules/DuneMacros.cmake @@ -139,7 +139,7 @@ endfunction(convert_deps_to_list var) macro(dune_module_information MODULE_DIR) file(READ "${MODULE_DIR}/dune.module" DUNE_MODULE) - # find version string + # find version strings extract_line("Version:" MODULE_LINE "${DUNE_MODULE}") if(NOT MODULE_LINE) message(FATAL_ERROR "${MODULE_DIR}/dune.module is missing a version.") @@ -529,7 +529,12 @@ macro(dune_project) "Installation directory for CMake modules. Default is \${CMAKE_INSTALL_DATAROOTDIR}/dune/cmake/modules when not set explicitely") set(DUNE_INSTALL_MODULEDIR ${CMAKE_INSTALL_DATAROOTDIR}/dune/cmake/modules) endif(NOT DUNE_INSTALL_MODULEDIR) - + if(NOT DUNE_INSTALL_NONOBJECTLIBDIR) + set(DUNE_INSTALL_NONOBJECTLIBDIR "" + CACHE PATH + "Installation directory for libraries that are not architecture dependent. Default is lib when not set explicitely") + set(DUNE_INSTALL_NONOBJECTLIBDIR lib) + endif(NOT DUNE_INSTALL_NONOBJECTLIBDIR) # set up make headercheck include(Headercheck) setup_headercheck() @@ -631,9 +636,22 @@ endif(NOT @DUNE_MOD_NAME@_FOUND)") set(CONFIG_SOURCE_FILE ${PROJECT_SOURCE_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake.in) endif(NOT EXISTS ${PROJECT_SOURCE_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake.in) get_property(DUNE_MODULE_LIBRARIES GLOBAL PROPERTY DUNE_MODULE_LIBRARIES) + + # compute under which libdir the package configuration files are to be installed. + # If the module installs an object library we use CMAKE_INSTALL_LIBDIR + # to capture the multiarch triplet of Debian/Ubuntu. + # Otherwise we fall back to DUNE_INSTALL_NONOBJECTLIB which is lib + # if not set otherwise. + get_property(DUNE_MODULE_LIBRARIES GLOBAL PROPERTY DUNE_MODULE_LIBRARIES) + if(DUNE_MODULE_LIBRARIES) + set(DUNE_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}) + else(DUNE_MODULE_LIBRARIES) + set(DUNE_INSTALL_LIBDIR ${DUNE_INSTALL_NONOBJECTLIBDIR}) + endif(DUNE_MODULE_LIBRARIES) + configure_package_config_file(${CONFIG_SOURCE_FILE} ${PROJECT_BINARY_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake - INSTALL_DESTINATION lib/cmake/${DUNE_MOD_NAME} + INSTALL_DESTINATION ${DUNE_INSTALL_LIBDIR}/cmake/${DUNE_MOD_NAME} PATH_VARS CMAKE_INSTALL_DATAROOTDIR DUNE_INSTALL_MODULEDIR CMAKE_INSTALL_INCLUDEDIR DOXYSTYLE_DIR SCRIPT_DIR) @@ -702,18 +720,21 @@ endif() ${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-version.cmake @ONLY) #install dune.module file - install(FILES dune.module DESTINATION lib/dunecontrol/${DUNE_MOD_NAME}) + install(FILES dune.module DESTINATION ${DUNE_INSTALL_NONOBJECTLIBDIR}/dunecontrol/${DUNE_MOD_NAME}) - #install cmake-config files + # install cmake-config files install(FILES ${PROJECT_BINARY_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake ${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-version.cmake - DESTINATION lib/cmake/${DUNE_MOD_NAME}) + DESTINATION ${DUNE_INSTALL_LIBDIR}/cmake/${DUNE_MOD_NAME}) #install config.h if(EXISTS ${CMAKE_SOURCE_DIR}/config.h.cmake) install(FILES config.h.cmake DESTINATION share/${DUNE_MOD_NAME}) endif(EXISTS ${CMAKE_SOURCE_DIR}/config.h.cmake) + #install pkg-config files + create_and_install_pkconfig(${DUNE_INSTALL_LIBDIR}) + if("${ARGC}" EQUAL "1") message(STATUS "Adding custom target for config.h generation") dune_regenerate_config_cmake() @@ -883,9 +904,9 @@ macro(dune_add_library basename) endif(NOT _MODULE_EXPORT_USED) # install targets to use the libraries in other modules. install(TARGETS ${_created_libs} - EXPORT ${DUNE_MOD_NAME}-targets DESTINATION lib) + EXPORT ${DUNE_MOD_NAME}-targets DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(EXPORT ${DUNE_MOD_NAME}-targets - DESTINATION lib/cmake/${DUNE_MOD_NAME}) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${DUNE_MOD_NAME}) # export libraries for use in build tree export(TARGETS ${_created_libs} ${_append} diff --git a/cmake/modules/DunePkgConfig.cmake b/cmake/modules/DunePkgConfig.cmake index 0b6e3fa87..a917b33e5 100644 --- a/cmake/modules/DunePkgConfig.cmake +++ b/cmake/modules/DunePkgConfig.cmake @@ -5,37 +5,39 @@ find_package(PkgConfig) -# set some variables that are used in the pkg-config file -set( prefix ${CMAKE_INSTALL_PREFIX}) -set(exec_prefix "\${prefix}") -set(libdir "\${exec_prefix}/lib") -set(includedir "\${prefix}/include") -set(PACKAGE_NAME ${DUNE_MOD_NAME}) -set(VERSION ${DUNE_MOD_VERSION}) -set(CC ${CMAKE_C_COMPILER}) -set(CXX "${CMAKE_CXX_COMPILER} ${CXX_STD11_FLAGS}") +function(create_and_install_pkconfig installlibdir) + # set some variables that are used in the pkg-config file + include(GNUInstallDirs) + set( prefix ${CMAKE_INSTALL_PREFIX}) + set(exec_prefix "\${prefix}") + set(libdir "\${exec_prefix}/${installlibdir}") + set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") + set(PACKAGE_NAME ${DUNE_MOD_NAME}) + set(VERSION ${DUNE_MOD_VERSION}) + set(CC ${CMAKE_C_COMPILER}) + set(CXX "${CMAKE_CXX_COMPILER} ${CXX_STD11_FLAGS}") -if(DUNE_DEPENDS) - foreach(_DUNE_DEPEND ${DUNE_DEPENDS}) - string(REGEX REPLACE "\\(" "" REQF1 ${_DUNE_DEPEND}) - string(REGEX REPLACE "\\)" "" LR ${REQF1}) - if(REQUIRES) - set(REQUIRES "${REQUIRES} ${LR}") - else() - set(REQUIRES ${LR}) - endif(REQUIRES) - endforeach(_DUNE_DEPEND ${DUNE_DEPENDS}) -endif(DUNE_DEPENDS) + if(DUNE_DEPENDS) + foreach(_DUNE_DEPEND ${DUNE_DEPENDS}) + string(REGEX REPLACE "\\(" "" REQF1 ${_DUNE_DEPEND}) + string(REGEX REPLACE "\\)" "" LR ${REQF1}) + if(REQUIRES) + set(REQUIRES "${REQUIRES} ${LR}") + else() + set(REQUIRES ${LR}) + endif(REQUIRES) + endforeach(_DUNE_DEPEND ${DUNE_DEPENDS}) + endif(DUNE_DEPENDS) -#create pkg-config file -configure_file( - ${PROJECT_SOURCE_DIR}/${DUNE_MOD_NAME}.pc.in - ${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}.pc - @ONLY -) + #create pkg-config file + configure_file( + ${PROJECT_SOURCE_DIR}/${DUNE_MOD_NAME}.pc.in + ${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}.pc + @ONLY + ) -# install pkgconfig file -if(PKG_CONFIG_FOUND) + # install pkgconfig file install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${DUNE_MOD_NAME}.pc - DESTINATION lib/pkgconfig) -endif(PKG_CONFIG_FOUND) + DESTINATION ${installlibdir}/pkgconfig) + +endfunction(create_and_install_pkconfig) -- GitLab