From 7f1b1a0fb7e95aae249fae94029e9d12ebb33736 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Sat, 11 Jan 2020 17:18:45 +0100 Subject: [PATCH] Config file: Use a separate section for multilib targets --- ldc2.conf.in | 2 +- ldc2_install.conf.in | 2 +- ldc2_phobos.conf.in | 2 +- runtime/CMakeLists.txt | 71 ++++++++++++++++++++++++----------- tools/add-multilib-section.sh | 45 ++++++++++++++++++++++ 5 files changed, 97 insertions(+), 25 deletions(-) create mode 100755 tools/add-multilib-section.sh diff --git a/ldc2.conf.in b/ldc2.conf.in index 6cbfa30c865..1ec4ce854c4 100644 --- a/ldc2.conf.in +++ b/ldc2.conf.in @@ -28,7 +28,7 @@ default: ]; // default directories to be searched for libraries when linking lib-dirs = [ - "@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@ + "@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@", ]; // default rpath when linking against the shared default libs rpath = "@SHARED_LIBS_RPATH@"; diff --git a/ldc2_install.conf.in b/ldc2_install.conf.in index 0e3034218ab..7536f8f0d4f 100644 --- a/ldc2_install.conf.in +++ b/ldc2_install.conf.in @@ -26,7 +26,7 @@ default: ]; // default directories to be searched for libraries when linking lib-dirs = [ - "@CMAKE_INSTALL_LIBDIR@",@MULTILIB_ADDITIONAL_INSTALL_PATH@ + "@CMAKE_INSTALL_LIBDIR@", ]; // default rpath when linking against the shared default libs rpath = "@SHARED_LIBS_INSTALL_RPATH@"; diff --git a/ldc2_phobos.conf.in b/ldc2_phobos.conf.in index 639b713a954..9bc5b1aa484 100644 --- a/ldc2_phobos.conf.in +++ b/ldc2_phobos.conf.in @@ -29,7 +29,7 @@ default: ]; // default directories to be searched for libraries when linking lib-dirs = [ - "@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@",@MULTILIB_ADDITIONAL_PATH@ + "@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@", ]; // default rpath when linking against the shared default libs rpath = "@SHARED_LIBS_RPATH@"; diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 1f7a245528d..2a5c794e5bf 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -230,24 +230,10 @@ endif() # Create configuration files. # -# Add extra paths on Linux and disable linker arch mismatch warnings (like -# DMD and GDC do). OS X doesn't need extra configuration due to the use of -# fat binaries. Other Posixen might need to be added here. -if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE") - set(ADDITIONAL_DEFAULT_LDC_SWITCHES "${ADDITIONAL_DEFAULT_LDC_SWITCHES}\n \"-L--no-warn-search-mismatch\",") - set(MULTILIB_ADDITIONAL_PATH "\n \"${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}\",") - set(MULTILIB_ADDITIONAL_INSTALL_PATH "\n \"${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX}\",") -endif() - # Default -rpath linker option when linking against shared libraries. if(SHARED_LIBS_SUPPORTED) - if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE") - set(SHARED_LIBS_RPATH "${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}:${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}") - set(SHARED_LIBS_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}:${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX}") - else() - set(SHARED_LIBS_RPATH "${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}") - set(SHARED_LIBS_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") - endif() + set(SHARED_LIBS_RPATH "${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}") + set(SHARED_LIBS_INSTALL_RPATH "${CMAKE_INSTALL_LIBDIR}") endif() # Only have either shared or static libs? @@ -276,8 +262,49 @@ if(LDC_EXE) else() set(CONFIG_NAME ${LDC_EXE}) endif() - configure_file(${PROJECT_PARENT_DIR}/${CONFIG_NAME}.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}.conf @ONLY) - configure_file(${PROJECT_PARENT_DIR}/${LDC_EXE}_install.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}_install.conf @ONLY) + set(conf_path ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}.conf) + set(install_conf_path ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}_install.conf) + configure_file(${PROJECT_PARENT_DIR}/${CONFIG_NAME}.conf.in ${conf_path} @ONLY) + configure_file(${PROJECT_PARENT_DIR}/${LDC_EXE}_install.conf.in ${install_conf_path} @ONLY) + + # macOS has fat libraries; otherwise, append a separate config file section for the + # multilib target and override the lib directory. + if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE") + file(RENAME ${conf_path} ${conf_path}.in) + file(RENAME ${install_conf_path} ${install_conf_path}.in) + if(SHARED_LIBS_SUPPORTED) + set(MULTILIB_RPATH "${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}") + set(MULTILIB_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX}") + endif() + + # Determine the multilib triple by parsing the `ldc2 -m32 -v` output. + # This means we depend on a built ldc2 executable; sadly, we cannot + # add post-build commands to that top-level target directly, so use + # a custom target built as part of `all`. + add_custom_command(OUTPUT ${conf_path} + COMMAND ${PROJECT_PARENT_DIR}/tools/add-multilib-section.sh + ${LDC_EXE_FULL} + ${MULTILIB_SUFFIX} + ${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX} + "${MULTILIB_RPATH}" + ${conf_path}.in + ${conf_path} + DEPENDS ${LDC_EXE} ${LDC_EXE_FULL} + ) + add_custom_command(OUTPUT ${install_conf_path} + COMMAND ${PROJECT_PARENT_DIR}/tools/add-multilib-section.sh + ${LDC_EXE_FULL} + ${MULTILIB_SUFFIX} + ${CMAKE_INSTALL_PREFIX}/lib${MULTILIB_SUFFIX} + "${MULTILIB_INSTALL_RPATH}" + ${install_conf_path}.in + ${install_conf_path} + DEPENDS ${LDC_EXE} ${LDC_EXE_FULL} + ) + add_custom_target(add-multilib-section ALL + DEPENDS ${conf_path} ${install_conf_path} + ) + endif() endif() # @@ -356,10 +383,10 @@ macro(dc src_files src_basedir d_flags output_basedir emit_bc all_at_once outlis list(APPEND dc_flags -flto=thin --output-bc) endif() - set(dc_deps ${LDC_EXE} - ${LDC_EXE_FULL} - ${GCCBUILTINS} - ) + set(dc_deps ${LDC_EXE} ${LDC_EXE_FULL} ${GCCBUILTINS}) + if(TARGET add-multilib-section) + set(dc_deps ${dc_deps} add-multilib-section) + endif() set(relative_src_files "") set(new_o "") diff --git a/tools/add-multilib-section.sh b/tools/add-multilib-section.sh new file mode 100755 index 00000000000..3a6f8e3b8b7 --- /dev/null +++ b/tools/add-multilib-section.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set -euo pipefail + +if [ "$#" -ne 6 ]; then + echo "Usage: $0 <32|64> " + exit 1 +fi + +ldc=$1 +bitness=$2 +libdir=$3 +rpath=$4 +input_conf=$5 +output_conf=$6 + +# parse multilib triple from `-v` output +set +e +# extract `config /path/to/ldc2.conf (i686-unknown-linux-gnu)` +triple="$(echo "module bla;" | $ldc -m$bitness -v -o- -conf=$input_conf - | grep -m 1 '^config')" +triple="${triple##* (}" # `i686-unknown-linux-gnu)` +triple="${triple%)}" # `i686-unknown-linux-gnu` +if [ "${triple//[^-]/}" = "---" ]; then + # ignore vendor => `i686-.*-linux-gnu` + triple="$(echo "$triple" | sed -e 's/-[^-]*/-.*/')" +fi +set -e + +cp $input_conf $output_conf + +if [ -z "$triple" ]; then + echo "Error: failed to parse triple from \"$ldc -m$bitness -v\" output" + exit 1 +fi + +# append config file section +section=" +\"$triple\": +{ + lib-dirs = [ + \"$libdir\", + ]; + rpath = \"$rpath\"; +};" +echo "$section" >> $output_conf