diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-04-27 15:10:05 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-05-17 00:25:02 -0400 |
commit | 0ef249aa26f653677c5368bb51af34f7577ba5b9 (patch) | |
tree | 733ab2de3d9a974e555b4034c513ab58c009e68a | |
parent | 43628ed44b063e25e6d1394314ed89f07f026503 (diff) | |
download | haskell-0ef249aa26f653677c5368bb51af34f7577ba5b9.tar.gz |
Introduce package to capture dependency on C++ stdlib
Here we introduce a new "virtual" package into the initial package
database, `system-cxx-std-lib`. This gives users a convenient, platform
agnostic way to link against C++ libraries, addressing #20010.
Fixes #20010.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | distrib/configure.ac.in | 4 | ||||
-rw-r--r-- | ghc.mk | 14 | ||||
-rw-r--r-- | hadrian/bindist/Makefile | 4 | ||||
-rw-r--r-- | hadrian/src/Base.hs | 23 | ||||
-rw-r--r-- | hadrian/src/Rules/BinaryDist.hs | 2 | ||||
-rw-r--r-- | hadrian/src/Rules/Generate.hs | 3 | ||||
-rw-r--r-- | m4/fp_find_cxx_std_lib.m4 | 58 | ||||
-rw-r--r-- | mk/system-cxx-std-lib-1.0.conf.in | 13 |
10 files changed, 118 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore index 3a92338b2e..8d573b30c0 100644 --- a/.gitignore +++ b/.gitignore @@ -181,6 +181,7 @@ _darcs/ /mk/config.h.in /mk/config.mk /mk/config.mk.old +/mk/system-cxx-std-lib-1.0.conf /mk/install.mk /mk/project.mk /mk/project.mk.old diff --git a/configure.ac b/configure.ac index f9e64c3383..9f673ba2d8 100644 --- a/configure.ac +++ b/configure.ac @@ -692,6 +692,10 @@ AC_SUBST(CONF_HC_OPTS_STAGE0) AC_SUBST(CONF_HC_OPTS_STAGE1) AC_SUBST(CONF_HC_OPTS_STAGE2) +dnl Identify C++ standard library flavour and location +FP_FIND_CXX_STD_LIB +AC_CONFIG_FILES([mk/system-cxx-std-lib-1.0.conf]) + dnl ** Set up the variables for the platform in the settings file. dnl May need to use gcc to find platform details. dnl -------------------------------------------------------------- diff --git a/distrib/configure.ac.in b/distrib/configure.ac.in index 07e0687a9d..9b7abd5867 100644 --- a/distrib/configure.ac.in +++ b/distrib/configure.ac.in @@ -173,6 +173,10 @@ AC_SUBST(CONF_CPP_OPTS_STAGE0) AC_SUBST(CONF_CPP_OPTS_STAGE1) AC_SUBST(CONF_CPP_OPTS_STAGE2) +dnl Identify C++ standard library flavour and location +FP_FIND_CXX_STD_LIB +AC_CONFIG_FILES([mk/system-cxx-std-lib-1.0.conf]) + dnl ** Set up the variables for the platform in the settings file. dnl May need to use gcc to find platform details. dnl -------------------------------------------------------------- @@ -579,6 +579,10 @@ utils/check-ppr/dist-install/package-data.mk: compiler/stage2/package-data.mk utils/check-exact/dist-install/package-data.mk: compiler/stage2/package-data.mk utils/count-deps/dist-install/package-data.mk: compiler/stage2/package-data.mk +# ensure that system-cxx-std-lib is installed in the inplace compiler by +# injecting a dependency from ghc-prim +libraries/ghc-prim/dist-install/package-data.mk : inplace/lib/package.conf.d/system-cxx-std-lib-1.0.conf + # add the final package.conf dependency: ghc-prim depends on RTS libraries/ghc-prim/dist-install/package-data.mk : rts/dist-install/package.conf.inplace endif @@ -823,6 +827,12 @@ INSTALL_LIBRARY_DOCS += libraries/dist-haddock/* endif # ----------------------------------------------------------------------------- +# system-cxx-std-lib + +inplace/lib/package.conf.d/system-cxx-std-lib-1.0.conf : mk/system-cxx-std-lib-1.0.conf $(ghc-pkg_INPLACE) + "$(ghc-pkg_INPLACE)" update --force $< + +# ----------------------------------------------------------------------------- # Creating a local mingw copy on Windows ifeq "$(Windows_Host)" "YES" @@ -993,7 +1003,7 @@ INSTALL_DISTDIR_compiler = stage2 # Now we can do the installation install_packages: install_libexecs -install_packages: rts/dist-install/package.conf.install +install_packages: rts/dist-install/package.conf.install mk/system-cxx-std-lib-1.0.conf.install $(INSTALL_DIR) "$(DESTDIR)$(topdir)" $(call removeTrees,"$(INSTALLED_PACKAGE_CONF)") $(INSTALL_DIR) "$(INSTALLED_PACKAGE_CONF)" @@ -1010,6 +1020,7 @@ install_packages: rts/dist-install/package.conf.install '$(docdir)/html/libraries' \ '$(GhcLibWays)')) "$(INSTALLED_GHC_PKG_REAL)" --force --global-package-db "$(INSTALLED_PACKAGE_CONF)" update rts/dist-install/package.conf.install + "$(INSTALLED_GHC_PKG_REAL)" --force --global-package-db "$(INSTALLED_PACKAGE_CONF)" update mk/system-cxx-std-lib-1.0.conf $(foreach p, $(INSTALL_PACKAGES), \ $(call make-command, \ "$(ghc-cabal_INPLACE)" register \ @@ -1050,6 +1061,7 @@ $(eval $(call bindist-list,.,\ packages \ Makefile \ mk/config.mk.in \ + mk/system-cxx-std-lib-1.0.conf.in \ $(INPLACE_BIN)/mkdirhier \ utils/ghc-cabal/dist-install/build/tmp/ghc-cabal \ $(BINDIST_WRAPPERS) \ diff --git a/hadrian/bindist/Makefile b/hadrian/bindist/Makefile index 6b2e1f8754..7752dd0f72 100644 --- a/hadrian/bindist/Makefile +++ b/hadrian/bindist/Makefile @@ -208,7 +208,9 @@ install_wrappers: install_bin_libdir PKG_CONFS = $(shell find "$(ActualLibsDir)/package.conf.d" -name '*.conf' | sed "s: :\0xxx\0:g") update_package_db: install_bin install_lib - @echo "$(PKG_CONFS)" + @echo "Installing C++ standard library virtual package" + cp mk/system-cxx-std-lib-1.0.conf "$(ActualLibsDir)/" + @echo "Updating the package DB" $(foreach p, $(PKG_CONFS),\ $(call patchpackageconf,$(shell echo $(notdir $p) | sed 's/-\([0-9]*[0-9]\.\)*conf//g'),$(shell echo "$p" | sed 's:\0xxx\0: :g'),$(docdir),$(shell mk/relpath.sh "$(ActualLibsDir)" "$(docdir)"))) diff --git a/hadrian/src/Base.hs b/hadrian/src/Base.hs index febe1ea7b2..b88e2e4df8 100644 --- a/hadrian/src/Base.hs +++ b/hadrian/src/Base.hs @@ -28,6 +28,7 @@ module Base ( stageBinPath, stageLibPath, templateHscPath, ghcBinDeps, ghcLibDeps, haddockDeps, relativePackageDbPath, packageDbPath, packageDbStamp, mingwStamp, + systemCxxStdLibConf, systemCxxStdLibConfPath ) where import Control.Applicative @@ -93,6 +94,15 @@ packageDbPath stage = buildRoot <&> (-/- relativePackageDbPath stage) packageDbStamp :: FilePath packageDbStamp = ".stamp" +systemCxxStdLibConf :: FilePath +systemCxxStdLibConf = "system-cxx-std-lib-1.0.conf" + +-- | The name of the generated @system-cxx-std-lib-1.0.conf@ package database +-- entry. +systemCxxStdLibConfPath :: Stage -> Action FilePath +systemCxxStdLibConfPath stage = + packageDbPath stage <&> (-/- systemCxxStdLibConf) + -- | @bin@ directory for the given 'Stage' (including the build root) stageBinPath :: Stage -> Action FilePath stageBinPath stage = buildRoot <&> (-/- stageString stage -/- "bin") @@ -103,11 +113,14 @@ stageLibPath stage = buildRoot <&> (-/- stageString stage -/- "lib") -- | Files the GHC library depends on ghcLibDeps :: Stage -> Action [FilePath] -ghcLibDeps stage = mapM (\f -> stageLibPath stage <&> (-/- f)) - [ "llvm-targets" - , "llvm-passes" - , "settings" - ] +ghcLibDeps stage = do + ps <- mapM (\f -> stageLibPath stage <&> (-/- f)) + [ "llvm-targets" + , "llvm-passes" + , "settings" + ] + cxxStdLib <- systemCxxStdLibConfPath stage + return (cxxStdLib : ps) -- | Files the GHC binary depends on. ghcBinDeps :: Stage -> Action [FilePath] diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs index 3b5dbca5a6..9c98c85371 100644 --- a/hadrian/src/Rules/BinaryDist.hs +++ b/hadrian/src/Rules/BinaryDist.hs @@ -324,7 +324,6 @@ bindistRules = do top <- topDirectory copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath - -- Copy various configure-related files needed for a working -- './configure [...] && make install' workflow -- (see the list of files needed in the 'binary-dist' rule above, before @@ -360,6 +359,7 @@ bindistInstallFiles = [ "config.sub", "config.guess", "install-sh" , "mk" -/- "config.mk.in", "mk" -/- "install.mk.in", "mk" -/- "project.mk" , "mk" -/- "relpath.sh" + , "mk" -/- "system-cxx-std-lib-1.0.conf.in" , "README", "INSTALL" ] -- | This auxiliary function gives us a top-level 'Filepath' that we can 'need' diff --git a/hadrian/src/Rules/Generate.hs b/hadrian/src/Rules/Generate.hs index 1cd95d7961..ca96302db3 100644 --- a/hadrian/src/Rules/Generate.hs +++ b/hadrian/src/Rules/Generate.hs @@ -192,6 +192,9 @@ copyRules = do prefix -/- "html/**" <~ return "utils/haddock/haddock-api/resources" prefix -/- "latex/**" <~ return "utils/haddock/haddock-api/resources" + root -/- relativePackageDbPath stage -/- systemCxxStdLibConf %> \file -> do + copyFile ("mk" -/- "system-cxx-std-lib-1.0.conf") file + generateRules :: Rules () generateRules = do root <- buildRootRules diff --git a/m4/fp_find_cxx_std_lib.m4 b/m4/fp_find_cxx_std_lib.m4 new file mode 100644 index 0000000000..d0bb3195c6 --- /dev/null +++ b/m4/fp_find_cxx_std_lib.m4 @@ -0,0 +1,58 @@ +# FP_FIND_CXX_STD_LIB +# ------------------- +# +# Identify which C++ standard library implementation the C++ toolchain links +# against. +AC_DEFUN([FP_FIND_CXX_STD_LIB],[ + # If this is non-empty then assume that the user has specified these + # manually. + if test -z "$CXX_STD_LIB_LIBS"; then + cat >actest.cpp <<-EOF +#include <iostream> +#if defined(_LIBCPP_VERSION) +libc++ +#elif defined(__GLIBCXX__) +libstdc++ +#else +unknown +#endif +EOF + AC_MSG_CHECKING([C++ standard library flavour]) + if "$CXX" -E actest.cpp -o actest.out; then + if grep "libc++" actest.out; then + CXX_STD_LIB_LIBS="c++ c++abi" + p="`"$CXX" --print-file-name libc++.so`" + d="`dirname "$p"`" + dnl On some platforms (e.g. Windows) the C++ standard library + dnl can be found in the system search path. In this case $CXX + dnl --print-file-name will simply print the filename without a + dnl directory part. Consequently, dirname will return `.`. However, + dnl we don't want to include such paths in the package database. + if test "$d" = "."; then d=""; fi + CXX_STD_LIB_LIB_DIRS="$d" + CXX_STD_LIB_DYN_LIB_DIRS="$d" + AC_MSG_RESULT([libc++]) + elif grep "libstdc++" actest.out; then + CXX_STD_LIB_LIBS="stdc++" + p="`"$CXX" --print-file-name libstdc++.so`" + d="`dirname "$p"`" + if test "$d" = "."; then d=""; fi + CXX_STD_LIB_LIB_DIRS="$d" + CXX_STD_LIB_DYN_LIB_DIRS="$d" + AC_MSG_RESULT([libstdc++]) + else + rm -f actest.cpp actest.out + AC_MSG_ERROR([Unknown C++ standard library implementation.]) + fi + rm -f actest.cpp actest.out + else + rm -f actest.cpp actest.out + AC_MSG_ERROR([Failed to compile test program]) + fi + fi + + AC_SUBST([CXX_STD_LIB_LIBS]) + AC_SUBST([CXX_STD_LIB_LIB_DIRS]) + AC_SUBST([CXX_STD_LIB_DYN_LIB_DIRS]) +]) + diff --git a/mk/system-cxx-std-lib-1.0.conf.in b/mk/system-cxx-std-lib-1.0.conf.in new file mode 100644 index 0000000000..34e6eb3596 --- /dev/null +++ b/mk/system-cxx-std-lib-1.0.conf.in @@ -0,0 +1,13 @@ +name: system-cxx-std-lib +version: 1.0 +visibility: public +id: system-cxx-std-lib-1.0 +key: system-cxx-std-lib-1.0 +synopsis: A placeholder for the system's C++ standard library implementation. +category: System +abi: 00000000000000000000000000000000 +exposed: True +exposed-modules: +extra-libraries: @CXX_STD_LIB_LIBS@ +library-dirs: @CXX_STD_LIB_LIB_DIRS@ +dynamic-library-dirs: @CXX_STD_LIB_DYN_LIB_DIRS@ |