diff --git a/Makefile b/Makefile index a73513279fa9..5708309e0a41 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ # - [ ] Where do we get the version number from? The configure script _does_ contain # one and sets it, but should it come from the last release tag this branch is # contains? -# - [ ] HADRIAN_SETTINGS needs to be removed. +# - [x] HADRIAN_SETTINGS has been removed. Version/platform info now generated by configure. # - [ ] The hadrian folder needs to be removed. # - [ ] All sublibs should be SRPs in the relevant cabal.project files. No more # submodules. @@ -169,17 +169,11 @@ TARGET_OS = $(call GHC_INFO,target os) TARGET_TRIPLE = $(call GHC_INFO,Target platform) GIT_COMMIT_ID := $(shell git rev-parse HEAD) -define HADRIAN_SETTINGS -[ ("hostPlatformArch", "$(TARGET_ARCH)") \ -, ("hostPlatformOS", "$(TARGET_OS)") \ -, ("cProjectGitCommitId", "$(GIT_COMMIT_ID)") \ -, ("cProjectVersion", "9.14") \ -, ("cProjectVersionInt", "914") \ -, ("cProjectPatchLevel", "0") \ -, ("cProjectPatchLevel1", "0") \ -, ("cProjectPatchLevel2", "0") \ -] -endef +# HADRIAN_SETTINGS has been removed. +# Version and platform info is now generated by ./configure into: +# - libraries/ghc-boot/GHC/Version.hs (from Version.hs.in) +# - libraries/ghc-boot/GHC/Platform/Host.hs (from Host.hs.in) +# See configure.ac for details. # Handle CPUS and THREADS CPUS_DETECT_SCRIPT := ./mk/detect-cpu-count.sh @@ -206,6 +200,8 @@ CONFIGURED_FILES := \ compiler/GHC/CmmToLlvm/Version/Bounds.hs \ compiler/ghc.cabal \ libraries/ghc-boot/ghc-boot.cabal \ + libraries/ghc-boot/GHC/Version.hs \ + libraries/ghc-boot/GHC/Platform/Host.hs \ libraries/ghc-boot-th/ghc-boot-th.cabal \ libraries/ghc-heap/ghc-heap.cabal \ libraries/template-haskell/template-haskell.cabal \ @@ -587,7 +583,7 @@ $(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES)) &: $(CABAL) $(CONFIGURE_SC @echo "::group::Building stage1 executables ($(STAGE1_EXECUTABLES))..." # Force cabal to replan rm -rf _build/stage1/cache - HADRIAN_SETTINGS='$(HADRIAN_SETTINGS)' $(CABAL_BUILD) $(STAGE1_TARGETS) + $(CABAL_BUILD) $(STAGE1_TARGETS) @echo "::endgroup::" _build/stage1/lib/settings: _build/stage1/bin/ghc-toolchain-bin @@ -631,8 +627,7 @@ $(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES)) &: $(CABAL) stage1 @echo "::group::Building stage2 executables ($(STAGE2_EXECUTABLES))..." # Force cabal to replan rm -rf _build/stage2/cache - HADRIAN_SETTINGS='$(HADRIAN_SETTINGS)' \ - PATH=$(PWD)/_build/stage1/bin:$(PATH) \ + PATH=$(PWD)/_build/stage1/bin:$(PATH) \ $(CABAL_BUILD) --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" -W $(GHC0) $(STAGE2_TARGETS) @echo "::endgroup::" @@ -645,8 +640,7 @@ $(addprefix _build/stage2/bin/,$(STAGE2_UTIL_EXECUTABLES)) &: $(CABAL) stage1 ca @echo "::group::Building stage2 utilities ($(STAGE2_UTIL_EXECUTABLES))..." # Force cabal to replan rm -rf _build/stage2/cache - HADRIAN_SETTINGS='$(HADRIAN_SETTINGS)' \ - PATH=$(PWD)/_build/stage1/bin:$(PATH) \ + PATH=$(PWD)/_build/stage1/bin:$(PATH) \ $(CABAL_BUILD) --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" -W $(GHC0) $(STAGE2_UTIL_TARGETS) @echo "::endgroup::" @@ -718,8 +712,7 @@ _build/stage3/lib/targets/%/lib/ghc-interp.js: # $1 = TIPLET define build_cross - HADRIAN_SETTINGS='$(call HADRIAN_SETTINGS)' \ - PATH=$(PWD)/_build/stage2/bin:$(PWD)/_build/stage3/bin:$(PATH) \ + PATH=$(PWD)/_build/stage2/bin:$(PWD)/_build/stage3/bin:$(PATH) \ $(CABAL_BUILD) -W $(GHC2) --happy-options="--template=$(abspath _build/stage2/src/happy-lib-2.1.5/data/)" --with-hsc2hs=$1-hsc2hs --hsc2hs-options='-x' --configure-option='--host=$1' \ $(foreach lib,$(CROSS_EXTRA_LIB_DIRS),--extra-lib-dirs=$(lib)) \ $(foreach include,$(CROSS_EXTRA_INCLUDE_DIRS),--extra-include-dirs=$(include)) \ diff --git a/configure.ac b/configure.ac index 224f12cbc7da..4bf02959318b 100644 --- a/configure.ac +++ b/configure.ac @@ -7,13 +7,138 @@ AC_CONFIG_MACRO_DIR([m4]) # For any custom m4 macros # --- Define GHC Build Options --- # Usage: ./configure ProjectVersion=X.Y ... AC_ARG_WITH([project-version], [AS_HELP_STRING([--with-project-version=VER], [GHC version (default: 9.14)])], [ProjectVersion="$withval"], [ProjectVersion="9.14"]) -AC_ARG_WITH([project-version-int], [AS_HELP_STRING([--with-project-version-int=VER], [GHC version as int (default: 913)])], [ProjectVersionInt="$withval"], [ProjectVersionInt="913"]) +AC_ARG_WITH([project-version-int], [AS_HELP_STRING([--with-project-version-int=VER], [GHC version as int (default: 914)])], [ProjectVersionInt="$withval"], [ProjectVersionInt="914"]) AC_ARG_WITH([project-version-munged], [AS_HELP_STRING([--with-project-version-munged=VER], [GHC version "munged" (default: 9.14)])], [ProjectVersionMunged="$withval"], [ProjectVersionMunged="9.14"]) AC_ARG_WITH([project-version-for-lib], [AS_HELP_STRING([--with-project-version-for-lib=VER], [GHC version for libraries (default: 9.1400)])], [ProjectVersionForLib="$withval"], [ProjectVersionForLib="9.1400"]) AC_ARG_WITH([project-patch-level], [AS_HELP_STRING([--with-project-patch-level=VER], [GHC patchlevel version (default: 0)])], [ProjectPatchLevel="$withval"], [ProjectPatchLevel="0"]) AC_ARG_WITH([project-patch-level1], [AS_HELP_STRING([--with-project-patch-level1=VER], [GHC patchlevel1 version (default: 0)])], [ProjectPatchLevel1="$withval"], [ProjectPatchLevel1="0"]) AC_ARG_WITH([project-patch-level2], [AS_HELP_STRING([--with-project-patch-level2=VER], [GHC patchlevel2 version (default: 0)])], [ProjectPatchLevel2="$withval"], [ProjectPatchLevel2="0"]) +# Git commit ID (captured at configure time) +AC_ARG_WITH([project-git-commit-id], [AS_HELP_STRING([--with-project-git-commit-id=ID], [Git commit hash (default: auto-detect)])], + [ProjectGitCommitId="$withval"], [ProjectGitCommitId="$(git rev-parse HEAD 2>/dev/null || echo unknown)"]) + +# --- Platform Detection --- +# Auto-detect build machine's architecture and OS using uname, with override options +# These are used to generate GHC.Platform.Host module + +# Detect default architecture from uname -m +default_arch=$(uname -m 2>/dev/null || echo unknown) +# Normalize common variants +case "$default_arch" in + arm64) default_arch="aarch64" ;; + amd64) default_arch="x86_64" ;; +esac + +# Detect default OS from uname -s +default_os=$(uname -s 2>/dev/null | tr '[[A-Z]]' '[[a-z]]' || echo unknown) +# Normalize common variants +case "$default_os" in + darwin*) default_os="darwin" ;; + linux*) default_os="linux" ;; + mingw*|msys*|cygwin*) default_os="mingw32" ;; + freebsd*) default_os="freebsd" ;; +esac + +AC_ARG_WITH([target-arch], [AS_HELP_STRING([--with-target-arch=ARCH], [Target architecture (default: auto-detect from uname)])], + [TargetArch="$withval"], [TargetArch="$default_arch"]) +AC_ARG_WITH([target-os], [AS_HELP_STRING([--with-target-os=OS], [Target OS (default: auto-detect from uname)])], + [TargetOS="$withval"], [TargetOS="$default_os"]) + +# Shell functions to convert platform strings to Haskell types +# (Inline the relevant parts from m4/fptools_set_haskell_platform_vars.m4) +checkArch() { + case $[]1 in + i386) + test -z "$[]2" || eval "$[]2=ArchX86" + ;; + x86_64|amd64) + test -z "$[]2" || eval "$[]2=ArchX86_64" + ;; + powerpc) + test -z "$[]2" || eval "$[]2=ArchPPC" + ;; + powerpc64*) + test -z "$[]2" || eval "$[]2=\"ArchPPC_64 ELF_V2\"" + ;; + s390x) + test -z "$[]2" || eval "$[]2=ArchS390X" + ;; + arm) + test -z "$[]2" || eval "$[]2=\"ArchARM ARMv7 VFPv3D16 HARD\"" + ;; + aarch64) + test -z "$[]2" || eval "$[]2=ArchAArch64" + ;; + riscv64) + test -z "$[]2" || eval "$[]2=ArchRISCV64" + ;; + wasm32) + test -z "$[]2" || eval "$[]2=ArchWasm32" + ;; + loongarch64) + test -z "$[]2" || eval "$[]2=ArchLoongArch64" + ;; + javascript) + test -z "$[]2" || eval "$[]2=ArchJavaScript" + ;; + *) + test -z "$[]2" || eval "$[]2=ArchUnknown" + ;; + esac +} + +checkOS() { + case $[]1 in + linux|linux-android) + test -z "$[]2" || eval "$[]2=OSLinux" + ;; + darwin|ios|watchos|tvos) + test -z "$[]2" || eval "$[]2=OSDarwin" + ;; + solaris2) + test -z "$[]2" || eval "$[]2=OSSolaris2" + ;; + mingw32|mingw64|windows) + test -z "$[]2" || eval "$[]2=OSMinGW32" + ;; + freebsd) + test -z "$[]2" || eval "$[]2=OSFreeBSD" + ;; + dragonfly) + test -z "$[]2" || eval "$[]2=OSDragonFly" + ;; + openbsd) + test -z "$[]2" || eval "$[]2=OSOpenBSD" + ;; + netbsd) + test -z "$[]2" || eval "$[]2=OSNetBSD" + ;; + wasi) + test -z "$[]2" || eval "$[]2=OSWasi" + ;; + aix) + test -z "$[]2" || eval "$[]2=OSAIX" + ;; + gnu) + test -z "$[]2" || eval "$[]2=OSHurd" + ;; + ghcjs|js) + test -z "$[]2" || eval "$[]2=OSGhcjs" + ;; + *) + test -z "$[]2" || eval "$[]2=OSUnknown" + ;; + esac +} + +# Convert target platform strings to Haskell types +checkArch "$TargetArch" "HaskellTargetArch" +checkOS "$TargetOS" "HaskellTargetOs" + +AC_MSG_NOTICE([Target architecture: $TargetArch -> $HaskellTargetArch]) +AC_MSG_NOTICE([Target OS: $TargetOS -> $HaskellTargetOs]) + # Export these variables for substitution by AC_SUBST AC_SUBST([ProjectVersion]) AC_SUBST([ProjectVersionInt]) @@ -22,6 +147,11 @@ AC_SUBST([ProjectVersionForLib]) AC_SUBST([ProjectPatchLevel]) AC_SUBST([ProjectPatchLevel1]) AC_SUBST([ProjectPatchLevel2]) +AC_SUBST([ProjectGitCommitId]) +AC_SUBST([TargetArch]) +AC_SUBST([TargetOS]) +AC_SUBST([HaskellTargetArch]) +AC_SUBST([HaskellTargetOs]) # For ghc-boot-th.cabal.in AC_SUBST([Suffix],[""]) @@ -81,6 +211,8 @@ AC_CONFIG_FILES([ compiler/ghc.cabal compiler/GHC/CmmToLlvm/Version/Bounds.hs libraries/ghc-boot/ghc-boot.cabal + libraries/ghc-boot/GHC/Version.hs + libraries/ghc-boot/GHC/Platform/Host.hs libraries/ghc-boot-th/ghc-boot-th.cabal libraries/ghc-boot-th-next/ghc-boot-th-next.cabal libraries/ghc-heap/ghc-heap.cabal diff --git a/libraries/ghc-boot/GHC/Platform/Host.hs.in b/libraries/ghc-boot/GHC/Platform/Host.hs.in new file mode 100644 index 000000000000..87689d604799 --- /dev/null +++ b/libraries/ghc-boot/GHC/Platform/Host.hs.in @@ -0,0 +1,12 @@ +module GHC.Platform.Host where + +import GHC.Platform.ArchOS + +hostPlatformArch :: Arch +hostPlatformArch = @HaskellTargetArch@ + +hostPlatformOS :: OS +hostPlatformOS = @HaskellTargetOs@ + +hostPlatformArchOS :: ArchOS +hostPlatformArchOS = ArchOS hostPlatformArch hostPlatformOS diff --git a/libraries/ghc-boot/GHC/Version.hs.in b/libraries/ghc-boot/GHC/Version.hs.in new file mode 100644 index 000000000000..444940048ed4 --- /dev/null +++ b/libraries/ghc-boot/GHC/Version.hs.in @@ -0,0 +1,21 @@ +module GHC.Version where + +import Prelude -- See Note [Why do we import Prelude here?] + +cProjectGitCommitId :: String +cProjectGitCommitId = "@ProjectGitCommitId@" + +cProjectVersion :: String +cProjectVersion = "@ProjectVersion@" + +cProjectVersionInt :: String +cProjectVersionInt = "@ProjectVersionInt@" + +cProjectPatchLevel :: String +cProjectPatchLevel = "@ProjectPatchLevel@" + +cProjectPatchLevel1 :: String +cProjectPatchLevel1 = "@ProjectPatchLevel1@" + +cProjectPatchLevel2 :: String +cProjectPatchLevel2 = "@ProjectPatchLevel2@" diff --git a/libraries/ghc-boot/Setup.hs b/libraries/ghc-boot/Setup.hs index 715b7e553596..6489ec9aa20b 100644 --- a/libraries/ghc-boot/Setup.hs +++ b/libraries/ghc-boot/Setup.hs @@ -1,129 +1,11 @@ -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE CPP #-} +-- | Simple Setup.hs for ghc-boot +-- +-- GHC.Version and GHC.Platform.Host modules are now generated by ./configure +-- from their .in templates (Version.hs.in, Platform/Host.hs.in). +-- The HADRIAN_SETTINGS environment variable mechanism has been removed. module Main where import Distribution.Simple -import Distribution.Simple.BuildPaths -import Distribution.Types.LocalBuildInfo -import Distribution.Verbosity -import Distribution.Simple.Program -import Distribution.Simple.Utils -import Distribution.Simple.Setup -#if MIN_VERSION_Cabal(3,14,0) -import Distribution.Simple.LocalBuildInfo (interpretSymbolicPathLBI) -#endif - -import System.IO -import System.Directory -import System.FilePath -import System.Environment -import Control.Monad -import Data.Char -import GHC.ResponseFile main :: IO () -main = defaultMainWithHooks ghcHooks - where - ghcHooks = simpleUserHooks - { postConf = \args cfg pd lbi -> do - let verbosity = fromFlagOrDefault minBound (configVerbosity cfg) - ghcAutogen verbosity lbi - postConf simpleUserHooks args cfg pd lbi - } - -ghcAutogen :: Verbosity -> LocalBuildInfo -> IO () -ghcAutogen verbosity lbi@LocalBuildInfo{..} = do -#if MIN_VERSION_Cabal(3,14,0) - let fromSymPath = interpretSymbolicPathLBI lbi -#else - let fromSymPath = id -#endif - - -- Get compiler/ root directory from the cabal file - let Just compilerRoot = (takeDirectory . fromSymPath) <$> pkgDescrFile - - let platformHostFile = "GHC/Platform/Host.hs" - platformHostPath = fromSymPath (autogenPackageModulesDir lbi) platformHostFile - ghcVersionFile = "GHC/Version.hs" - ghcVersionPath = fromSymPath (autogenPackageModulesDir lbi) ghcVersionFile - - -- Get compiler settings - settings <- lookupEnv "HADRIAN_SETTINGS" >>= \case - Just settings -> pure $ Left $ read settings - Nothing -> do - (ghc,withPrograms) <- requireProgram normal ghcProgram withPrograms - Right . read <$> getProgramOutput normal ghc ["--info"] - - -- Write GHC.Platform.Host - createDirectoryIfMissingVerbose verbosity True (takeDirectory platformHostPath) - rewriteFileEx verbosity platformHostPath (generatePlatformHostHs settings) - - -- Write GHC.Version - createDirectoryIfMissingVerbose verbosity True (takeDirectory ghcVersionPath) - rewriteFileEx verbosity ghcVersionPath (generateVersionHs settings) - --- | Takes either a list of hadrian generated settings, or a list of settings from ghc --info, --- and keys in both lists, and looks up the value in the appropriate list -getSetting :: Either [(String,String)] [(String,String)] -> String -> String -> Either String String -getSetting settings kh kr = case settings of - Left settings -> go settings kh - Right settings -> go settings kr - where - go settings k = case lookup k settings of - Nothing -> Left (show k ++ " not found in settings: " ++ show settings) - Just v -> Right v - -generatePlatformHostHs :: Either [(String,String)] [(String,String)] -> String -generatePlatformHostHs settings = either error id $ do - let getSetting' = getSetting settings - cHostPlatformArch <- getSetting' "hostPlatformArch" "target arch" - cHostPlatformOS <- getSetting' "hostPlatformOS" "target os" - return $ unlines - [ "module GHC.Platform.Host where" - , "" - , "import GHC.Platform.ArchOS" - , "" - , "hostPlatformArch :: Arch" - , "hostPlatformArch = " ++ cHostPlatformArch - , "" - , "hostPlatformOS :: OS" - , "hostPlatformOS = " ++ cHostPlatformOS - , "" - , "hostPlatformArchOS :: ArchOS" - , "hostPlatformArchOS = ArchOS hostPlatformArch hostPlatformOS" - ] - -generateVersionHs :: Either [(String,String)] [(String,String)] -> String -generateVersionHs settings = either error id $ do - let getSetting' = getSetting settings - cProjectGitCommitId <- getSetting' "cProjectGitCommitId" "Project Git commit id" - cProjectVersion <- getSetting' "cProjectVersion" "Project version" - cProjectVersionInt <- getSetting' "cProjectVersionInt" "Project Version Int" - - cProjectPatchLevel <- getSetting' "cProjectPatchLevel" "Project Patch Level" - cProjectPatchLevel1 <- getSetting' "cProjectPatchLevel1" "Project Patch Level1" - cProjectPatchLevel2 <- getSetting' "cProjectPatchLevel2" "Project Patch Level2" - return $ unlines - [ "module GHC.Version where" - , "" - , "import Prelude -- See Note [Why do we import Prelude here?]" - , "" - , "cProjectGitCommitId :: String" - , "cProjectGitCommitId = " ++ show cProjectGitCommitId - , "" - , "cProjectVersion :: String" - , "cProjectVersion = " ++ show cProjectVersion - , "" - , "cProjectVersionInt :: String" - , "cProjectVersionInt = " ++ show cProjectVersionInt - , "" - , "cProjectPatchLevel :: String" - , "cProjectPatchLevel = " ++ show cProjectPatchLevel - , "" - , "cProjectPatchLevel1 :: String" - , "cProjectPatchLevel1 = " ++ show cProjectPatchLevel1 - , "" - , "cProjectPatchLevel2 :: String" - , "cProjectPatchLevel2 = " ++ show cProjectPatchLevel2 - ] +main = defaultMain diff --git a/libraries/ghc-boot/ghc-boot.cabal.in b/libraries/ghc-boot/ghc-boot.cabal.in index 9ccbcc81c76d..7e4cc7eef1b9 100644 --- a/libraries/ghc-boot/ghc-boot.cabal.in +++ b/libraries/ghc-boot/ghc-boot.cabal.in @@ -24,12 +24,9 @@ description: This library is shared between GHC, ghc-pkg, and other boot The package database format and this library are constructed in such a way that while ghc-pkg depends on Cabal, the GHC library and program do not have to depend on Cabal. -build-type: Custom +build-type: Simple extra-source-files: changelog.md -custom-setup - setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.18, directory, filepath - source-repository head type: git location: https://gitlab.haskell.org/ghc/ghc.git @@ -70,10 +67,8 @@ Library reexported-modules: GHC.Platform.ArchOS - -- but done by Hadrian - autogen-modules: - GHC.Version - GHC.Platform.Host + -- GHC.Version and GHC.Platform.Host are generated by ./configure + -- from their .in templates (no longer using autogen-modules) build-depends: base >= 4.7 && < 4.23, binary == 0.8.*,