From 9a3f8882b90d9d7f78af4b4b119207700abaebff Mon Sep 17 00:00:00 2001 From: Stable Haskell Team Date: Thu, 28 Aug 2025 20:19:26 +0900 Subject: [PATCH 1/3] feat: Implement cabal-based multi-stage build system This commit introduces a comprehensive cabal-based build infrastructure to support multi-target and cross-compilation scenarios for GHC. The new build system provides a clean separation between different build stages and better modularity for toolchain components. Key changes: - Add Makefile with stage1, stage2, and stage3 build targets - Create separate cabal.project files for each build stage - Update configure.ac for new build system requirements - Adapt hie.yaml to support cabal-based builds - Update GitHub CI workflow for new build process Build stages explained: - Stage 1: Bootstrap compiler built with system GHC - Stage 2: Intermediate compiler built with Stage 1 - Stage 3: Final compiler built with Stage 2 (for validation) This modular approach enables: - Clean cross-compilation support - Better dependency management - Simplified build process for different targets - Improved build reproducibility Contributors: - Andrea Bedini: Build system design and Makefile implementation - Moritz Angermann: Cross-compilation infrastructure The new build system maintains compatibility with existing workflows while providing a more maintainable foundation for future enhancements. --- .github/workflows/ci.yml | 62 +- Makefile | 940 ++++++++++++++++++++++++++++++ cabal.project.stage1 | 62 ++ cabal.project.stage2 | 187 ++++++ cabal.project.stage3 | 207 +++++++ configure.ac | 1169 ++------------------------------------ hie.yaml | 12 +- 7 files changed, 1496 insertions(+), 1143 deletions(-) create mode 100644 Makefile create mode 100644 cabal.project.stage1 create mode 100644 cabal.project.stage2 create mode 100644 cabal.project.stage3 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2b448f8ee8b..e60209cf40d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,43 +9,59 @@ on: push: branches: [master] + workflow_dispatch: + jobs: cabal: - name: ${{ matrix.os }} / ghc ${{ matrix.ghc }} - runs-on: ${{ matrix.os }} + name: ${{ matrix.plat }} / ghc ${{ matrix.ghc }} + runs-on: "${{ fromJSON('{\"x86_64-linux\": \"ubuntu-24.04\", \"aarch64-linux\": \"ubuntu-24.04-arm\", \"x86_64-darwin\": \"macos-latest\", \"aarch64-darwin\": \"macos-latest\"}')[matrix.plat] }}" + strategy: fail-fast: false matrix: - os: [ubuntu-latest] - ghc: ['9.6.5'] # bootstrapping compiler + plat: [x86_64-linux, aarch64-linux, x86_64-darwin, aarch64-darwin] + ghc: ['98'] # bootstrapping compiler steps: - uses: actions/checkout@v4 with: submodules: "recursive" - - uses: haskell-actions/setup@v2 - id: setup - name: Setup Haskell tools + - uses: input-output-hk/actions/devx@latest with: - ghc-version: ${{ matrix.ghc }} - cabal-version: "latest" - cabal-update: true + platform: ${{ matrix.plat }} + compiler-nix-name: 'ghc98' + minimal: true + ghc: true - - name: Install Alex and Happy - run: | - cabal install alex - cabal install happy + - name: Update hackage + shell: devx {0} + run: cabal update - name: Configure the build - run: | - ./boot - ./configure - - - name: Build Hadrian - run: | - ./hadrian/build --version + shell: devx {0} + run: ./configure - name: Build the bindist - run: | - ./hadrian/build --flavour=release -j binary-dist-dir --docs=none + shell: devx {0} + run: make CABAL=$PWD/_build/stage0/bin/cabal + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.plat }}-bindist + path: _build/bindist + + - name: Run the testsuite + shell: devx {0} + run: make test CABAL=$PWD/_build/stage0/bin/cabal + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} # upload test results even if the testsuite failed to pass + with: + name: testsuite-results + path: | + _build/test-perf.csv + _build/test-summary.txt + _build/test-junit.xml diff --git a/Makefile b/Makefile new file mode 100644 index 00000000000..95dc2641a63 --- /dev/null +++ b/Makefile @@ -0,0 +1,940 @@ +# Top-level Makefile +# +# This file is still _TOO_ large (should be < 100L). There are too many moving +# _global_ parts, most of this should be relegated to the respective packages. +# The whole version replacement therapy is utterly ridiculous. It should be done +# in the respective packages. + +# ┌─────────────────────────────────────────────────────────────────────────┐ +# │ GHC Bootstrapping Stages │ +# ├─────────────────────────────────────────────────────────────────────────┤ +# │ │ +# │ Stage 0 (Bootstrap) │ +# │ ┌─────────┐ ┌─────────┐ │ +# │ │ ghc0 │ │ pkg0 │ (initial boot packages) │ +# │ │ (binary)│ │ │ │ +# │ └────┬────┘ └────┬────┘ │ +# │ │ │ │ +# │ └───────┬───────┘ │ +# │ ▼ │ +# │ ┌─────────┐ │ +# │ │ pkg0+ │ (augmented boot packages) │ +# │ └────┬────┘ │ +# │ │ │ +# │ ············│························································· │ +# │ ▼ │ +# │ Stage 1 │ │ +# │ ┌─────────┐ │ │ +# │ │ ghc1 │◄┘ (built with ghc0, linked with rts0) │ +# │ │ │ │ +# │ └────┬────┘ │ +# │ │ │ +# │ │ ┌─────────┐ │ +# │ └────►│ pkg1 │ (initially empty, then populated) │ +# │ ┌─────│ │ (built with ghc1) │ +# │ │ └─────────┘ │ +# │ │ ▲ │ +# │ │ │ (mutual dependency; ghc1 needs to sees pkg1) │ +# │ ▼ │ │ +# │ ┌─────────┐ │ │ +# │ │ ghc1 │──────┘ │ +# │ │ (uses) │ │ +# │ └────┬────┘ │ +# │ │ │ +# │ ·····│································································ │ +# │ ▼ │ +# │ Stage 2 │ +# │ ┌─────────┐ ┌──────────┐ ┌─────────┐ │ +# │ │ ghc2 │ │ ghc-pkg2 │ │ ... │ │ +# │ │ │ │ │ │ │ │ +# │ └─────────┘ └──────────┘ └─────────┘ │ +# │ (built with ghc1, linked with rts1) │ +# │ │ +# │ ┌─────────────────────────────────┐ │ +# │ │ SHIPPED RESULT │ │ +# │ │ ┌─────────┐ ┌─────────┐ │ │ +# │ │ │ pkg1 │ + │ ghc2 │ │ │ +# │ │ └─────────┘ └─────────┘ │ │ +# │ └─────────────────────────────────┘ │ +# │ │ +# │ Notes: │ +# │ • Binaries: one stage ahead (ghc1 builds pkg1, ghc2 ships with pkg1) │ +# │ • Libraries: one stage below (pkg1 ships with ghc2) │ +# │ • ghc1 and ghc2 are ABI compatible | +# | • ghc0 and ghc1 are not guaruateed to be ABI compatible | +# │ • ghc1 is linked against rts0, ghc2 against rts1 │ +# | • augmented packages are needed because ghc1 may require newer | +# | versions or even new pacakges, not shipped with the boot compiler | +# │ │ +# └─────────────────────────────────────────────────────────────────────────┘ + + +# ISSUES: +# - [ ] 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. +# - [ ] The hadrian folder needs to be removed. +# - [ ] All sublibs should be SRPs in the relevant cabal.project files. No more +# submodules. + +SHELL := bash +.SHELLFLAGS := -eu -o pipefail -O globstar -c + +VERBOSE ?= 0 + +ROOT_DIR := $(patsubst %/,%,$(dir $(realpath $(lastword $(MAKEFILE_LIST))))) + +GHC0 ?= ghc-9.8.4 +PYTHON ?= python3 +CABAL ?= cabal + +LD ?= ld + +EMCC ?= emcc +EMCXX ?= em++ +EMAR ?= emar +EMRANLIB ?= emranlib + +EXTRA_LIB_DIRS ?= +EXTRA_INCLUDE_DIRS ?= + +MUSL_EXTRA_LIB_DIRS ?= +MUSL_EXTRA_INCLUDE_DIRS ?= + +JS_EXTRA_LIB_DIRS ?= +JS_EXTRA_INCLUDE_DIRS ?= + +WASM_EXTRA_LIB_DIRS ?= +WASM_EXTRA_INCLUDE_DIRS ?= +WASM_CC_OPTS = -fno-strict-aliasing -Wno-error=int-conversion -Oz -msimd128 -mnontrapping-fptoint -msign-ext -mbulk-memory -mmutable-globals -mmultivalue -mreference-types +WASM_CXX_OPTS = -fno-exceptions -fno-strict-aliasing -Wno-error=int-conversion -Oz -msimd128 -mnontrapping-fptoint -msign-ext -mbulk-memory -mmutable-globals -mmultivalue -mreference-types + +# :exploding-head: It turns out override doesn't override the command-line +# value but it overrides Make's normal behavior of ignoring assignments to +# command-line variables. This allows the += operations to append to whatever +# was passed from the command line. + +override CABAL_ARGS += \ + --remote-repo-cache _build/packages \ + --store-dir=_build/$(STAGE)/$(TARGET_PLATFORM)/store \ + --logs-dir=_build/$(STAGE)/logs + +override CABAL_BUILD_ARGS += \ + -j -w $(GHC) --with-gcc=$(CC) --with-ld=$(LD) \ + --project-file=cabal.project.$(STAGE) \ + $(foreach lib,$(EXTRA_LIB_DIRS),--extra-lib-dirs=$(lib)) \ + $(foreach include,$(EXTRA_INCLUDE_DIRS),--extra-include-dirs=$(include)) \ + --builddir=_build/$(STAGE)/$(TARGET_PLATFORM) \ + --ghc-options="-fhide-source-paths" + +GHC_TOOLCHAIN_ARGS ?= --disable-ld-override + +# just some defaults +STAGE ?= stage1 +GHC ?= $(GHC0) + +CABAL_BUILD = $(CABAL) $(CABAL_ARGS) build $(CABAL_BUILD_ARGS) + +GHC1 = _build/stage1/bin/ghc +GHC2 = _build/stage2/bin/ghc + +define GHC_INFO +$(shell sh -c "$(GHC) --info | $(GHC0) -e 'getContents >>= foldMap putStrLn . lookup \"$1\" . read'") +endef + +TARGET_PLATFORM = $(call GHC_INFO,target platform string) +TARGET_ARCH = $(call GHC_INFO,target arch) +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.13") \ +, ("cProjectVersionInt", "913") \ +, ("cProjectPatchLevel", "0") \ +, ("cProjectPatchLevel1", "0") \ +, ("cProjectPatchLevel2", "0") \ +] +endef + +# Handle CPUS and THREADS +CPUS_DETECT_SCRIPT := ./mk/detect-cpu-count.sh +CPUS := $(shell if [ -x $(CPUS_DETECT_SCRIPT) ]; then $(CPUS_DETECT_SCRIPT); else echo 2; fi) +THREADS ?= $(shell echo $$(( $(CPUS) + 1 ))) + +# Files that will be generated by config.status from their .in counterparts +# FIXME: This is stupid. Why do we patch versions across multiple libraries? Idiotic. +# also, why on earth do we use a non standard SnakeCase convention for substitutions +# when CAPITAL_CASE is the standard? +CONFIGURED_FILES := \ + ghc/ghc-bin.cabal \ + compiler/ghc.cabal \ + libraries/ghc-boot/ghc-boot.cabal \ + libraries/ghc-boot-th/ghc-boot-th.cabal \ + libraries/ghc-heap/ghc-heap.cabal \ + libraries/template-haskell/template-haskell.cabal \ + libraries/ghci/ghci.cabal \ + utils/ghc-pkg/ghc-pkg.cabal \ + utils/ghc-iserv/ghc-iserv.cabal \ + utils/runghc/runghc.cabal \ + libraries/ghc-internal/ghc-internal.cabal \ + libraries/ghc-experimental/ghc-experimental.cabal \ + libraries/base/base.cabal \ + rts/include/ghcversion.h + +# --- Main Targets --- +all: _build/bindist # booted will depend on prepare-sources + +STAGE_UTIL_TARGETS := \ + deriveConstants:deriveConstants \ + genapply:genapply \ + genprimopcode:genprimopcode \ + ghc-pkg:ghc-pkg \ + hsc2hs:hsc2hs \ + rts-headers:rts-headers \ + unlit:unlit + +STAGE1_TARGETS := $(STAGE_UTIL_TARGETS) ghc-bin:ghc ghc-toolchain-bin:ghc-toolchain-bin + +# TODO: dedup +STAGE1_EXECUTABLES := \ + deriveConstants \ + genapply \ + genprimopcode \ + ghc \ + ghc-pkg \ + ghc-toolchain-bin \ + hsc2hs \ + unlit + +# We really want to work towards `cabal build/instsall ghc-bin:ghc`. +STAGE2_TARGETS := \ + ghc-bin:ghc + +STAGE2_UTIL_TARGETS := \ + $(STAGE_UTIL_TARGETS) \ + ghc-iserv:ghc-iserv \ + rts:nonthreaded-debug \ + rts:nonthreaded-nodebug \ + hp2ps:hp2ps \ + hpc-bin:hpc \ + runghc:runghc \ + ghc-bignum:ghc-bignum \ + ghc-compact:ghc-compact \ + ghc-experimental:ghc-experimental \ + ghc-toolchain:ghc-toolchain \ + integer-gmp:integer-gmp \ + system-cxx-std-lib:system-cxx-std-lib \ + terminfo:terminfo \ + xhtml:xhtml + +# These things should be built on demand. +# hp2ps:hp2ps \ +# hpc-bin:hpc \ +# ghc-iserv:ghc-iserv \ +# runghc:runghc \ + +# This package is just utterly retarded +# I don't understand why this following line somehow breaks the build... +# STAGE2_TARGETS += system-cxx-std-lib:system-cxx-std-lib + +# TODO: dedup +STAGE2_EXECUTABLES := \ + ghc + +STAGE2_UTIL_EXECUTABLES := \ + deriveConstants \ + genapply \ + genprimopcode \ + hsc2hs \ + ghc-iserv \ + ghc-pkg \ + hp2ps \ + hpc \ + runghc \ + unlit + +BINDIST_EXECTUABLES := \ + ghc \ + ghc-iserv \ + ghc-pkg \ + hp2ps \ + hpc \ + hsc2hs \ + runghc + +STAGE3_LIBS := \ + rts:nonthreaded-nodebug \ + Cabal \ + Cabal-syntax \ + array \ + base \ + binary \ + bytestring \ + containers \ + deepseq \ + directory \ + exceptions \ + file-io \ + filepath \ + ghc-bignum \ + hpc \ + integer-gmp \ + mtl \ + os-string \ + parsec \ + pretty \ + process \ + stm \ + template-haskell \ + text \ + time \ + transformers \ + xhtml + +# --- Source headers --- +# TODO: this is a hack, because of https://github.com/haskell/cabal/issues/11172 +# +# $1 = headers +# $2 = source base dirs +# $3 = pkgname +# $4 = ghc-pkg +define copy_headers + set -e; \ + dest=`$4 field $3 include-dirs | awk '{ print $$2 }'` ;\ + for h in $1 ; do \ + mkdir -p "$$dest/`dirname $$h`" ; \ + for sdir in $2 ; do \ + if [ -e "$$sdir/$$h" ] ; then \ + cp -frp "$$sdir/$$h" "$$dest/$$h" ; \ + break ; \ + fi ; \ + done ; \ + [ -e "$$dest/$$h" ] || { echo "Copying $$dest/$$h failed... tried source dirs $2" >&2 ; exit 2 ; } ; \ + done +endef + +RTS_HEADERS_H := \ + rts/Bytecodes.h \ + rts/storage/ClosureTypes.h \ + rts/storage/FunTypes.h \ + stg/MachRegs.h \ + stg/MachRegs/arm32.h \ + stg/MachRegs/arm64.h \ + stg/MachRegs/loongarch64.h \ + stg/MachRegs/ppc.h \ + stg/MachRegs/riscv64.h \ + stg/MachRegs/s390x.h \ + stg/MachRegs/wasm32.h \ + stg/MachRegs/x86.h + +define copy_rts_headers_h + $(call copy_headers,$(RTS_HEADERS_H),rts-headers/include/,rts-headers,$1) +endef + +RTS_FS_H := \ + fs.h + +define copy_rts_fs_h + $(call copy_headers,$(RTS_FS_H),rts-fs/,rts-fs,$1) +endef + +RTS_H := \ + Cmm.h \ + HsFFI.h \ + MachDeps.h \ + Jumps.h \ + Rts.h \ + RtsAPI.h \ + RtsSymbols.h \ + Stg.h \ + ghcconfig.h \ + ghcversion.h \ + rts/ghc_ffi.h \ + rts/Adjustor.h \ + rts/ExecPage.h \ + rts/BlockSignals.h \ + rts/Config.h \ + rts/Constants.h \ + rts/EventLogFormat.h \ + rts/EventLogWriter.h \ + rts/FileLock.h \ + rts/Flags.h \ + rts/ForeignExports.h \ + rts/GetTime.h \ + rts/Globals.h \ + rts/Hpc.h \ + rts/IOInterface.h \ + rts/Libdw.h \ + rts/LibdwPool.h \ + rts/Linker.h \ + rts/Main.h \ + rts/Messages.h \ + rts/NonMoving.h \ + rts/OSThreads.h \ + rts/Parallel.h \ + rts/PrimFloat.h \ + rts/Profiling.h \ + rts/IPE.h \ + rts/PosixSource.h \ + rts/Signals.h \ + rts/SpinLock.h \ + rts/StableName.h \ + rts/StablePtr.h \ + rts/StaticPtrTable.h \ + rts/TTY.h \ + rts/Threads.h \ + rts/Ticky.h \ + rts/Time.h \ + rts/Timer.h \ + rts/TSANUtils.h \ + rts/Types.h \ + rts/Utils.h \ + rts/prof/CCS.h \ + rts/prof/Heap.h \ + rts/prof/LDV.h \ + rts/storage/Block.h \ + rts/storage/ClosureMacros.h \ + rts/storage/Closures.h \ + rts/storage/Heap.h \ + rts/storage/HeapAlloc.h \ + rts/storage/GC.h \ + rts/storage/InfoTables.h \ + rts/storage/MBlock.h \ + rts/storage/TSO.h \ + stg/DLL.h \ + stg/MiscClosures.h \ + stg/Prim.h \ + stg/Regs.h \ + stg/SMP.h \ + stg/Ticky.h \ + stg/Types.h + +RTS_H_DIRS := \ + rts/ \ + rts/include/ + +define copy_rts_h + $(call copy_headers,$(RTS_H),$(RTS_H_DIRS),rts,$1) +endef + +RTS_JS_H := \ + HsFFI.h \ + MachDeps.h \ + Rts.h \ + RtsAPI.h \ + Stg.h \ + ghcconfig.h \ + ghcversion.h \ + stg/MachRegsForHost.h \ + stg/Types.h + +define copy_rts_js_h + $(call copy_headers,$(RTS_JS_H),rts/include/,rts,$1) +endef + +HASKELINE_H := \ + win_console.h + +define copy_haskeline_h + $(call copy_headers,$(HASKELINE_H),libraries/haskeline/includes,haskeline,$1) +endef + +WIN32_H := \ + HsWin32.h \ + HsGDI.h \ + WndProc.h \ + windows_cconv.h \ + alphablend.h \ + wincon_compat.h \ + winternl_compat.h \ + winuser_compat.h \ + winreg_compat.h \ + tlhelp32_compat.h \ + winnls_compat.h \ + winnt_compat.h \ + namedpipeapi_compat.h + +define copy_win32_h + $(call copy_headers,$(WIN32_H),libraries/Win32/include/,Win32,$1) +endef + +GHC_INTERNAL_H := \ + HsBase.h \ + consUtils.h + +define copy_ghc_internal_h + $(call copy_headers,$(GHC_INTERNAL_H),libraries/ghc-internal/include/,ghc-internal,$1) +endef + +PROCESS_H := \ + runProcess.h \ + processFlags.h + +define copy_process_h + $(call copy_headers,$(PROCESS_H),libraries/process/include/,process,$1) +endef + +BYTESTRING_H := \ + fpstring.h \ + bytestring-cpp-macros.h + +define copy_bytestring_h + $(call copy_headers,$(BYTESTRING_H),libraries/bytestring/include/,bytestring,$1) +endef + +TIME_H := \ + HsTime.h + +define copy_time_h + $(call copy_headers,$(TIME_H),libraries/time/lib/include/,time,$1) +endef + +UNIX_H := \ + HsUnix.h \ + execvpe.h + +define copy_unix_h + $(call copy_headers,$(UNIX_H),libraries/unix/include/,unix,$1) +endef + +define copy_all_stage3_h + $(call copy_rts_headers_h,$1) + $(call copy_rts_fs_h,$1) + if [ "$2" = "javascript-unknown-ghcjs" ] ; then $(call copy_rts_js_h,$1) ; else $(call copy_rts_h,$1) ; fi + $(call copy_ghc_internal_h,$1) + $(call copy_process_h,$1) + $(call copy_bytestring_h,$1) + $(call copy_time_h,$1) + if [ "$(OS)" = "Windows_NT" ] ; then $(call copy_win32_h,$1) ; else $(call copy_unix_h,$1) ; fi +endef + +define copy_all_stage2_h + $(call copy_all_stage3_h,$1,none) + $(call copy_haskeline_h,$1) +endef + + +# --- Bootstrapping and stage 0 --- + +# export CABAL := $(shell cabal update 2>&1 >/dev/null && cabal build cabal-install -v0 --disable-tests --project-dir libraries/Cabal && cabal list-bin -v0 --project-dir libraries/Cabal cabal-install:exe:cabal) +$(abspath _build/stage0/bin/cabal): _build/stage0/bin/cabal + +# --- Stage 0 build --- + +# This just builds cabal-install, which is used to build the rest of the project. + +# We need an absolute path here otherwise cabal will consider the path relative to `the project directory +_build/stage0/bin/cabal: BUILD_ARGS=-j -w $(GHC0) --disable-tests --project-dir libraries/Cabal --builddir=$(abspath _build/stage0) --ghc-options="-fhide-source-paths" +_build/stage0/bin/cabal: + @echo "::group::Building Cabal..." + @mkdir -p _build/stage0/bin _build/logs + cabal build $(BUILD_ARGS) cabal-install:exe:cabal + cp -rfp $(shell cabal list-bin -v0 $(BUILD_ARGS) cabal-install:exe:cabal) _build/stage0/bin/cabal + @echo "::endgroup::" + +# --- Stage 1 build --- + +_build/stage1/%: private STAGE=stage1 +_build/stage1/%: private GHC=$(GHC0) + +.PHONY: $(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES)) +$(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES)) &: private TARGET_PLATFORM= +$(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES)) &: $(CABAL) | _build/booted + @echo "::group::Building stage1 executables ($(STAGE1_EXECUTABLES))..." + # Force cabal to replan + rm -rf _build/stage1/cache + HADRIAN_SETTINGS='$(HADRIAN_SETTINGS)' $(CABAL_BUILD) $(STAGE1_TARGETS) + @echo "::endgroup::" + +_build/stage1/lib/settings: _build/stage1/bin/ghc-toolchain-bin + @echo "::group::Creating settings for $(TARGET_TRIPLE)..." + @mkdir -p $(@D) + _build/stage1/bin/ghc-toolchain-bin $(GHC_TOOLCHAIN_ARGS) --triple $(TARGET_TRIPLE) --output-settings -o $@ --cc $(CC) --cxx $(CXX) + @echo "::endgroup::" + +# The somewhat strange thing is, we might not even need this at all now anymore. cabal seems to +# pass all the necessary flags correctly. Thus even with an _empty_ package-db here (and it will +# stay empty until we are done with the build), the build succeeds. +# +# For now, we are tying the knot here by making sure the stage1 compiler (stage1/bin/ghc) sees +# the packages it builds (to build stage2/bin/ghc), by symlining cabal's target package-db into +# the compilers global package-db. Another maybe even better solution might be to set the +# Global Package DB in the settings file to the absolute path where cabal will place the +# package db. This would elminate this rule outright. +_build/stage1/lib/package.conf.d/package.cache: _build/stage1/bin/ghc-pkg _build/stage1/lib/settings + @echo "::group::Creating stage1 package cache..." + @mkdir -p _build/stage1/lib/package.conf.d +# @mkdir -p _build/stage2/packagedb/host +# ln -s $(abspath ./_build/stage2/packagedb/host/ghc-9.13) _build/stage1/lib/package.conf.d +# _build/stage1/bin/ghc-pkg init $(abspath ./_build/stage2/packagedb/host/ghc-9.13) + @echo "::endgroup::" + +_build/stage1/lib/template-hsc.h: utils/hsc2hs/data/template-hsc.h + @mkdir -p $(@D) + cp -rfp $< $@ + +.PHONY: stage1 +stage1: $(addprefix _build/stage1/bin/,$(STAGE1_EXECUTABLES)) _build/stage1/lib/settings _build/stage1/lib/package.conf.d/package.cache _build/stage1/lib/template-hsc.h + +# --- Stage 2 build --- + +_build/stage2/%: private STAGE=stage2 +_build/stage2/%: private GHC=$(realpath _build/stage1/bin/ghc) + +.PHONY: $(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES)) +$(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES)) &: private TARGET_PLATFORM= +$(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) \ + $(CABAL_BUILD) --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" -W $(GHC0) $(STAGE2_TARGETS) + @echo "::endgroup::" + +# Do we want to build these with the stage2 GHC or the stage1 GHC? +# Traditionally we build them with the stage1 ghc, but we could just as well +# build them with the stage2 ghc; seems like a better/cleaner idea to me (moritz). +.PHONY: $(addprefix _build/stage2/bin/,$(STAGE2_UTIL_EXECUTABLES)) +$(addprefix _build/stage2/bin/,$(STAGE2_UTIL_EXECUTABLES)) &: private TARGET_PLATFORM= +$(addprefix _build/stage2/bin/,$(STAGE2_UTIL_EXECUTABLES)) &: $(CABAL) stage1 + @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) \ + $(CABAL_BUILD) --ghc-options="-ghcversion-file=$(abspath ./rts/include/ghcversion.h)" -W $(GHC0) $(STAGE2_UTIL_TARGETS) + @echo "::endgroup::" + +_build/stage2/lib/settings: _build/stage1/lib/settings + @mkdir -p $(@D) + cp -rfp _build/stage1/lib/settings _build/stage2/lib/settings + +_build/stage2/lib/package.conf.d/package.cache: _build/stage2/bin/ghc-pkg _build/stage2/lib/settings + @echo "::group::Creating stage2 package cache..." + @mkdir -p _build/stage2/lib/package.conf.d + @rm -rf _build/stage2/lib/package.conf.d/* + cp -rfp _build/stage2/packagedb/host/*/* _build/stage2/lib/package.conf.d + _build/stage2/bin/ghc-pkg recache + @echo "::endgroup::" + +_build/stage2/lib/template-hsc.h: utils/hsc2hs/data/template-hsc.h + @mkdir -p $(@D) + cp -rfp $< $@ + +.PHONY: stage2 +stage2: $(addprefix _build/stage2/bin/,$(STAGE2_EXECUTABLES)) _build/stage2/lib/settings _build/stage2/lib/package.conf.d/package.cache _build/stage2/lib/template-hsc.h + +# --- Stage 3 generic --- + +_build/stage3/lib/targets/%: + @mkdir -p $@ + @mkdir -p _build/stage2/lib/targets/ + @ln -sf ../../../stage3/lib/targets/$(@F) _build/stage2/lib/targets/$(@F) + +_build/stage3/bin/%-ghc-pkg: _build/stage2/bin/ghc-pkg + @mkdir -p $(@D) + @ln -sf ../../stage2/bin/ghc-pkg $@ + +_build/stage3/bin/%-ghc: _build/stage2/bin/ghc + @mkdir -p $(@D) + @ln -sf ../../stage2/bin/ghc $@ + +_build/stage3/bin/%-hsc2hs: _build/stage2/bin/hsc2hs + @mkdir -p $(@D) + @ln -sf ../../stage2/bin/hsc2hs $@ + +_build/stage3/lib/targets/%/lib/package.conf.d: _build/stage3/lib/targets/% + @mkdir -p $@ + +# ghc-toolchain borks unlit +_build/stage3/lib/targets/%/bin/unlit: _build/stage2/bin/unlit + @mkdir -p $(@D) + cp -rfp $< $@ + +# $1 = TIPLET +define build_cross + HADRIAN_SETTINGS='$(call HADRIAN_SETTINGS)' \ + 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)) \ + $(STAGE3_LIBS) +endef + +# --- Stage 3 javascript build --- + +.PHONY: stage3-javascript-unknown-ghcjs +stage3-javascript-unknown-ghcjs: _build/stage3/lib/targets/javascript-unknown-ghcjs/lib/settings javascript-unknown-ghcjs-libs _build/stage3/lib/targets/javascript-unknown-ghcjs/lib/package.conf.d/package.cache + +_build/stage3/lib/targets/javascript-unknown-ghcjs/lib/settings: _build/stage3/lib/targets/javascript-unknown-ghcjs _build/stage1/bin/ghc-toolchain-bin + @mkdir -p $(@D) + _build/stage1/bin/ghc-toolchain-bin $(GHC_TOOLCHAIN_ARGS) --triple javascript-unknown-ghcjs --output-settings -o $@ --cc $(EMCC) --cxx $(EMCXX) --ar $(EMAR) --ranlib $(EMRANLIB) + +_build/stage3/lib/targets/javascript-unknown-ghcjs/lib/package.conf.d/package.cache: _build/stage3/bin/javascript-unknown-ghcjs-ghc-pkg _build/stage3/lib/targets/javascript-unknown-ghcjs/lib/settings javascript-unknown-ghcjs-libs + @mkdir -p $(@D) + @rm -rf $(@D)/* + cp -rfp _build/stage3/javascript-unknown-ghcjs/packagedb/host/*/* $(@D) + _build/stage3/bin/javascript-unknown-ghcjs-ghc-pkg recache + +.PHONY: javascript-unknown-ghcjs-libs +javascript-unknown-ghcjs-libs: private GHC=$(abspath _build/stage3/bin/javascript-unknown-ghcjs-ghc) +javascript-unknown-ghcjs-libs: private GHC2=$(abspath _build/stage2/bin/ghc) +javascript-unknown-ghcjs-libs: private STAGE=stage3 +javascript-unknown-ghcjs-libs: private CC=emcc +javascript-unknown-ghcjs-libs: private CROSS_EXTRA_LIB_DIRS=$(JS_EXTRA_LIB_DIRS) +javascript-unknown-ghcjs-libs: private CROSS_EXTRA_INCLUDE_DIRS=$(JS_EXTRA_INCLUDE_DIRS) +javascript-unknown-ghcjs-libs: _build/stage3/bin/javascript-unknown-ghcjs-ghc-pkg _build/stage3/bin/javascript-unknown-ghcjs-ghc _build/stage3/bin/javascript-unknown-ghcjs-hsc2hs _build/stage3/lib/targets/javascript-unknown-ghcjs/lib/settings _build/stage3/lib/targets/javascript-unknown-ghcjs/bin/unlit _build/stage3/lib/targets/javascript-unknown-ghcjs/lib/package.conf.d + $(call build_cross,javascript-unknown-ghcjs) + +# --- Stage 3 musl build --- + +.PHONY: stage3-x86_64-musl-linux +stage3-x86_64-musl-linux: x86_64-musl-linux-libs _build/stage3/lib/targets/x86_64-musl-linux/lib/package.conf.d/package.cache + +_build/stage3/lib/targets/x86_64-musl-linux/lib/settings: _build/stage3/lib/targets/x86_64-musl-linux _build/stage1/bin/ghc-toolchain-bin + @mkdir -p $(@D) + _build/stage1/bin/ghc-toolchain-bin $(GHC_TOOLCHAIN_ARGS) --triple x86_64-musl-linux --output-settings -o $@ --cc x86_64-unknown-linux-musl-cc --cxx x86_64-unknown-linux-musl-c++ --ar x86_64-unknown-linux-musl-ar --ranlib x86_64-unknown-linux-musl-ranlib --ld x86_64-unknown-linux-musl-ld + +_build/stage3/lib/targets/x86_64-musl-linux/lib/package.conf.d/package.cache: _build/stage3/bin/x86_64-musl-linux-ghc-pkg _build/stage3/lib/targets/x86_64-musl-linux/lib/settings x86_64-musl-linux-libs + @mkdir -p $(@D) + @rm -rf $(@D)/* + cp -rfp _build/stage3/x86_64-musl-linux/packagedb/host/*/* $(@D) + _build/stage3/bin/x86_64-musl-linux-ghc-pkg recache + +.PHONY: x86_64-musl-linux-libs +x86_64-musl-linux-libs: private GHC=$(abspath _build/stage3/bin/x86_64-musl-linux-ghc) +x86_64-musl-linux-libs: private GHC2=$(abspath _build/stage2/bin/ghc) +x86_64-musl-linux-libs: private STAGE=stage3 +x86_64-musl-linux-libs: private CC=x86_64-unknown-linux-musl-cc +x86_64-musl-linux-libs: private CROSS_EXTRA_LIB_DIRS=$(MUSL_EXTRA_LIB_DIRS) +x86_64-musl-linux-libs: private CROSS_EXTRA_INCLUDE_DIRS=$(MUSL_EXTRA_INCLUDE_DIRS) +x86_64-musl-linux-libs: _build/stage3/bin/x86_64-musl-linux-ghc-pkg _build/stage3/bin/x86_64-musl-linux-ghc _build/stage3/bin/x86_64-musl-linux-hsc2hs _build/stage3/lib/targets/x86_64-musl-linux/lib/settings _build/stage3/lib/targets/x86_64-musl-linux/bin/unlit _build/stage3/lib/targets/x86_64-musl-linux/lib/package.conf.d + $(call build_cross,x86_64-musl-linux) + +# --- Stage 3 wasm build --- + +.PHONY: stage3-wasm32-unknown-wasi +stage3-wasm32-unknown-wasi: wasm32-unknown-wasi-libs _build/stage3/lib/targets/wasm32-unknown-wasi/lib/package.conf.d/package.cache _build/stage3/lib/targets/wasm32-unknown-wasi/lib/dyld.mjs _build/stage3/lib/targets/wasm32-unknown-wasi/lib/post-link.mjs _build/stage3/lib/targets/wasm32-unknown-wasi/lib/prelude.mjs + +_build/stage3/lib/targets/wasm32-unknown-wasi/lib/settings: _build/stage3/lib/targets/wasm32-unknown-wasi _build/stage1/bin/ghc-toolchain-bin + @mkdir -p $(@D) + PATH=/home/hasufell/.ghc-wasm/wasi-sdk/bin:$(PATH) _build/stage1/bin/ghc-toolchain-bin $(GHC_TOOLCHAIN_ARGS) --triple wasm32-unknown-wasi --output-settings -o $@ --cc wasm32-wasi-clang --cxx wasm32-wasi-clang++ --ar ar --ranlib ranlib --ld wasm-ld --merge-objs wasm-ld --merge-objs-opt="-r" --disable-ld-override --disable-tables-next-to-code $(foreach opt,$(WASM_CC_OPTS),--cc-opt=$(opt)) $(foreach opt,$(WASM_CXX_OPTS),--cxx-opt=$(opt)) + +_build/stage3/lib/targets/wasm32-unknown-wasi/lib/package.conf.d/package.cache: _build/stage3/bin/wasm32-unknown-wasi-ghc-pkg _build/stage3/lib/targets/wasm32-unknown-wasi/lib/settings wasm32-unknown-wasi-libs + @mkdir -p $(@D) + @rm -rf $(@D)/* + cp -rfp _build/stage3/wasm32-unknown-wasi/packagedb/host/*/* $(@D) + _build/stage3/bin/wasm32-unknown-wasi-ghc-pkg recache + +# ghc-toolchain borks unlit +_build/stage3/lib/targets/wasm32-unknown-wasi/bin/unlit: _build/stage2/bin/unlit + @mkdir -p $(@D) + cp -rfp $< $@ + +.PHONY: wasm32-unknown-wasi-libs +wasm32-unknown-wasi-libs: private GHC=$(abspath _build/stage3/bin/wasm32-unknown-wasi-ghc) +wasm32-unknown-wasi-libs: private GHC2=$(abspath _build/stage2/bin/ghc) +wasm32-unknown-wasi-libs: private STAGE=stage3 +wasm32-unknown-wasi-libs: private CC=wasm32-wasi-clang +wasm32-unknown-wasi-libs: private CROSS_EXTRA_LIB_DIRS=$(WASM_EXTRA_LIB_DIRS) +wasm32-unknown-wasi-libs: private CROSS_EXTRA_INCLUDE_DIRS=$(WASM_EXTRA_INCLUDE_DIRS) +wasm32-unknown-wasi-libs: _build/stage3/bin/wasm32-unknown-wasi-ghc-pkg _build/stage3/bin/wasm32-unknown-wasi-ghc _build/stage3/bin/wasm32-unknown-wasi-hsc2hs _build/stage3/lib/targets/wasm32-unknown-wasi/lib/settings _build/stage3/lib/targets/wasm32-unknown-wasi/bin/unlit _build/stage3/lib/targets/wasm32-unknown-wasi/lib/package.conf.d + $(call build_cross,wasm32-unknown-wasi) + +_build/stage3/lib/targets/wasm32-unknown-wasi/lib/dyld.mjs: + @mkdir -p $(@D) + @cp -f utils/jsffi/dyld.mjs $@ + @chmod +x $@ + +_build/stage3/lib/targets/wasm32-unknown-wasi/lib/post-link.mjs: + @mkdir -p $(@D) + @cp -f utils/jsffi/post-link.mjs $@ + @chmod +x $@ + +_build/stage3/lib/targets/wasm32-unknown-wasi/lib/prelude.mjs: + @mkdir -p $(@D) + @cp -f utils/jsffi/prelude.mjs $@ + @chmod +x $@ + +_build/stage3/lib/targets/wasm32-unknown-wasi/lib/ghc-interp.js: + @mkdir -p $(@D) + @cp -f ghc-interp.js $@ + +# --- Bindist --- + +# patchpackageconf +# +# Hacky function to patch up the paths in the package .conf files +# +# $1 = package name (ex: 'bytestring') +# $2 = path to .conf file +# $3 = (relative) path from $${pkgroot} to docs directory +# $4 = host triple +# $5 = package name and version (ex: bytestring-0.13) +# +define patchpackageconf + sed -i \ + -e "s|haddock-interfaces:.*|haddock-interfaces: \"\$${pkgroot}/$3/html/libraries/$5/$1.haddock\"|" \ + -e "s|haddock-html:.*|haddock-html: \"\$${pkgroot}/$3/html/libraries/$5\"|" \ + -e "s|import-dirs:.*|import-dirs: \"\$${pkgroot}/../lib/$4/$5\"|" \ + -e "s|library-dirs:.*|library-dirs: \"\$${pkgroot}/../lib/$4/$5\"|" \ + -e "s|library-dirs-static:.*|library-dirs-static: \"\$${pkgroot}/../lib/$4/$5\"|" \ + -e "s|dynamic-library-dirs:.*|dynamic-library-dirs: \"\$${pkgroot}/../lib/$4\"|" \ + -e "s|data-dir:.*|data-dir: \"\$${pkgroot}/../lib/$4/$5\"|" \ + -e "s|include-dirs:.*|include-dirs: \"\$${pkgroot}/../lib/$4/$5/include\"|" \ + -e "s|^ $(CURDIR).*||" \ + $2 +endef + +# $1 = triplet +define copycrosslib + @cp -rfp _build/stage3/lib/targets/$1 _build/bindist/lib/targets/ + @cd _build/bindist/lib/targets/$1/lib/package.conf.d ; \ + for pkg in *.conf ; do \ + pkgname=`echo $${pkg} | sed 's/-[0-9.]*\(-[0-9a-zA-Z]*\)\?\.conf//'` ; \ + pkgnamever=`echo $${pkg} | sed 's/\.conf//'` ; \ + mkdir -p $(CURDIR)/_build/bindist/lib/targets/$1/lib/$1/$${pkg%.conf} && \ + cp -rfp $(CURDIR)/_build/stage3/$1/build/host/*/ghc-*/$${pkg%.conf}/build/* $(CURDIR)/_build/bindist/lib/targets/$1/lib/$1/$${pkg%.conf}/ && \ + $(call patchpackageconf,$${pkgname},$${pkg},../../..,$1,$${pkgnamever}) ; \ + done +endef + +# Target for creating the final binary distribution directory +#_build/bindist: stage2 driver/ghc-usage.txt driver/ghci-usage.txt +_build/bindist: stage2 driver/ghc-usage.txt driver/ghci-usage.txt + @echo "::group::Creating binary distribution in $@" + @mkdir -p $@/bin + @mkdir -p $@/lib + # Copy executables from stage2 bin + @cp -rfp _build/stage2/bin/* $@/bin/ + # Copy libraries and settings from stage2 lib + @cp -rfp _build/stage2/lib/{package.conf.d,settings,template-hsc.h} $@/lib/ + @mkdir -p $@/lib/x86_64-linux + @cd $@/lib/package.conf.d ; \ + for pkg in *.conf ; do \ + pkgname=`echo $${pkg} | sed 's/-[0-9.]*\(-[0-9a-zA-Z]*\)\?\.conf//'` ; \ + pkgnamever=`echo $${pkg} | sed 's/\.conf//'` ; \ + mkdir -p $(CURDIR)/$@/lib/x86_64-linux/$${pkg%.conf} ; \ + cp -rfp $(CURDIR)/_build/stage2/build/host/x86_64-linux/ghc-*/$${pkg%.conf}/build/* $(CURDIR)/$@/lib/x86_64-linux/$${pkg%.conf} ; \ + $(call patchpackageconf,$${pkgname},$${pkg},../../..,x86_64-linux,$${pkgnamever}) ; \ + done + # Copy driver usage files + @cp -rfp driver/ghc-usage.txt $@/lib/ + @cp -rfp driver/ghci-usage.txt $@/lib/ + @echo "FIXME: Changing 'Support SMP' from YES to NO in settings file" + @sed 's/("Support SMP","YES")/("Support SMP","NO")/' -i.bck $@/lib/settings + # Recache + $@/bin/ghc-pkg recache + # Copy headers + @$(call copy_all_stage2_h,$@/bin/ghc-pkg) + @echo "::endgroup::" + +_build/bindist/ghc.tar.gz: _build/bindist + @tar czf $@ \ + --directory=_build/bindist \ + $(foreach exe,$(BINDIST_EXECTUABLES),bin/$(exe)) \ + lib/ghc-usage.txt \ + lib/ghci-usage.txt \ + lib/package.conf.d \ + lib/settings \ + lib/template-hsc.h \ + lib/x86_64-linux + +_build/bindist/lib/targets/%: _build/bindist driver/ghc-usage.txt driver/ghci-usage.txt stage3-% + @echo "::group::Creating binary distribution in $@" + @mkdir -p _build/bindist/bin + @mkdir -p _build/bindist/lib/targets + # Symlinks + @cd _build/bindist/bin ; for binary in * ; do \ + test -L $$binary || ln -sf $$binary $(@F)-$$binary \ + ; done + # Copy libraries and settings + @if [ -e $(CURDIR)/_build/bindist/lib/targets/$(@F)/lib/$(@F) ] ; then find $(CURDIR)/_build/bindist/lib/targets/$(@F)/lib/$(@F)/ -mindepth 1 -type f -name "*.so" -execdir mv '{}' $(CURDIR)/_build/bindist/lib/targets/$(@F)/lib/$(@F)/'{}' \; ; fi + $(call copycrosslib,$(@F)) + # --help + @cp -rfp driver/ghc-usage.txt _build/bindist/lib/targets/$(@F)/lib/ + @cp -rfp driver/ghci-usage.txt _build/bindist/lib/targets/$(@F)/lib/ + # Recache + @_build/bindist/bin/$(@F)-ghc-pkg recache + # Copy headers + @$(call copy_all_stage3_h,_build/bindist/bin/$(@F)-ghc-pkg,$(@F)) + @echo "::endgroup::" + +_build/bindist/ghc-%.tar.gz: _build/bindist/lib/targets/% _build/bindist/ghc.tar.gz + @triple=`basename $<` ; \ + tar czf $@ \ + --directory=_build/bindist \ + $(foreach exe,$(BINDIST_EXECTUABLES),bin/$${triple}-$(exe)) \ + lib/targets/$${triple} + + +# --- Configuration --- + +$(GHC1) $(GHC2): | hackage +hackage: _build/packages/hackage.haskell.org/01-index.tar.gz +_build/packages/hackage.haskell.org/01-index.tar.gz: | $(CABAL) + @mkdir -p $(@D) + $(CABAL) $(CABAL_ARGS) update --index-state 2025-04-22T01:25:40Z + +# booted depends on successful source preparation +_build/booted: + @echo "::group::Running ./boot script..." + @mkdir -p _build/logs + ./boot |& tee _build/logs/boot.log + @echo ">>> Running ./configure script..." + ./configure + touch $@ + @echo "::endgroup::" + +# --- Clean Targets --- +clean: + @echo "::group::Cleaning build artifacts..." + rm -rf _build + @echo "::endgroup::" + +clean-stage1: + @echo "::group::Cleaning stage1 build artifacts..." + rm -rf _build/stage1 + @echo "::endgroup::" + +clean-stage2: + @echo "::group::Cleaning stage2 build artifacts..." + rm -rf _build/stage2 + @echo "::endgroup::" + +clean-stage3: + @echo "::group::Cleaning stage3 build artifacts..." + rm -rf _build/stage3 + rm -rf _build/stage2/lib/targets + @echo "::endgroup::" + +distclean: clean + @echo "::group::Cleaning all generated files (distclean)..." + rm -rf autom4te.cache + rm -f config.status config.log config.h configure aclocal.m4 + rm -rf build-aux/config.guess build-aux/config.sub build-aux/install-sh build-aux/missing build-aux/compile depcomp + find . -name 'Makefile.in' -delete + rm -f $(CONFIGURED_FILES) + @echo "::endgroup::" + + +# --- Test Target --- +test: _build/bindist + @echo "::group::Running tests with THREADS=${THREADS}" >&2 + TEST_HC=`pwd`/_build/bindist/bin/ghc \ + TEST_CC=$(CC) \ + TEST_CXX=$(CXX) \ + METRICS_FILE=`pwd`/_build/test-perf.csv \ + SUMMARY_FILE=`pwd`/_build/test-summary.txt \ + JUNIT_FILE=`pwd`/_build/test-junit.xml \ + make -C testsuite/tests test THREADS=${THREADS} + @echo "::endgroup::" + +# Inform Make that these are not actual files if they get deleted by other means +.PHONY: clean clean-stage1 clean-stage2 clean-stage3 distclean test all configure diff --git a/cabal.project.stage1 b/cabal.project.stage1 new file mode 100644 index 00000000000..eac8c10a20e --- /dev/null +++ b/cabal.project.stage1 @@ -0,0 +1,62 @@ +packages: + -- NOTE: we need rts-headers, because the _newly_ built compiler depends + -- on these potentially _new_ headers, we must not rely on those from + -- the rts as shipped with the bootstrap compiler. For the stage2 + -- compiler we have the `rts` available, which would have the correct + -- headers around, now it has them through the rts -> rts-headers + -- dependency. + rts-headers + rts-fs + + -- other packages. + ghc + compiler + libraries/directory + libraries/file-io + libraries/filepath + libraries/ghc-platform + libraries/ghc-boot + libraries/ghc-boot-th + libraries/ghc-heap + libraries/ghci + libraries/os-string + libraries/process + libraries/semaphore-compat + libraries/time + libraries/unix + libraries/Win32 + libraries/Cabal/Cabal-syntax + libraries/Cabal/Cabal + utils/ghc-pkg + utils/hsc2hs + utils/unlit + utils/genprimopcode + utils/genapply + utils/deriveConstants + utils/ghc-toolchain + utils/ghc-toolchain/exe + +benchmarks: False +tests: False +allow-boot-library-installs: True + +package * + library-vanilla: True + shared: False + executable-profiling: False + executable-dynamic: False + executable-static: False + +package ghc-boot-th + flags: +bootstrap + +package hsc2hs + flags: +in-ghc-tree + +allow-newer: ghc-boot-th + +constraints: + template-haskell <= 2.22 + +program-options + ghc-options: -fhide-source-paths -j diff --git a/cabal.project.stage2 b/cabal.project.stage2 new file mode 100644 index 00000000000..e9160f0a5ac --- /dev/null +++ b/cabal.project.stage2 @@ -0,0 +1,187 @@ +package-dbs: clear, global + +packages: + rts-headers + rts-fs + rts + + libraries/ghc-prim + libraries/ghc-internal + libraries/ghc-experimental + libraries/base + compiler + ghc + libraries/ghc-platform + libraries/ghc-compact + libraries/ghc-bignum + libraries/integer-gmp + libraries/ghc-boot + libraries/ghc-boot-th + libraries/ghc-heap + libraries/ghci + libraries/stm + libraries/template-haskell + libraries/hpc + libraries/system-cxx-std-lib + libraries/array + libraries/binary + libraries/bytestring + libraries/containers/containers + libraries/deepseq + libraries/directory + libraries/exceptions + libraries/file-io + libraries/filepath + libraries/mtl + libraries/os-string + libraries/parsec + libraries/pretty + libraries/process + libraries/semaphore-compat + libraries/text + libraries/time + libraries/transformers + libraries/unix + libraries/xhtml + libraries/Win32 + + libraries/Cabal/Cabal-syntax + libraries/Cabal/Cabal + https://hackage.haskell.org/package/alex-3.5.2.0/alex-3.5.2.0.tar.gz + https://hackage.haskell.org/package/happy-2.1.5/happy-2.1.5.tar.gz + https://hackage.haskell.org/package/happy-lib-2.1.5/happy-lib-2.1.5.tar.gz + + utils/genprimopcode + utils/deriveConstants + utils/ghc-pkg + utils/hsc2hs + utils/unlit + utils/ghc-toolchain + + libraries/haskeline + libraries/terminfo + utils/hp2ps + utils/hpc + utils/ghc-iserv + utils/genapply + utils/runghc + +-- project-rts +benchmarks: False +tests: False +allow-boot-library-installs: True +active-repositories: :none + +constraints: + -- we do not want to use the rts-headers from stage1 + rts-headers source, rts-fs source + -- All build dependencies should be installed, i.e. from stage1. + -- I cannot write build:* but ghc-internal is enough to do the job. + , build:any.ghc-internal installed + +package * + library-vanilla: True + shared: False + executable-profiling: False + executable-dynamic: False + executable-static: False + +-- Maybe we should fix this with some import +if os(linux) + package rts + ghc-options: "-optc-DProjectVersion=\"913\"" + ghc-options: "-optc-DRtsWay=\"v\"" + ghc-options: "-optc-DHostPlatform=\"x86_64-unknown-linux\"" + ghc-options: "-optc-DHostArch=\"x86_64\"" + ghc-options: "-optc-DHostOS=\"linux\"" + ghc-options: "-optc-DHostVendor=\"unknown\"" + ghc-options: "-optc-DBuildPlatform=\"FIXME\"" + ghc-options: "-optc-DBuildArch=\"FIXME\"" + ghc-options: "-optc-DBuildOS=\"FIXME\"" + ghc-options: "-optc-DBuildVendor=\"FIXME\"" + ghc-options: "-optc-DGhcUnregisterised=\"FIXME\"" + ghc-options: "-optc-DTablesNextToCode=\"FIXME\"" + ghc-options: "-optc-DFS_NAMESPACE=rts" + flags: +tables-next-to-code + +if os(darwin) + package rts + ghc-options: "-optc-DProjectVersion=\"913\"" + ghc-options: "-optc-DRtsWay=\"v\"" + ghc-options: "-optc-DHostPlatform=\"aarch64-apple-darwin\"" + ghc-options: "-optc-DHostArch=\"aarch64\"" + ghc-options: "-optc-DHostOS=\"darwin\"" + ghc-options: "-optc-DHostVendor=\"unknown\"" + ghc-options: "-optc-DBuildPlatform=\"FIXME\"" + ghc-options: "-optc-DBuildArch=\"FIXME\"" + ghc-options: "-optc-DBuildOS=\"FIXME\"" + ghc-options: "-optc-DBuildVendor=\"FIXME\"" + ghc-options: "-optc-DGhcUnregisterised=\"FIXME\"" + ghc-options: "-optc-DTablesNextToCode=\"FIXME\"" + ghc-options: "-optc-DFS_NAMESPACE=rts" + flags: +tables-next-to-code +leading-underscore + + +program-options + ghc-options: -fhide-source-paths -j + +-- project-boot-libs +benchmarks: False +tests: False +allow-boot-library-installs: True +active-repositories: :none + +package * + library-vanilla: True + shared: False + executable-profiling: False + executable-dynamic: False + executable-static: False + +package rts-headers + ghc-options: -no-rts + +package rts-fs + ghc-options: -no-rts + +package rts + ghc-options: -no-rts + +package ghc + flags: +build-tool-depends +internal-interpreter + +package ghci + flags: +internal-interpreter + +package ghc-internal + flags: +bignum-native + +package text + flags: -simdutf + +program-options + ghc-options: -fhide-source-paths -j + +-- project-ghc +benchmarks: False +tests: False + +package * + library-vanilla: True + shared: False + executable-profiling: False + executable-dynamic: False + executable-static: False + +package ghc-bin + flags: +internal-interpreter -threaded + +package hsc2hs + flags: +in-ghc-tree + +package haskeline + flags: -terminfo + + +program-options + ghc-options: -fhide-source-paths -j diff --git a/cabal.project.stage3 b/cabal.project.stage3 new file mode 100644 index 00000000000..136ce252917 --- /dev/null +++ b/cabal.project.stage3 @@ -0,0 +1,207 @@ +package-dbs: clear, global + + +packages: + rts-headers + rts-fs + rts + + libraries/ghc-prim + libraries/ghc-internal + libraries/ghc-experimental + libraries/base + compiler + libraries/ghc-platform + libraries/ghc-compact + libraries/ghc-bignum + libraries/integer-gmp + libraries/ghc-boot + libraries/ghc-boot-th + libraries/ghc-heap + libraries/ghci + libraries/stm + libraries/template-haskell + libraries/hpc + libraries/system-cxx-std-lib + libraries/array + libraries/binary + libraries/bytestring + libraries/containers/containers + libraries/deepseq + libraries/directory + libraries/exceptions + libraries/file-io + libraries/filepath + libraries/mtl + libraries/os-string + libraries/parsec + libraries/pretty + libraries/process + libraries/semaphore-compat + libraries/text + libraries/time + libraries/transformers + libraries/unix + libraries/xhtml + libraries/Win32 + + libraries/Cabal/Cabal-syntax + libraries/Cabal/Cabal + https://hackage.haskell.org/package/alex-3.5.2.0/alex-3.5.2.0.tar.gz + https://hackage.haskell.org/package/happy-2.1.5/happy-2.1.5.tar.gz + https://hackage.haskell.org/package/happy-lib-2.1.5/happy-lib-2.1.5.tar.gz + + utils/genprimopcode + utils/deriveConstants + +-- project-rts +benchmarks: False +tests: False +allow-boot-library-installs: True +active-repositories: :none + +constraints: + build:any.ghc-internal installed, + -- for some reason cabal things these are already installed for the target, + -- although they only exist in the build compiler package db + Cabal source, + Cabal-syntax source, + array source, + base source, + binary source, + bytestring source, + containers source, + deepseq source, + directory source, + exceptions source, + file-io source, + filepath source, + ghc-bignum source, + hpc source, + integer-gmp source, + mtl source, + os-string source, + parsec source, + pretty source, + process source, + rts source, + rts-headers source, + rts-fs source, + stm source, + system-cxx-std-lib source, + template-haskell source, + text source, + time source, + transformers source, + unix source, + xhtml source, + Win32 source + + +package * + library-vanilla: True + shared: False + executable-profiling: False + executable-dynamic: False + executable-static: False + +if os(wasi) + package * + shared: True + package rts + ghc-options: "-optc-DProjectVersion=\"913\"" + ghc-options: "-optc-DRtsWay=\"v\"" + ghc-options: "-optc-DHostPlatform=\"wasm32-wasi\"" + ghc-options: "-optc-DHostArch=\"wasm32\"" + ghc-options: "-optc-DHostOS=\"unknown\"" + ghc-options: "-optc-DHostVendor=\"unknown\"" + ghc-options: "-optc-DBuildPlatform=\"FIXME\"" + ghc-options: "-optc-DBuildArch=\"FIXME\"" + ghc-options: "-optc-DBuildOS=\"FIXME\"" + ghc-options: "-optc-DBuildVendor=\"FIXME\"" + ghc-options: "-optc-DGhcUnregisterised=\"FIXME\"" + ghc-options: "-optc-DTablesNextToCode=\"FIXME\"" + ghc-options: "-optc-DFS_NAMESPACE=rts" + ghc-options: "-optl-Wl,--export-dynamic" + ghc-options: "-optc-fvisibility=default" + ghc-options: "-optc-fvisibility-inlines-hidden" + flags: -tables-next-to-code + +-- Maybe we should fix this with some import +if os(linux) + package rts + ghc-options: "-optc-DProjectVersion=\"913\"" + ghc-options: "-optc-DRtsWay=\"v\"" + ghc-options: "-optc-DHostPlatform=\"x86_64-unknown-linux\"" + ghc-options: "-optc-DHostArch=\"x86_64\"" + ghc-options: "-optc-DHostOS=\"linux\"" + ghc-options: "-optc-DHostVendor=\"unknown\"" + ghc-options: "-optc-DBuildPlatform=\"FIXME\"" + ghc-options: "-optc-DBuildArch=\"FIXME\"" + ghc-options: "-optc-DBuildOS=\"FIXME\"" + ghc-options: "-optc-DBuildVendor=\"FIXME\"" + ghc-options: "-optc-DGhcUnregisterised=\"FIXME\"" + ghc-options: "-optc-DTablesNextToCode=\"FIXME\"" + ghc-options: "-optc-DFS_NAMESPACE=rts" + flags: +tables-next-to-code + +if os(darwin) + package rts + ghc-options: "-optc-DProjectVersion=\"913\"" + ghc-options: "-optc-DRtsWay=\"v\"" + ghc-options: "-optc-DHostPlatform=\"aarch64-apple-darwin\"" + ghc-options: "-optc-DHostArch=\"aarch64\"" + ghc-options: "-optc-DHostOS=\"darwin\"" + ghc-options: "-optc-DHostVendor=\"unknown\"" + ghc-options: "-optc-DBuildPlatform=\"FIXME\"" + ghc-options: "-optc-DBuildArch=\"FIXME\"" + ghc-options: "-optc-DBuildOS=\"FIXME\"" + ghc-options: "-optc-DBuildVendor=\"FIXME\"" + ghc-options: "-optc-DGhcUnregisterised=\"FIXME\"" + ghc-options: "-optc-DTablesNextToCode=\"FIXME\"" + ghc-options: "-optc-DFS_NAMESPACE=rts" + flags: +tables-next-to-code +leading-underscore + + +program-options + ghc-options: -fhide-source-paths -j + +-- project-boot-libs +benchmarks: False +tests: False +allow-boot-library-installs: True +active-repositories: :none + +package rts-headers + ghc-options: -no-rts + +package rts-fs + ghc-options: -no-rts + +package rts + ghc-options: -no-rts + +package ghc + flags: +build-tool-depends +internal-interpreter + +package ghci + flags: +internal-interpreter + +package ghc-internal + flags: +bignum-native + +package text + flags: -simdutf + +program-options + ghc-options: -fhide-source-paths -j + +-- project-ghc +benchmarks: False +tests: False + +package hsc2hs + flags: +in-ghc-tree + +program-options + ghc-options: -fhide-source-paths -j diff --git a/configure.ac b/configure.ac index cc90facaa53..480cbb6bcfa 100644 --- a/configure.ac +++ b/configure.ac @@ -1,1117 +1,62 @@ -dnl == autoconf source for the Glasgow FP tools == -dnl (run "grep '^dnl \*' configure.ac | sed -e 's/dnl / /g; s/\*\*/ +/g;'" -dnl (or some such) to see the outline of this file) -dnl -# -# (c) The University of Glasgow 1994-2012 -# -# Configure script template for GHC -# -# Process with 'autoreconf' to get a working configure script. -# -# For the generated configure script, do "./configure --help" to -# see what flags are available. (Better yet, read the documentation!) -# - -AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-haskell-bugs@haskell.org], [ghc-AC_PACKAGE_VERSION]) - # Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable - # to be useful (cf #19058). However, the version must have three components - # (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are - # versioned correctly. - -AC_CONFIG_MACRO_DIRS([m4]) - -# Set this to YES for a released version, otherwise NO -: ${RELEASE=NO} - -# The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line -# above. If this is not a released version, then we will append the -# date to the version number (e.g. 7.4.20111220). The date is -# constructed by finding the date of the most recent patch in the -# git repository. If this is a source distribution (not a git -# checkout), then we ship a file 'VERSION' containing the full version -# when the source distribution was created. - -if test ! -f rts/ghcautoconf.h.autoconf.in; then - echo "rts/ghcautoconf.h.autoconf.in doesn't exist: perhaps you haven't run 'python3 boot'?" - exit 1 -fi - -dnl this makes sure `./configure --target=` -dnl works as expected, since we're slightly modifying how Autoconf -dnl interprets build/host/target and how this interacts with $CC tests -test -n "$target_alias" && ac_tool_prefix=$target_alias- - -dnl ---------------------------------------------------------- -dnl ** Store USER specified environment variables to pass them on to -dnl ** ghc-toolchain (in m4/ghc-toolchain.m4) -USER_CFLAGS="$CFLAGS" -USER_LDFLAGS="$LDFLAGS" -USER_LIBS="$LIBS" -USER_CXXFLAGS="$CXXFLAGS" -dnl The lower-level/not user-facing environment variables that may still be set -dnl by developers such as in ghc-wasm-meta -USER_CONF_CC_OPTS_STAGE2="$CONF_CC_OPTS_STAGE2" -USER_CONF_CXX_OPTS_STAGE2="$CONF_CXX_OPTS_STAGE2" -USER_CONF_GCC_LINKER_OPTS_STAGE2="$CONF_GCC_LINKER_OPTS_STAGE2" - -USER_LD="$LD" - -dnl ---------------------------------------------------------- -dnl ** Find unixy sort and find commands, -dnl ** which are needed by FP_SETUP_PROJECT_VERSION - -dnl ** Find find command (for Win32's benefit) -FP_PROG_FIND -FP_PROG_SORT - -dnl ---------------------------------------------------------- -FP_SETUP_PROJECT_VERSION - -# Hmmm, we fix the RPM release number to 1 here... Is this convenient? -AC_SUBST([release], [1]) - -dnl * We require autoconf version 2.69 due to -dnl https://bugs.ruby-lang.org/issues/8179. Also see #14910. -dnl * We need 2.50 due to the use of AC_SYS_LARGEFILE and AC_MSG_NOTICE. -dnl * We need 2.52 due to the use of AS_TR_CPP and AS_TR_SH. -dnl * Using autoconf 2.59 started to give nonsense like this -dnl #define SIZEOF_CHAR 0 -dnl recently. +# configure.ac AC_PREREQ([2.69]) - -# No, semi-sadly, we don't do `--srcdir'... -if test x"$srcdir" != 'x.' ; then - echo "This configuration does not support the \`--srcdir' option.." - exit 1 -fi - -dnl -------------------------------------------------------------- -dnl * Project specific configuration options -dnl -------------------------------------------------------------- -dnl What follows is a bunch of options that can either be configured -dnl through command line options to the configure script or by -dnl supplying defns in the build tree's mk/build.mk. Having the option to -dnl use either is considered a Feature. - -dnl ** What command to use to compile compiler sources ? -dnl -------------------------------------------------------------- - -AC_ARG_VAR(GHC,[Use as the full path to GHC. [default=autodetect]]) -AC_PATH_PROG([GHC], [ghc]) -AC_ARG_WITH([ghc], - AS_HELP_STRING([--with-ghc=PATH], [Use PATH as the full path to ghc (obsolete, use GHC=PATH instead) [default=autodetect]]), - AC_MSG_ERROR([--with-ghc=$withval is obsolete (use './configure GHC=$withval' or 'GHC=$withval ./configure' instead)])) -AC_SUBST(WithGhc,$GHC) - -AC_ARG_ENABLE(bootstrap-with-devel-snapshot, -[AS_HELP_STRING([--enable-bootstrap-with-devel-snapshot], - [Allow bootstrapping using a development snapshot of GHC. This is not guaranteed to work.])], - [FP_CAPITALIZE_YES_NO(["$enableval"], [EnableBootstrapWithDevelSnaphost])], - [EnableBootstrapWithDevelSnaphost=NO] -) - -AC_ARG_ENABLE(ignore-build-platform-mismatch, -[AS_HELP_STRING([--ignore-build-platform-mismatch], - [Ignore when the target platform reported by the bootstrap compiler doesn''t match the configured build platform. This flag is used to correct mistakes when the target platform is incorrectly reported by the bootstrap (#25200). ])], - [FP_CAPITALIZE_YES_NO(["$enableval"], [IgnoreBuildPlatformMismatch])], - [IgnoreBuildPlatformMismatch=NO] -) - - -AC_ARG_ENABLE(tarballs-autodownload, -[AS_HELP_STRING([--enable-tarballs-autodownload], - [Automatically download Windows distribution binaries if needed.])], - [FP_CAPITALIZE_YES_NO(["$enableval"], [TarballsAutodownload])], - [TarballsAutodownload=NO] -) - -AC_ARG_ENABLE(distro-toolchain, -[AS_HELP_STRING([--enable-distro-toolchain], - [Do not use bundled Windows toolchain binaries.])], - [FP_CAPITALIZE_YES_NO(["$enableval"], [EnableDistroToolchain])], - [EnableDistroToolchain=NO] -) - -if test "$EnableDistroToolchain" = "YES"; then - TarballsAutodownload=NO -fi - -AC_ARG_ENABLE(ghc-toolchain, -[AS_HELP_STRING([--enable-ghc-toolchain], - [Whether to use the newer ghc-toolchain tool to configure ghc targets])], - [FP_CAPITALIZE_YES_NO(["$enableval"], [EnableGhcToolchain])], - [EnableGhcToolchain=NO] -) -AC_SUBST([EnableGhcToolchain]) - -AC_ARG_ENABLE(strict-ghc-toolchain-check, -[AS_HELP_STRING([--enable-strict-ghc-toolchain-check], - [Whether to raise an error if the output of ghc-toolchain differs from configure])], - [FP_CAPITALIZE_YES_NO(["$enableval"], [EnableStrictGhcToolchainCheck])], - [EnableStrictGhcToolchainCheck=NO] -) -AC_SUBST([EnableStrictGhcToolchainCheck]) - -dnl CC_STAGE0, LD_STAGE0, AR_STAGE0 are like the "previous" variable -dnl CC, LD, AR (inherited by CC_STAGE[123], etc.) -dnl but instead used by stage0 for bootstrapping stage1 -AC_ARG_VAR(CC_STAGE0, [C compiler command (bootstrap)]) -AC_ARG_VAR(LD_STAGE0, [Linker command (bootstrap)]) -AC_ARG_VAR(AR_STAGE0, [Archive command (bootstrap)]) - -dnl RTS ways supplied by the bootstrapping compiler. -AC_ARG_VAR(RTS_WAYS_STAGE0, [RTS ways]) - -if test "$WithGhc" != ""; then - FPTOOLS_GHC_VERSION([GhcVersion], [GhcMajVersion], [GhcMinVersion], [GhcPatchLevel])dnl - - if test "$GhcMajVersion" = "unknown" || test "$GhcMinVersion" = "unknown"; then - AC_MSG_ERROR([Cannot determine the version of $WithGhc. Is it really GHC?]) - fi - - AC_SUBST(GhcVersion)dnl - AC_SUBST(GhcMajVersion)dnl - AC_SUBST(GhcMinVersion)dnl - AC_SUBST(GhcPatchLevel)dnl - GhcMinVersion2=`echo "$GhcMinVersion" | sed 's/^\\(.\\)$/0\\1/'` - GhcCanonVersion="$GhcMajVersion$GhcMinVersion2" - - dnl infer {CC,LD,AR}_STAGE0 from `ghc --info` unless explicitly set by user - if test -z "$CC_STAGE0"; then - BOOTSTRAPPING_GHC_INFO_FIELD([CC_STAGE0],[C compiler command]) - fi - - if test -z "$LD_STAGE0"; then - BOOTSTRAPPING_GHC_INFO_FIELD([LD_STAGE0],[ld command]) - # ld command is removed in 9.10.1 as a boot compiler and supplies "Merge objects - # command" instead - if test -z "$LD_STAGE0"; then - BOOTSTRAPPING_GHC_INFO_FIELD([LD_STAGE0],[Merge objects command]) - fi - - fi - if test -z "$AR_STAGE0"; then - BOOTSTRAPPING_GHC_INFO_FIELD([AR_STAGE0],[ar command]) - fi - BOOTSTRAPPING_GHC_INFO_FIELD([AR_OPTS_STAGE0],[ar flags]) - BOOTSTRAPPING_GHC_INFO_FIELD([ArSupportsAtFile_STAGE0],[ar supports at file]) - BOOTSTRAPPING_GHC_INFO_FIELD([ArSupportsDashL_STAGE0],[ar supports -L]) - BOOTSTRAPPING_GHC_INFO_FIELD([SUPPORT_SMP_STAGE0],[Support SMP]) - BOOTSTRAPPING_GHC_INFO_FIELD([RTS_WAYS_STAGE0],[RTS ways]) - - dnl Check whether or not the bootstrapping GHC has a threaded RTS. This - dnl determines whether or not we can have a threaded stage 1. - dnl See Note [Linking ghc-bin against threaded stage0 RTS] in - dnl hadrian/src/Settings/Packages.hs for details. - dnl SMP support which implies a registerised stage0 is also required (see issue 18266) - if echo ${RTS_WAYS_STAGE0} | tr ' ' '\n' | grep '^thr$' 2>&1 >/dev/null && \ - test "$SUPPORT_SMP_STAGE0" = "YES" - then - AC_SUBST(GhcThreadedRts, YES) - else - AC_SUBST(GhcThreadedRts, NO) - fi -fi - -dnl ** Must have GHC to build GHC -if test "$WithGhc" = "" -then - AC_MSG_ERROR([GHC is required.]) -fi -MinBootGhcVersion="9.6" -FP_COMPARE_VERSIONS([$GhcVersion],[-lt],[$MinBootGhcVersion], - [AC_MSG_ERROR([GHC version $MinBootGhcVersion or later is required to compile GHC.])]) - -if test `expr $GhcMinVersion % 2` = "1" -then - if test "$EnableBootstrapWithDevelSnaphost" = "NO" - then - AC_MSG_ERROR([ - $WithGhc is a development snapshot of GHC, version $GhcVersion. - Bootstrapping using this version of GHC is not supported, and may not - work. Use --enable-bootstrap-with-devel-snapshot to try it anyway, - or 'GHC=' to specify a different GHC to use.]) - fi -fi - -# GHC is passed to Cabal, so we need a native path -if test "${WithGhc}" != "" -then - ghc_host_os=`"${WithGhc}" +RTS --info | grep 'Host OS' | sed -e 's/.*, "//' -e 's/")//'` - - if test "$ghc_host_os" = "mingw32" - then - if test "${OSTYPE}" = "msys" - then - WithGhc=`echo "${WithGhc}" | sed "s#^/\([a-zA-Z]\)/#\1:/#"` - else - # Canonicalise to :/path/to/ghc - WithGhc=`cygpath -m "${WithGhc}"` - fi - echo "GHC path canonicalised to: ${WithGhc}" - fi -fi -AC_SUBST([WithGhc]) - -dnl ** Without optimization some INLINE trickery fails for GHCi -SRC_CC_OPTS="-O" - -dnl-------------------------------------------------------------------- -dnl * Choose host(/target/build) platform -dnl-------------------------------------------------------------------- -dnl If we aren't explicitly told what values to use with configure flags, -dnl we ask the bootstrapping compiler what platform it is for - -if test "${WithGhc}" != "" -then - bootstrap_host=`"${WithGhc}" --info | grep '^ ,("Host platform"' | sed -e 's/.*,"//' -e 's/")//' | tr -d '\r'` - bootstrap_target=`"${WithGhc}" --info | grep '^ ,("Target platform"' | sed -e 's/.*,"//' -e 's/")//' | tr -d '\r'` - if test "$bootstrap_host" != "$bootstrap_target" - then - echo "Bootstrapping GHC is a cross compiler. This probably isn't going to work" - fi -fi - -# We have to run these unconditionally, but we may discard their -# results in the following code -AC_CANONICAL_BUILD -AC_CANONICAL_HOST -AC_CANONICAL_TARGET - -FPTOOLS_SET_PLATFORMS_VARS - -FP_PROG_SH - -# Verify that the installed (bootstrap) GHC is capable of generating -# code for the requested build platform. -if test "$BuildPlatform" != "$bootstrap_target" -then - if test "$IgnoreBuildPlatformMismatch" = "NO" - then - echo "This GHC (${WithGhc}) does not generate code for the build platform" - echo " GHC target platform : $bootstrap_target" - echo " Desired build platform : $BuildPlatform" - exit 1 - fi -fi - -dnl ** Do an unregisterised build? -dnl -------------------------------------------------------------- - -GHC_UNREGISTERISED -AC_SUBST(Unregisterised) - -dnl ** Do a build with tables next to code? -dnl -------------------------------------------------------------- - -GHC_TABLES_NEXT_TO_CODE -AC_SUBST(TablesNextToCode) - -# Requires FPTOOLS_SET_PLATFORMS_VARS to be run first. -FP_FIND_ROOT - -# Extract and configure the Windows toolchain -if test "$HostOS" = "mingw32" -a "$EnableDistroToolchain" = "NO"; then - FP_INSTALL_WINDOWS_TOOLCHAIN - FP_SETUP_WINDOWS_TOOLCHAIN([$hardtop/inplace/mingw], [$hardtop/inplace/mingw]) -else - AC_CHECK_TOOL([CC],[gcc], [clang]) - AC_CHECK_TOOL([CXX],[g++], [clang++]) - AC_CHECK_TOOL([NM],[nm]) - # N.B. we don't probe for LD here but instead - # do so in FIND_LD to avoid #21778. - AC_CHECK_TOOL([AR],[ar]) - AC_CHECK_TOOL([RANLIB],[ranlib]) - AC_CHECK_TOOL([OBJDUMP],[objdump]) - AC_CHECK_TOOL([WindresCmd],[windres]) - AC_CHECK_TOOL([Genlib],[genlib]) - - if test "$HostOS" = "mingw32"; then - AC_CHECK_TARGET_TOOL([WindresCmd],[windres]) - AC_CHECK_TARGET_TOOL([OBJDUMP],[objdump]) - - WindresCmd="$(cygpath -m $WindresCmd)" - - if test "$Genlib" != ""; then - GenlibCmd="$(cygpath -m $Genlib)" - fi - fi -fi - -FP_ICONV -FP_GMP -FP_CURSES - -dnl On Windows we force in-tree GMP build until we support dynamic linking -if test "$HostOS" = "mingw32" -then - GMP_FORCE_INTREE="YES" -fi - -dnl ** Building a cross compiler? -dnl -------------------------------------------------------------- -CrossCompiling=NO -# If 'host' and 'target' differ, then this means we are building a cross-compiler. -if test "$target" != "$host" ; then - CrossCompiling=YES - cross_compiling=yes # This tells configure that it can accept just 'target', - # otherwise you get - # configure: error: cannot run C compiled programs. - # If you meant to cross compile, use `--host'. -fi -if test "$BuildPlatform" != "$HostPlatform" ; then - AC_MSG_ERROR([ -You've selected: - - BUILD: $BuildPlatform (the architecture we're building on) - HOST: $HostPlatform (the architecture the compiler we're building will execute on) - TARGET: $TargetPlatform (the architecture the compiler we're building will produce code for) - -BUILD must equal HOST; that is, we do not support building GHC itself -with a cross-compiler. To cross-compile GHC itself, set TARGET: stage -1 will be a cross-compiler, and stage 2 will be the cross-compiled -GHC. +AC_INIT([ghc-builder], [0.1.0], [your-email@example.com]) +AC_CONFIG_SRCDIR([.]) # A representative .in file +AC_CONFIG_AUX_DIR([build-aux]) # Recommended place for config.guess, config.sub +AC_CONFIG_MACRO_DIR([m4]) # For any custom m4 macros +# AM_INIT_AUTOMAKE([-Wall -Werror foreign]) # Using some automake conventions + +# --- 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.13)])], [ProjectVersion="$withval"], [ProjectVersion="9.13"]) +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-munged], [AS_HELP_STRING([--with-project-version-munged=VER], [GHC version "munged" (default: 9.13)])], [ProjectVersionMunged="$withval"], [ProjectVersionMunged="9.13"]) +AC_ARG_WITH([project-version-for-lib], [AS_HELP_STRING([--with-project-version-for-lib=VER], [GHC version for libraries (default: 9.1300)])], [ProjectVersionForLib="$withval"], [ProjectVersionForLib="9.1300"]) +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"]) + +# Export these variables for substitution by AC_SUBST +AC_SUBST([ProjectVersion]) +AC_SUBST([ProjectVersionInt]) +AC_SUBST([ProjectVersionMunged]) +AC_SUBST([ProjectVersionForLib]) +AC_SUBST([ProjectPatchLevel]) +AC_SUBST([ProjectPatchLevel1]) +AC_SUBST([ProjectPatchLevel2]) + +# For ghc-boot-th.cabal.in +AC_SUBST([Suffix],[""]) +AC_SUBST([SourceRoot],["."]) + +# --- Define Programs --- +# We don't need to check for CC, MAKE_SET, and others for now, we only want substitution. +# AC_PROG_CC +# AC_PROG_MAKE_SET # To ensure 'set' works in Makefiles for undefined variables +AC_CHECK_PROGS([PYTHON], [python3 python python2]) +AS_IF([test "x$PYTHON" = x], [AC_MSG_ERROR([Python interpreter not found. Please install Python or set PYTHON environment variable.])]) +AC_SUBST([PYTHON]) + +# --- Files to generate --- +# config.status will create these files by substituting @VAR@ placeholders. +AC_CONFIG_FILES([ + ghc/ghc-bin.cabal:ghc/ghc-bin.cabal.in + compiler/ghc.cabal:compiler/ghc.cabal.in + libraries/ghc-boot/ghc-boot.cabal:libraries/ghc-boot/ghc-boot.cabal.in + libraries/ghc-boot-th/ghc-boot-th.cabal:libraries/ghc-boot-th/ghc-boot-th.cabal.in + libraries/ghc-heap/ghc-heap.cabal:libraries/ghc-heap/ghc-heap.cabal.in + libraries/template-haskell/template-haskell.cabal:libraries/template-haskell/template-haskell.cabal.in + libraries/ghci/ghci.cabal:libraries/ghci/ghci.cabal.in + utils/ghc-pkg/ghc-pkg.cabal:utils/ghc-pkg/ghc-pkg.cabal.in + utils/ghc-iserv/ghc-iserv.cabal:utils/ghc-iserv/ghc-iserv.cabal.in + utils/runghc/runghc.cabal:utils/runghc/runghc.cabal.in + libraries/ghc-internal/ghc-internal.cabal:libraries/ghc-internal/ghc-internal.cabal.in + libraries/ghc-experimental/ghc-experimental.cabal:libraries/ghc-experimental/ghc-experimental.cabal.in + libraries/base/base.cabal:libraries/base/base.cabal.in + rts/include/ghcversion.h:rts/include/ghcversion.h.in ]) -fi -# Despite its similarity in name to TargetPlatform, TargetPlatformFull is used -# in calls to subproject configure scripts and thus must be set to the autoconf -# triple, not the normalized GHC triple that TargetPlatform is set to. -# -# We use the non-canonicalized triple, target_alias, here since the subproject -# configure scripts will use this triple to construct the names of the toolchain -# executables. If we instead passed down the triple produced by -# AC_CANONICAL_TARGET then it may look for the target toolchain under the wrong -# name (this is a known problem in the case of the Android NDK, which has -# slightly odd triples). -# -# It may be better to just do away with the GHC triples altogether. This would -# all be taken care of for us if we configured the subprojects using -# AC_CONFIG_DIR, but unfortunately Cabal needs to be the one to do the -# configuration. -# -# We also use non-canonicalized triple when install stage1 crosscompiler -if test -z "${target_alias}" -then - # --target wasn't given; use result from AC_CANONICAL_TARGET - TargetPlatformFull="${target}" -else - TargetPlatformFull="${target_alias}" -fi -AC_SUBST(CrossCompiling) -AC_SUBST(TargetPlatformFull) - -dnl ** Which gcc to use? -dnl -------------------------------------------------------------- - -AC_ARG_WITH([gcc], - AS_HELP_STRING([--with-gcc=ARG], [Use ARG as the path to gcc (obsolete, use CC=ARG instead) [default=autodetect]]), - AC_MSG_ERROR([--with-gcc=$withval is obsolete (use './configure CC=$withval' or 'CC=$withval ./configure' instead)])) - -AC_ARG_WITH([clang], - AS_HELP_STRING([--with-clang=ARG], [Use ARG as the path to clang (obsolete, use CC=ARG instead) [default=autodetect]]), - AC_MSG_ERROR([--with-clang=$withval is obsolete (use './configure CC=$withval' or 'CC=$withval ./configure' instead)])) - -dnl detect compiler (prefer gcc over clang) and set $CC (unless CC already set), -dnl later CC is copied to CC_STAGE{1,2,3} -AC_PROG_CC([cc gcc clang]) -AC_PROG_CXX([g++ clang++ c++]) -# Work around #24324 -MOVE_TO_FLAGS([CC],[CFLAGS]) -MOVE_TO_FLAGS([CXX],[CXXFLAGS]) - -MAYBE_OVERRIDE_STAGE0([ar],[AR_STAGE0]) - -dnl make extensions visible to allow feature-tests to detect them lateron -AC_USE_SYSTEM_EXTENSIONS - -# --with-hs-cpp/--with-hs-cpp-flags -FP_HSCPP_CMD_WITH_ARGS(HaskellCPPCmd, HaskellCPPArgs) -AC_SUBST([HaskellCPPCmd]) -AC_SUBST([HaskellCPPArgs]) - -# --with-js-cpp/--with-js-cpp-flags -FP_JSCPP_CMD_WITH_ARGS(JavaScriptCPPCmd, JavaScriptCPPArgs) -AC_SUBST([JavaScriptCPPCmd]) -AC_SUBST([JavaScriptCPPArgs]) - -# --with-cmm-cpp/--with-cmm-cpp-flags -FP_CMM_CPP_CMD_WITH_ARGS([$CC_STAGE0], [CmmCPPCmd_STAGE0], [CmmCPPArgs_STAGE0], [CmmCPPSupportsG0_STAGE0]) -AC_SUBST([CmmCPPCmd_STAGE0]) -AC_SUBST([CmmCPPArgs_STAGE0]) -AC_SUBST([CmmCPPSupportsG0_STAGE0]) -FP_CMM_CPP_CMD_WITH_ARGS([$CC], [CmmCPPCmd], [CmmCPPArgs], [CmmCPPSupportsG0]) -AC_SUBST([CmmCPPCmd]) -AC_SUBST([CmmCPPArgs]) -AC_SUBST([CmmCPPSupportsG0]) - -FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS]) -FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0]) -FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1]) -FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2]) - -dnl ** Do we have a compatible emsdk version? -dnl -------------------------------------------------------------- -EMSDK_VERSION("3.1.20", "", "") - -dnl ** Which ld to use -dnl -------------------------------------------------------------- -AC_ARG_VAR(LD,[Use as the path to ld. See also --disable-ld-override.]) -FIND_LD([$target],[GccUseLdOpt]) -FIND_MERGE_OBJECTS() -CONF_GCC_LINKER_OPTS_STAGE1="$CONF_GCC_LINKER_OPTS_STAGE1 $GccUseLdOpt" -CONF_GCC_LINKER_OPTS_STAGE2="$CONF_GCC_LINKER_OPTS_STAGE2 $GccUseLdOpt" -CFLAGS="$CFLAGS $GccUseLdOpt" - -FP_PROG_LD_IS_GNU -FP_PROG_LD_NO_COMPACT_UNWIND -FP_PROG_LD_FILELIST -FP_PROG_LD_SINGLE_MODULE - - -dnl ** Which nm to use? -dnl -------------------------------------------------------------- -FP_FIND_NM - -dnl ** Which objdump to use? -dnl -------------------------------------------------------------- -dnl Note: we may not have objdump on OS X, and we only need it on -dnl Windows (for DLL checks), OpenBSD, and AIX -case $HostOS_CPP in - cygwin32|mingw32|openbsd|aix) - AC_CHECK_TARGET_TOOL([OBJDUMP], [objdump]) - ;; -esac - -if test "$HostOS" = "mingw32" -then - ObjdumpCmd=$(cygpath -m "$OBJDUMP") -else - ObjdumpCmd="$OBJDUMP" -fi -AC_SUBST([ObjdumpCmd]) - -dnl ** Which ranlib to use? -dnl -------------------------------------------------------------- -AC_PROG_RANLIB -if test "$RANLIB" = ":"; then - AC_MSG_ERROR([cannot find ranlib in your PATH]) -fi -if test "$HostOS" = "mingw32" -then - RanlibCmd=$(cygpath -m "$RANLIB") -else - RanlibCmd="$RANLIB" -fi -AC_SUBST([RanlibCmd]) - -dnl ** which strip to use? -dnl -------------------------------------------------------------- -AC_CHECK_TARGET_TOOL([STRIP], [strip]) -StripCmd="$STRIP" -AC_SUBST([StripCmd]) - -dnl ** Which otool to use on macOS -dnl -------------------------------------------------------------- -AC_CHECK_TARGET_TOOL([OTOOL], [otool]) -OtoolCmd="$OTOOL" -AC_SUBST(OtoolCmd) - -dnl ** Which install_name_tool to use on macOS -dnl -------------------------------------------------------------- -AC_CHECK_TARGET_TOOL([INSTALL_NAME_TOOL], [install_name_tool]) -InstallNameToolCmd="$INSTALL_NAME_TOOL" -AC_SUBST(InstallNameToolCmd) - -# Here is where we re-target which specific version of the LLVM -# tools we are looking for. In the past, GHC supported a number of -# versions of LLVM simultaneously, but that stopped working around -# 3.5/3.6 release of LLVM. -LlvmMinVersion=13 # inclusive -LlvmMaxVersion=20 # not inclusive -AC_SUBST([LlvmMinVersion]) -AC_SUBST([LlvmMaxVersion]) - -ConfiguredEmsdkVersion="${EmsdkVersion}" -AC_SUBST([ConfiguredEmsdkVersion]) - -dnl ** Which LLVM llc to use? -dnl -------------------------------------------------------------- -AC_ARG_VAR(LLC,[Use as the path to LLVM's llc [default=autodetect]]) -FIND_LLVM_PROG([LLC], [llc], [$LlvmMinVersion], [$LlvmMaxVersion]) -LlcCmd="$LLC" -AC_SUBST([LlcCmd]) - -dnl ** Which LLVM opt to use? -dnl -------------------------------------------------------------- -AC_ARG_VAR(OPT,[Use as the path to LLVM's opt [default=autodetect]]) -FIND_LLVM_PROG([OPT], [opt], [$LlvmMinVersion], [$LlvmMaxVersion]) -OptCmd="$OPT" -AC_SUBST([OptCmd]) - -dnl ** Which LLVM assembler to use? -dnl -------------------------------------------------------------- -AC_ARG_VAR(LLVMAS,[Use as the path to LLVM's assembler (typically clang) [default=autodetect]]) -FIND_LLVM_PROG([LLVMAS], [clang], [$LlvmMinVersion], [$LlvmMaxVersion]) -LlvmAsCmd="$LLVMAS" -AC_SUBST([LlvmAsCmd]) - -dnl -------------------------------------------------------------- -dnl End of configure script option section -dnl -------------------------------------------------------------- - -dnl ** Copy headers shared by the RTS and compiler -dnl -------------------------------------------------------------- -dnl We can't commit symlinks without breaking Windows in the default -dnl configuration. -AC_MSG_NOTICE([Creating links for headers shared by the RTS and compiler]) -ln -f rts/include/rts/Bytecodes.h compiler/ -ln -f rts/include/rts/storage/ClosureTypes.h compiler/ -ln -f rts/include/rts/storage/FunTypes.h compiler/ -ln -f rts/include/stg/MachRegs.h compiler/ -mkdir -p compiler/MachRegs -ln -f rts/include/stg/MachRegs/arm32.h compiler/MachRegs/arm32.h -ln -f rts/include/stg/MachRegs/arm64.h compiler/MachRegs/arm64.h -ln -f rts/include/stg/MachRegs/loongarch64.h compiler/MachRegs/loongarch64.h -ln -f rts/include/stg/MachRegs/ppc.h compiler/MachRegs/ppc.h -ln -f rts/include/stg/MachRegs/riscv64.h compiler/MachRegs/riscv64.h -ln -f rts/include/stg/MachRegs/s390x.h compiler/MachRegs/s390x.h -ln -f rts/include/stg/MachRegs/wasm32.h compiler/MachRegs/wasm32.h -ln -f rts/include/stg/MachRegs/x86.h compiler/MachRegs/x86.h -AC_MSG_NOTICE([done.]) - -dnl ** Copy the files from the "fs" utility into the right folders. -dnl -------------------------------------------------------------- -AC_MSG_NOTICE([Creating links for in-tree file handling routines]) -ln -f utils/fs/fs.* utils/unlit/ -ln -f utils/fs/fs.* rts/ -ln -f utils/fs/fs.h libraries/ghc-internal/include/ -ln -f utils/fs/fs.c libraries/ghc-internal/cbits/ -AC_MSG_NOTICE([Routines in place. Packages can now be build normally.]) - -dnl ** Copy files for ghci wrapper C utilities. -dnl -------------------------------------------------------------- -dnl See Note [Hadrian's ghci-wrapper package] in hadrian/src/Packages.hs -AC_MSG_NOTICE([Creating links for ghci wrapper]) -ln -f driver/utils/getLocation.c driver/ghci/ -ln -f driver/utils/getLocation.h driver/ghci/ -ln -f driver/utils/isMinTTY.c driver/ghci/ -ln -f driver/utils/isMinTTY.h driver/ghci/ -ln -f driver/utils/cwrapper.c driver/ghci/ -ln -f driver/utils/cwrapper.h driver/ghci/ -AC_MSG_NOTICE([done.]) - -dnl -------------------------------------------------------------- -dnl ** Can the unix package be built? -dnl -------------------------------------------------------------- - -dnl ** does #! work? -AC_SYS_INTERPRETER() - -dnl ** look for GCC and find out which version -dnl Figure out which C compiler to use. Gcc is preferred. -dnl If gcc, make sure it's at least 4.7 -dnl -FP_GCC_VERSION - - -dnl ** Check support for the extra flags passed by GHC when compiling via C -FP_GCC_SUPPORTS_VIA_C_FLAGS - -dnl ** Used to determine how to compile ghc-prim's atomics.c, used by -dnl unregisterised, Sparc, and PPC backends. Also determines whether -dnl linking to libatomic is required for atomic operations, e.g. on -dnl RISCV64 GCC. -FP_CC_SUPPORTS__ATOMICS -if test "$need_latomic" = 1; then - AC_SUBST([NeedLibatomic],[YES]) -else - AC_SUBST([NeedLibatomic],[NO]) -fi - -dnl ** look to see if we have a C compiler using an llvm back end. -dnl -FP_CC_LLVM_BACKEND -AC_SUBST(CcLlvmBackend) - -FPTOOLS_SET_C_LD_FLAGS([target],[CFLAGS],[LDFLAGS],[IGNORE_LINKER_LD_FLAGS],[CPPFLAGS]) -FPTOOLS_SET_C_LD_FLAGS([build],[CONF_CC_OPTS_STAGE0],[CONF_GCC_LINKER_OPTS_STAGE0],[CONF_LD_LINKER_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0]) -FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE1],[CONF_GCC_LINKER_OPTS_STAGE1],[CONF_LD_LINKER_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1]) -FPTOOLS_SET_C_LD_FLAGS([target],[CONF_CC_OPTS_STAGE2],[CONF_GCC_LINKER_OPTS_STAGE2],[CONF_LD_LINKER_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2]) -# Stage 3 won't be supported by cross-compilation - -#-no_fixup_chains -FP_LD_NO_FIXUP_CHAINS([target], [LDFLAGS]) -FP_LD_NO_FIXUP_CHAINS([build], [CONF_GCC_LINKER_OPTS_STAGE0]) -FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE1]) -FP_LD_NO_FIXUP_CHAINS([target], [CONF_GCC_LINKER_OPTS_STAGE2]) - -#-no_warn_duplicate_libraries -FP_LD_NO_WARN_DUPLICATE_LIBRARIES([build], [CONF_GCC_LINKER_OPTS_STAGE0]) -FP_LD_NO_WARN_DUPLICATE_LIBRARIES([target], [CONF_GCC_LINKER_OPTS_STAGE1]) -FP_LD_NO_WARN_DUPLICATE_LIBRARIES([target], [CONF_GCC_LINKER_OPTS_STAGE2]) - -FP_MERGE_OBJECTS_SUPPORTS_RESPONSE_FILES - -GHC_LLVM_TARGET_SET_VAR -# The target is substituted into the distrib/configure.ac file -AC_SUBST(LlvmTarget) - -dnl ** See whether cc supports --target= and set -dnl CONF_CC_OPTS_STAGE[012] accordingly. -FP_CC_SUPPORTS_TARGET([$CC_STAGE0], [CONF_CC_OPTS_STAGE0], [CONF_CXX_OPTS_STAGE0]) -FP_CC_SUPPORTS_TARGET([$CC], [CONF_CC_OPTS_STAGE1], [CONF_CXX_OPTS_STAGE1]) -FP_CC_SUPPORTS_TARGET([$CC], [CONF_CC_OPTS_STAGE2], [CONF_CXX_OPTS_STAGE2]) - -FP_PROG_CC_LINKER_TARGET([$CC_STAGE0], [CONF_CC_OPTS_STAGE0], [CONF_GCC_LINKER_OPTS_STAGE0]) -FP_PROG_CC_LINKER_TARGET([$CC], [CONF_CC_OPTS_STAGE1], [CONF_GCC_LINKER_OPTS_STAGE1]) -FP_PROG_CC_LINKER_TARGET([$CC], [CONF_CC_OPTS_STAGE2], [CONF_GCC_LINKER_OPTS_STAGE2]) - -dnl ** See whether cc used as a linker supports -no-pie -FP_GCC_SUPPORTS_NO_PIE - -dnl Pass -Qunused-arguments or otherwise GHC will have very noisy invocations of Clang -dnl TODO: Do we need -Qunused-arguments in CXX and GCC linker too? -FP_CC_IGNORE_UNUSED_ARGS([$CC_STAGE0], [CONF_CC_OPTS_STAGE0]) -FP_CC_IGNORE_UNUSED_ARGS([$CC], [CONF_CC_OPTS_STAGE1]) -FP_CC_IGNORE_UNUSED_ARGS([$CC], [CONF_CC_OPTS_STAGE2]) - -# CPP, CPPFLAGS -# --with-cpp/-with-cpp-flags -dnl Note that we must do this after setting and using the C99 CPPFLAGS, or -dnl otherwise risk trying to configure the C99 and LD flags using -E as a CPPFLAG -FP_CPP_CMD_WITH_ARGS([$CC_STAGE0],[CPPCmd_STAGE0],[CONF_CPP_OPTS_STAGE0]) -FP_CPP_CMD_WITH_ARGS([$CC],[CPPCmd],[CONF_CPP_OPTS_STAGE1]) -FP_CPP_CMD_WITH_ARGS([$CC],[CPPCmd],[CONF_CPP_OPTS_STAGE2]) -AC_SUBST([CPPCmd_STAGE0]) -AC_SUBST([CPPCmd]) - -# See rules/distdir-way-opts.mk for details. -# Flags passed to the C compiler -AC_SUBST(CONF_CC_OPTS_STAGE0) -AC_SUBST(CONF_CC_OPTS_STAGE1) -AC_SUBST(CONF_CC_OPTS_STAGE2) -# Flags passed to the C compiler when we ask it to link -AC_SUBST(CONF_GCC_LINKER_OPTS_STAGE0) -AC_SUBST(CONF_GCC_LINKER_OPTS_STAGE1) -AC_SUBST(CONF_GCC_LINKER_OPTS_STAGE2) -# Flags passed to the linker when we ask it to link -AC_SUBST(CONF_LD_LINKER_OPTS_STAGE0) -AC_SUBST(CONF_LD_LINKER_OPTS_STAGE1) -AC_SUBST(CONF_LD_LINKER_OPTS_STAGE2) -# Flags passed to the C preprocessor -AC_SUBST(CONF_CPP_OPTS_STAGE0) -AC_SUBST(CONF_CPP_OPTS_STAGE1) -AC_SUBST(CONF_CPP_OPTS_STAGE2) -# Flags passed to the Haskell compiler -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 only when _not_ compiling -dnl the JS backend. The JS backend uses emscripten to wrap c++ utilities which -dnl fails this check, so we avoid it when compiling to JS. -if test "$TargetOS" != "ghcjs"; then - FP_FIND_CXX_STD_LIB -fi -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 -------------------------------------------------------------- -FPTOOLS_SET_HASKELL_PLATFORM_VARS([Build]) - -FPTOOLS_SET_HASKELL_PLATFORM_VARS([Host]) -AC_SUBST(HaskellHostArch) -AC_SUBST(HaskellHostOs) - -FPTOOLS_SET_HASKELL_PLATFORM_VARS([Target]) -AC_SUBST(HaskellTargetArch) -AC_SUBST(HaskellTargetOs) - -GHC_SUBSECTIONS_VIA_SYMBOLS -AC_SUBST(TargetHasSubsectionsViaSymbols) - -GHC_IDENT_DIRECTIVE -AC_SUBST(TargetHasIdentDirective) - -GHC_GNU_NONEXEC_STACK -AC_SUBST(TargetHasGnuNonexecStack) - -dnl Let's make sure install-sh is executable here. If we got it from -dnl a darcs repo, it might not be (see bug #978). -chmod +x install-sh -dnl ** figure out how to do a BSD-ish install -AC_PROG_INSTALL - -dnl ** how to invoke `ar' and `ranlib' -FP_PROG_AR_SUPPORTS_ATFILE -FP_PROG_AR_SUPPORTS_DASH_L -FP_PROG_AR_NEEDS_RANLIB - -dnl ** Check to see whether ln -s works -AC_PROG_LN_S - -FP_SETTINGS - -dnl ** Find the path to sed -AC_PATH_PROGS(SedCmd,gsed sed,sed) - - -dnl ** check for time command -AC_PATH_PROG(TimeCmd,time) - -dnl ** check for tar -dnl if GNU tar is named gtar, look for it first. -AC_PATH_PROGS(TarCmd,gnutar gtar tar,tar) - -dnl ** check for autoreconf -AC_PATH_PROG(AutoreconfCmd, autoreconf, autoreconf) - -dnl ** check for dtrace (currently only implemented for Mac OS X) -AC_ARG_ENABLE(dtrace, - [AS_HELP_STRING([--enable-dtrace], - [Enable DTrace])], - EnableDtrace=$enableval, - EnableDtrace=yes -) - -HaveDtrace=NO - -AC_PATH_PROG(DtraceCmd,dtrace) -if test "x$EnableDtrace" = "xyes"; then - if test -n "$DtraceCmd"; then - if test "x$TargetOS_CPP-$TargetVendor_CPP" = "xdarwin-apple" \ - -o "x$TargetOS_CPP-$TargetVendor_CPP" = "xfreebsd-portbld" \ - -o "x$TargetOS_CPP-$TargetVendor_CPP" = "xsolaris2-unknown"; then - HaveDtrace=YES - fi - fi -fi -AC_SUBST(HaveDtrace) - -AC_PATH_PROG(HSCOLOUR,HsColour) -# HsColour is passed to Cabal, so we need a native path -if test "$HostOS" = "mingw32" && \ - test "${OSTYPE}" != "msys" && \ - test "${HSCOLOUR}" != "" -then - # Canonicalise to :/path/to/gcc - HSCOLOUR=`cygpath -m ${HSCOLOUR}` -fi - -dnl ** check for Sphinx toolchain -AC_PATH_PROG(SPHINXBUILD,sphinx-build) -AC_CACHE_CHECK([for version of sphinx-build], fp_cv_sphinx_version, -changequote(, )dnl -[if test -n "$SPHINXBUILD"; then - fp_cv_sphinx_version=`"$SPHINXBUILD" --version 2>&1 | sed -re 's/.* v?([0-9]\.[0-9]\.[0-9])/\1/' | head -n1`; -fi; -changequote([, ])dnl -]) -FP_COMPARE_VERSIONS([$fp_cv_sphinx_version],-lt,1.0.0, - [AC_MSG_WARN([Sphinx version 1.0.0 or later is required to build documentation]); SPHINXBUILD=;]) -if test -n "$SPHINXBUILD"; then - if "$SPHINXBUILD" -b text utils/check-sphinx utils/check-sphinx/dist > /dev/null 2>&1; then true; else - AC_MSG_WARN([Sphinx for python3 is required to build documentation.]) - SPHINXBUILD=; - fi -fi - -dnl ** check for xelatex -AC_PATH_PROG(XELATEX,xelatex) -AC_PATH_PROG(MAKEINDEX,makeindex) -AC_PATH_PROG(GIT,git) - -dnl ** check for makeinfo -AC_PATH_PROG(MAKEINFO,makeinfo) - -dnl ** check for cabal -AC_PATH_PROG(CABAL,cabal) - - -dnl ** check for Python for testsuite driver -FIND_PYTHON - -dnl ** check for ghc-pkg command -FP_PROG_GHC_PKG - -dnl ** check for installed happy binary + version - -AC_ARG_VAR(HAPPY,[Use as the path to happy [default=autodetect]]) -FPTOOLS_HAPPY - -dnl ** check for installed alex binary + version - -AC_ARG_VAR(ALEX,[Use as the path to alex [default=autodetect]]) -FPTOOLS_ALEX - -dnl -------------------------------------------------- -dnl ### program checking section ends here ### -dnl -------------------------------------------------- - -dnl for use in settings file -AC_CHECK_SIZEOF([void *]) -TargetWordSize=$ac_cv_sizeof_void_p -AC_SUBST(TargetWordSize) - -AC_C_BIGENDIAN([TargetWordBigEndian=YES],[TargetWordBigEndian=NO]) -AC_SUBST(TargetWordBigEndian) - -dnl ** check for math library -dnl Keep that check as early as possible. -dnl as we need to know whether we need libm -dnl for math functions or not -dnl (see https://gitlab.haskell.org/ghc/ghc/issues/3730) -AC_CHECK_LIB(m, atan, UseLibm=YES, UseLibm=NO) -AC_SUBST([UseLibm]) -TargetHasLibm=$UseLibm -AC_SUBST(TargetHasLibm) - -FP_BFD_FLAG -AC_SUBST([UseLibbfd]) - -dnl ################################################################ -dnl Check for libraries -dnl ################################################################ - -FP_FIND_LIBFFI -AC_SUBST(UseSystemLibFFI) -AC_SUBST(FFILibDir) -AC_SUBST(FFIIncludeDir) - -dnl ** check whether we need -ldl to get dlopen() -AC_CHECK_LIB([dl], [dlopen], UseLibdl=YES, UseLibdl=NO) -AC_SUBST([UseLibdl]) - -dnl ** check for leading underscores in symbol names -FP_LEADING_UNDERSCORE -AC_SUBST([LeadingUnderscore], [`echo $fptools_cv_leading_underscore | sed 'y/yesno/YESNO/'`]) - -dnl ** check for librt -AC_CHECK_LIB([rt], [clock_gettime], UseLibrt=YES, UseLibrt=NO) -AC_SUBST([UseLibrt]) - -FP_CHECK_PTHREAD_LIB -AC_SUBST([UseLibpthread]) - -GHC_ADJUSTORS_METHOD([Target]) -AC_SUBST([UseLibffiForAdjustors]) - -dnl ** IPE data compression -dnl -------------------------------------------------------------- -FP_FIND_LIBZSTD -AC_SUBST(UseLibZstd) -AC_SUBST(UseStaticLibZstd) -AC_SUBST(LibZstdLibDir) -AC_SUBST(LibZstdIncludeDir) - -dnl ** Other RTS features -dnl -------------------------------------------------------------- -FP_FIND_LIBDW -AC_SUBST(UseLibdw) -AC_SUBST(LibdwLibDir) -AC_SUBST(LibdwIncludeDir) - -FP_FIND_LIBNUMA -AC_SUBST(UseLibNuma) -AC_SUBST(LibNumaLibDir) -AC_SUBST(LibNumaIncludeDir) - -dnl ** Documentation -dnl -------------------------------------------------------------- -if test -n "$SPHINXBUILD"; then - BUILD_MAN=YES - BUILD_SPHINX_HTML=YES - if test -n "$XELATEX" -a -n "$MAKEINDEX"; then - BUILD_SPHINX_PDF=YES - else - BUILD_SPHINX_PDF=NO - fi - if test -n "$MAKEINFO"; then - BUILD_SPHINX_INFO=YES - else - BUILD_SPHINX_INFO=NO - fi -else - BUILD_MAN=NO - BUILD_SPHINX_HTML=NO - BUILD_SPHINX_PDF=NO - BUILD_SPHINX_INFO=NO -fi -AC_SUBST(BUILD_MAN) -AC_SUBST(BUILD_SPHINX_HTML) -AC_SUBST(BUILD_SPHINX_PDF) - -if grep ' ' compiler/ghc.cabal.in 2>&1 >/dev/null; then - AC_MSG_ERROR([compiler/ghc.cabal.in contains tab characters; please remove them]) -fi - -# We got caught by -# http://savannah.gnu.org/bugs/index.php?1516 -# $(eval ...) inside conditionals causes errors -# with make 3.80, so warn the user if it looks like they're about to -# try to use it. -# We would use "grep -q" here, but Solaris's grep doesn't support it. -print_make_warning="" -checkMake380() { - make_ver=`$1 --version 2>&1 | head -1` - if echo "$make_ver" | grep 'GNU Make 3\.80' > /dev/null - then - print_make_warning="true" - fi - if echo "$make_ver" | grep 'GNU Make' > /dev/null - then - MakeCmd=$1 - AC_SUBST(MakeCmd) - fi -} - -checkMake380 make -checkMake380 gmake - -# Toolchain target files -FIND_GHC_TOOLCHAIN_BIN([NO]) -PREP_TARGET_FILE -FIND_GHC_TOOLCHAIN([hadrian/cfg]) - -AC_CONFIG_FILES( -[ hadrian/cfg/system.config - hadrian/ghci-cabal - hadrian/ghci-multi-cabal - hadrian/ghci-stack - hadrian/cfg/default.host.target - hadrian/cfg/default.target -]) - -dnl Create the VERSION file, satisfying #22322. -printf "$ProjectVersion" > VERSION AC_OUTPUT -[ -if test "$print_make_warning" = "true"; then - echo - echo "WARNING: It looks like \"$MakeCmd\" is GNU make 3.80." - echo "This version cannot be used to build GHC." - echo "Please use GNU make >= 3.81." -fi - -echo " ----------------------------------------------------------------------- -Configure completed successfully. - - Building GHC version : $ProjectVersion - Git commit id : $ProjectGitCommitId - - Build platform : $BuildPlatform - Host platform : $HostPlatform - Target platform : $TargetPlatform -" - -echo "\ - Bootstrapping using : $WithGhc - which is version : $GhcVersion - with threaded RTS? : $GhcThreadedRts -" - -if test "x$CcLlvmBackend" = "xYES"; then - CompilerName="clang " -else - CompilerName="gcc " -fi - -echo "\ - Using (for bootstrapping) : $CC_STAGE0 - Using $CompilerName : $CC - which is version : $GccVersion - linker options : $GccUseLdOpt - Building a cross compiler : $CrossCompiling - Unregisterised : $Unregisterised - TablesNextToCode : $TablesNextToCode - Build GMP in tree : $GMP_FORCE_INTREE - cpp : $CPPCmd - cpp-flags : $CONF_CPP_OPTS_STAGE2 - hs-cpp : $HaskellCPPCmd - hs-cpp-flags : $HaskellCPPArgs - js-cpp : $JavaScriptCPPCmd - js-cpp-flags : $JavaScriptCPPArgs - cmmcpp : $CmmCPPCmd - cmmcpp-flags : $CmmCPPArgs - cmmcpp-g0 : $CmmCPPSupportsG0 - c++ : $CXX - ar : $ArCmd - nm : $NmCmd - objdump : $ObjdumpCmd - ranlib : $RanlibCmd - otool : $OtoolCmd - install_name_tool : $InstallNameToolCmd - windres : $WindresCmd - genlib : $GenlibCmd - Happy : $HappyCmd ($HappyVersion) - Alex : $AlexCmd ($AlexVersion) - sphinx-build : $SPHINXBUILD - xelatex : $XELATEX - makeinfo : $MAKEINFO - git : $GIT - cabal-install : $CABAL -" - -echo "\ - Using optional dependencies: - libnuma : $UseLibNuma - libzstd : $UseLibZstd - statically linked? : ${UseStaticLibZstd:-N/A} - libdw : $UseLibdw - - Using LLVM tools - llc : $LlcCmd - opt : $OptCmd - llvm-as : $LlvmAsCmd" - -if test "$HSCOLOUR" = ""; then -echo " - HsColour was not found; documentation will not contain source links -" -else -echo "\ - HsColour : $HSCOLOUR -" -fi - -echo "\ - Tools to build Sphinx HTML documentation available: $BUILD_SPHINX_HTML - Tools to build Sphinx PDF documentation available: $BUILD_SPHINX_PDF - Tools to build Sphinx INFO documentation available: $BUILD_SPHINX_INFO" - -echo "---------------------------------------------------------------------- -" - -echo "\ -For a standard build of GHC (fully optimised with profiling), type - ./hadrian/build - -You can customise the build with flags such as - ./hadrian/build -j --flavour=devel2 [--freeze1] - -To make changes to the default build configuration, see the file - hadrian/src/UserSettings.hs - -For more information on how to configure your GHC build, see - https://gitlab.haskell.org/ghc/ghc/-/wikis/building/hadrian -"] - -# Currently we don't validate the /host/ GHC toolchain because configure -# doesn't configure flags and properties for most of the host toolchain -# -# In fact, most values in default.host.target are dummy values since they are -# never used (see default.host.target.in) -# -# When we move to configure toolchains by means of ghc-toolchain only, we'll -# have a correct complete /host/ toolchain rather than an incomplete one, which -# might further unlock things like canadian cross-compilation -# -# VALIDATE_GHC_TOOLCHAIN([default.host.target],[default.host.target.ghc-toolchain]) - -VALIDATE_GHC_TOOLCHAIN([hadrian/cfg/default.target],[hadrian/cfg/default.target.ghc-toolchain]) -rm -Rf acargs acghc-toolchain actmp-ghc-toolchain +# After running ./configure, the following command can be used to see configured values: +# ./config.status --config diff --git a/hie.yaml b/hie.yaml index 34dde0452ad..3248a026222 100644 --- a/hie.yaml +++ b/hie.yaml @@ -1,8 +1,4 @@ -# This is a IDE configuration file which tells IDEs such as `ghcide` how -# to set up a GHC API session for this project. -# -# To use it in windows systems replace the config with -# cradle: {bios: {program: "./hadrian/hie-bios.bat"}} -# -# The format is documented here - https://github.com/mpickering/hie-bios -cradle: {bios: {program: "./hadrian/hie-bios"}} +# This is not perfect but it works ok +cradle: + cabal: + cabalProject: cabal.project.stage1 \ No newline at end of file From c16b25ad3f49d76fc4e3e2df930cca82d57bdbd3 Mon Sep 17 00:00:00 2001 From: Stable Haskell Team Date: Thu, 28 Aug 2025 20:19:52 +0900 Subject: [PATCH 2/3] feat: Modularize RTS and extract headers/filesystem utilities This commit restructures the Runtime System (RTS) components for better modularity and reusability across different build configurations. The changes enable cleaner separation of concerns and improved support for cross-compilation scenarios. Key changes: - Extract RTS headers into standalone rts-headers package * Moved include/rts/Bytecodes.h to rts-headers * Moved include/rts/storage/ClosureTypes.h to rts-headers * Moved include/rts/storage/FunTypes.h to rts-headers * Moved include/stg/MachRegs/* to rts-headers - Create rts-fs package for filesystem utilities * Extracted filesystem code from utils/fs * Provides reusable filesystem operations for RTS - Rename utils/iserv to utils/ghc-iserv for consistency * Better naming alignment with other GHC utilities * Updated all references throughout the codebase - Update RTS configuration and build files * Modified rts/configure.ac for new structure * Updated rts.cabal with new dependencies * Adjusted .gitignore for new artifacts Rationale: The modularization allows different stages of the compiler build to share common RTS components without circular dependencies. This is particularly important for: - Cross-compilation where host and target RTS differ - JavaScript backend which needs selective RTS components - Stage1/Stage2 builds that require different RTS configurations Contributors: - Moritz Angermann: RTS modularization architecture and implementation - Sylvain Henry: JavaScript backend RTS adjustments - Andrea Bedini: Build system integration This refactoring maintains full backward compatibility while providing a cleaner foundation for multi-target support. --- compiler/GHC/Driver/Main.hs | 4 +- compiler/GHC/Driver/Pipeline.hs | 12 +- compiler/GHC/Runtime/Heap/Layout.hs | 4 +- compiler/GHC/StgToCmm/Layout.hs | 2 +- compiler/GHC/StgToCmm/TagCheck.hs | 2 +- rts-fs/README | 2 + rts-fs/fs.c | 590 +++++++++ rts-fs/fs.h | 55 + rts-fs/rts-fs.cabal | 17 + {rts => rts-headers}/include/rts/Bytecodes.h | 0 .../include/rts/storage/ClosureTypes.h | 0 .../include/rts/storage/FunTypes.h | 0 {rts => rts-headers}/include/stg/MachRegs.h | 0 .../include/stg/MachRegs/arm32.h | 0 .../include/stg/MachRegs/arm64.h | 0 .../include/stg/MachRegs/loongarch64.h | 0 .../include/stg/MachRegs/ppc.h | 0 .../include/stg/MachRegs/riscv64.h | 0 .../include/stg/MachRegs/s390x.h | 0 .../include/stg/MachRegs/wasm32.h | 0 .../include/stg/MachRegs/x86.h | 0 rts-headers/rts-headers.cabal | 31 + rts/.gitignore | 1 - rts/configure.ac | 110 ++ rts/include/stg/MachRegsForHost.h | 2 +- rts/rts.cabal | 1156 ++++++++++------- utils/{iserv => ghc-iserv}/cbits/iservmain.c | 0 utils/ghc-iserv/ghc-iserv.cabal | 44 + .../ghc-iserv.cabal.in} | 10 +- utils/{iserv => ghc-iserv}/src/Main.hs | 0 30 files changed, 1562 insertions(+), 480 deletions(-) create mode 100644 rts-fs/README create mode 100644 rts-fs/fs.c create mode 100644 rts-fs/fs.h create mode 100644 rts-fs/rts-fs.cabal rename {rts => rts-headers}/include/rts/Bytecodes.h (100%) rename {rts => rts-headers}/include/rts/storage/ClosureTypes.h (100%) rename {rts => rts-headers}/include/rts/storage/FunTypes.h (100%) rename {rts => rts-headers}/include/stg/MachRegs.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/arm32.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/arm64.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/loongarch64.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/ppc.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/riscv64.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/s390x.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/wasm32.h (100%) rename {rts => rts-headers}/include/stg/MachRegs/x86.h (100%) create mode 100644 rts-headers/rts-headers.cabal rename utils/{iserv => ghc-iserv}/cbits/iservmain.c (100%) create mode 100644 utils/ghc-iserv/ghc-iserv.cabal rename utils/{iserv/iserv.cabal.in => ghc-iserv/ghc-iserv.cabal.in} (85%) rename utils/{iserv => ghc-iserv}/src/Main.hs (100%) diff --git a/compiler/GHC/Driver/Main.hs b/compiler/GHC/Driver/Main.hs index a81afa0803b..a094a98bd6d 100644 --- a/compiler/GHC/Driver/Main.hs +++ b/compiler/GHC/Driver/Main.hs @@ -1299,7 +1299,7 @@ hscDesugarAndSimplify summary (FrontendTypecheck tc_result) tc_warnings mb_old_h -- when compiling gHC_PRIM without generating code (e.g. with -- Haddock), we still want the virtual interface in the cache if ms_mod summary == gHC_PRIM - then return $ HscUpdate (getGhcPrimIface hsc_env) + then return $ HscUpdate (getGhcPrimIface (hsc_hooks hsc_env)) else return $ HscUpdate iface @@ -1314,7 +1314,7 @@ hscDesugarAndSimplify summary (FrontendTypecheck tc_result) tc_warnings mb_old_h -- when compiling gHC_PRIM without generating code (e.g. with -- Haddock), we still want the virtual interface in the cache if ms_mod summary == gHC_PRIM - then return $ HscUpdate (getGhcPrimIface hsc_env) + then return $ HscUpdate (getGhcPrimIface (hsc_hooks hsc_env)) else return $ HscUpdate iface {- diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs index ea01b4e10fc..8885b40f577 100644 --- a/compiler/GHC/Driver/Pipeline.hs +++ b/compiler/GHC/Driver/Pipeline.hs @@ -44,11 +44,14 @@ module GHC.Driver.Pipeline ( import GHC.Prelude +import GHC.Builtin.Names import GHC.Platform import GHC.Utils.Monad ( MonadIO(liftIO), mapMaybeM ) +import GHC.Builtin.Names + import GHC.Driver.Main import GHC.Driver.Env hiding ( Hsc ) import GHC.Driver.Errors @@ -91,6 +94,7 @@ import GHC.Data.StringBuffer ( hPutStringBuffer ) import GHC.Data.Maybe ( expectJust ) import GHC.Iface.Make ( mkFullIface ) +import GHC.Iface.Load ( getGhcPrimIface ) import GHC.Runtime.Loader ( initializePlugins ) @@ -819,7 +823,13 @@ hscGenBackendPipeline pipe_env hsc_env mod_sum result = do let !linkable = Linkable part_time (ms_mod mod_sum) (NE.singleton (DotO final_object ModuleObject)) -- Add the object linkable to the potential bytecode linkable which was generated in HscBackend. return (mlinkable { homeMod_object = Just linkable }) - return (miface, final_linkable) + + -- when building ghc-internal with --make (e.g. with cabal-install), we want + -- the virtual interface for gHC_PRIM in the cache, not the empty one. + let miface_final + | ms_mod mod_sum == gHC_PRIM = getGhcPrimIface (hsc_hooks hsc_env) + | otherwise = miface + return (miface_final, final_linkable) asPipeline :: P m => Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> m (Maybe ObjFile) asPipeline use_cpp pipe_env hsc_env location input_fn = diff --git a/compiler/GHC/Runtime/Heap/Layout.hs b/compiler/GHC/Runtime/Heap/Layout.hs index 73e2ff9e410..e0956185a59 100644 --- a/compiler/GHC/Runtime/Heap/Layout.hs +++ b/compiler/GHC/Runtime/Heap/Layout.hs @@ -438,8 +438,8 @@ cardTableSizeW platform elems = ----------------------------------------------------------------------------- -- deriving the RTS closure type from an SMRep -#include "ClosureTypes.h" -#include "FunTypes.h" +#include "rts/storage/ClosureTypes.h" +#include "rts/storage/FunTypes.h" -- Defines CONSTR, CONSTR_1_0 etc -- | Derives the RTS closure type from an 'SMRep' diff --git a/compiler/GHC/StgToCmm/Layout.hs b/compiler/GHC/StgToCmm/Layout.hs index 2f81200a289..b93dc185408 100644 --- a/compiler/GHC/StgToCmm/Layout.hs +++ b/compiler/GHC/StgToCmm/Layout.hs @@ -549,7 +549,7 @@ mkVirtConstrSizes profile field_reps ------------------------------------------------------------------------- -- bring in ARG_P, ARG_N, etc. -#include "FunTypes.h" +#include "rts/storage/FunTypes.h" mkArgDescr :: Platform -> [Id] -> ArgDescr mkArgDescr platform args diff --git a/compiler/GHC/StgToCmm/TagCheck.hs b/compiler/GHC/StgToCmm/TagCheck.hs index 5b3cf2e7e1e..18fd617c000 100644 --- a/compiler/GHC/StgToCmm/TagCheck.hs +++ b/compiler/GHC/StgToCmm/TagCheck.hs @@ -12,7 +12,7 @@ module GHC.StgToCmm.TagCheck ( emitTagAssertion, emitArgTagCheck, checkArg, whenCheckTags, checkArgStatic, checkFunctionArgTags,checkConArgsStatic,checkConArgsDyn) where -#include "ClosureTypes.h" +#include "rts/storage/ClosureTypes.h" import GHC.Prelude diff --git a/rts-fs/README b/rts-fs/README new file mode 100644 index 00000000000..446f95e9ece --- /dev/null +++ b/rts-fs/README @@ -0,0 +1,2 @@ +This "fs" library, used by various ghc utilities is used to share some common +I/O filesystem functions with different packages. diff --git a/rts-fs/fs.c b/rts-fs/fs.c new file mode 100644 index 00000000000..d64094cae15 --- /dev/null +++ b/rts-fs/fs.c @@ -0,0 +1,590 @@ +/* ----------------------------------------------------------------------------- + * + * (c) Tamar Christina 2018-2019 + * + * Windows I/O routines for file opening. + * + * NOTE: Only modify this file in utils/fs/ and rerun configure. Do not edit + * this file in any other directory as it will be overwritten. + * + * ---------------------------------------------------------------------------*/ +#include "fs.h" +#include + +#if defined(_WIN32) + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Duplicate a string, but in wide form. The caller is responsible for freeing + the result. */ +static wchar_t* FS(to_wide) (const char *path) { + size_t len = mbstowcs (NULL, path, 0); + wchar_t *w_path = malloc (sizeof (wchar_t) * (len + 1)); + mbstowcs (w_path, path, len); + w_path[len] = L'\0'; + return w_path; +} + +/* This function converts Windows paths between namespaces. More specifically + It converts an explorer style path into a NT or Win32 namespace. + This has several caveats but they are caveats that are native to Windows and + not POSIX. See + https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx. + Anything else such as raw device paths we leave untouched. The main benefit + of doing any of this is that we can break the MAX_PATH restriction and also + access raw handles that we couldn't before. + + The resulting string is dynamically allocated and so callers are expected to + free this string. */ +wchar_t* FS(create_device_name) (const wchar_t* filename) { + const wchar_t* win32_dev_namespace = L"\\\\.\\"; + const wchar_t* win32_file_namespace = L"\\\\?\\"; + const wchar_t* nt_device_namespace = L"\\Device\\"; + const wchar_t* unc_prefix = L"UNC\\"; + const wchar_t* network_share = L"\\\\"; + + wchar_t* result = _wcsdup (filename); + wchar_t ns[10] = {0}; + + /* If the file is already in a native namespace don't change it. */ + if ( wcsncmp (win32_dev_namespace , filename, 4) == 0 + || wcsncmp (win32_file_namespace, filename, 4) == 0 + || wcsncmp (nt_device_namespace , filename, 8) == 0) + return result; + + /* Since we're using the lower level APIs we must normalize slashes now. The + Win32 API layer will no longer convert '/' into '\\' for us. */ + for (size_t i = 0; i < wcslen (result); i++) + { + if (result[i] == L'/') + result[i] = L'\\'; + } + + /* We need to expand dos short paths as well. */ + DWORD nResult = GetLongPathNameW (result, NULL, 0) + 1; + wchar_t* temp = NULL; + if (nResult > 1) + { + temp = _wcsdup (result); + free (result); + result = malloc (nResult * sizeof (wchar_t)); + if (GetLongPathNameW (temp, result, nResult) == 0) + { + result = memcpy (result, temp, wcslen (temp)); + goto cleanup; + } + free (temp); + } + + /* Now resolve any . and .. in the path or subsequent API calls may fail since + Win32 will no longer resolve them. */ + nResult = GetFullPathNameW (result, 0, NULL, NULL) + 1; + temp = _wcsdup (result); + free (result); + result = malloc (nResult * sizeof (wchar_t)); + if (GetFullPathNameW (temp, nResult, result, NULL) == 0) + { + result = memcpy (result, temp, wcslen (temp)); + goto cleanup; + } + + free (temp); + + int startOffset = 0; + /* When remapping a network share, \\foo needs to become + \\?\UNC\foo and not \\?\\UNC\\foo which is an invalid path. */ + if (wcsncmp (network_share, result, 2) == 0) + { + if (swprintf (ns, 10, L"%ls%ls", win32_file_namespace, unc_prefix) <= 0) + { + goto cleanup; + } + startOffset = 2; + } + else if (swprintf (ns, 10, L"%ls", win32_file_namespace) <= 0) + { + goto cleanup; + } + + /* Create new string. */ + int bLen = wcslen (result) + wcslen (ns) + 1 - startOffset; + temp = _wcsdup (result + startOffset); + free (result); + result = malloc (bLen * sizeof (wchar_t)); + if (swprintf (result, bLen, L"%ls%ls", ns, temp) <= 0) + { + goto cleanup; + } + + free (temp); + + return result; + +cleanup: + free (temp); + free (result); + return NULL; +} + +static int setErrNoFromWin32Error (void); +/* Sets errno to the right error value and returns -1 to indicate the failure. + This function should only be called when the creation of the fd actually + failed and you want to return -1 for the fd. */ +static +int setErrNoFromWin32Error (void) { + switch (GetLastError()) { + case ERROR_SUCCESS: + errno = 0; + break; + case ERROR_ACCESS_DENIED: + case ERROR_FILE_READ_ONLY: + errno = EACCES; + break; + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + errno = ENOENT; + break; + case ERROR_FILE_EXISTS: + errno = EEXIST; + break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_OUTOFMEMORY: + errno = ENOMEM; + break; + case ERROR_INVALID_HANDLE: + errno = EBADF; + break; + case ERROR_INVALID_FUNCTION: + errno = EFAULT; + break; + default: + errno = EINVAL; + break; + } + return -1; +} + + +#define HAS_FLAG(a,b) (((a) & (b)) == (b)) + +int FS(swopen) (const wchar_t* filename, int oflag, int shflag, int pmode) +{ + /* Construct access mode. */ + /* https://docs.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants */ + DWORD dwDesiredAccess = 0; + if (HAS_FLAG (oflag, _O_RDONLY)) + dwDesiredAccess |= GENERIC_READ; + if (HAS_FLAG (oflag, _O_RDWR)) + dwDesiredAccess |= GENERIC_WRITE | GENERIC_READ; + if (HAS_FLAG (oflag, _O_WRONLY)) + dwDesiredAccess |= GENERIC_WRITE; + if (HAS_FLAG (oflag, _O_APPEND)) + dwDesiredAccess |= FILE_APPEND_DATA; + + /* Construct shared mode. */ + /* https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants */ + DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + if (HAS_FLAG (shflag, _SH_DENYRW)) + dwShareMode &= ~(FILE_SHARE_READ | FILE_SHARE_WRITE); + if (HAS_FLAG (shflag, _SH_DENYWR)) + dwShareMode &= ~FILE_SHARE_WRITE; + if (HAS_FLAG (shflag, _SH_DENYRD)) + dwShareMode &= ~FILE_SHARE_READ; + if (HAS_FLAG (pmode, _S_IWRITE)) + dwShareMode |= FILE_SHARE_READ | FILE_SHARE_WRITE; + if (HAS_FLAG (pmode, _S_IREAD)) + dwShareMode |= FILE_SHARE_READ; + + /* Override access mode with pmode if creating file. */ + if (HAS_FLAG (oflag, _O_CREAT)) + { + if (HAS_FLAG (pmode, _S_IWRITE)) + dwDesiredAccess |= FILE_GENERIC_WRITE; + if (HAS_FLAG (pmode, _S_IREAD)) + dwDesiredAccess |= FILE_GENERIC_READ; + } + + /* Create file disposition. */ + /* https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea */ + DWORD dwCreationDisposition = 0; + if (HAS_FLAG (oflag, (_O_CREAT | _O_EXCL))) + dwCreationDisposition |= CREATE_NEW; + else if (HAS_FLAG (oflag, _O_TRUNC | _O_CREAT)) + dwCreationDisposition |= CREATE_ALWAYS; + else if (HAS_FLAG (oflag, _O_TRUNC) && !HAS_FLAG (oflag, O_RDONLY)) + dwCreationDisposition |= TRUNCATE_EXISTING; + else if (HAS_FLAG (oflag, _O_APPEND | _O_CREAT)) + dwCreationDisposition |= OPEN_ALWAYS; + else if (HAS_FLAG (oflag, _O_APPEND)) + dwCreationDisposition |= OPEN_EXISTING; + else if (HAS_FLAG (oflag, _O_CREAT)) + dwCreationDisposition |= OPEN_ALWAYS; + else + dwCreationDisposition |= OPEN_EXISTING; + + /* Set file access attributes. */ + DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; + if (HAS_FLAG (oflag, _O_RDONLY)) + dwFlagsAndAttributes |= 0; /* No special attribute. */ + if (HAS_FLAG (oflag, _O_TEMPORARY)) + { + dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; + dwShareMode |= FILE_SHARE_DELETE; + } + if (HAS_FLAG (oflag, _O_SHORT_LIVED)) + dwFlagsAndAttributes |= FILE_ATTRIBUTE_TEMPORARY; + if (HAS_FLAG (oflag, _O_RANDOM)) + dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; + if (HAS_FLAG (oflag, _O_SEQUENTIAL)) + dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; + /* Flag is only valid on it's own. */ + if (dwFlagsAndAttributes != FILE_ATTRIBUTE_NORMAL) + dwFlagsAndAttributes &= ~FILE_ATTRIBUTE_NORMAL; + + /* Ensure we have shared read for files which are opened read-only. */ + if (HAS_FLAG (dwCreationDisposition, OPEN_EXISTING) + && ((dwDesiredAccess & (GENERIC_WRITE|GENERIC_READ)) == GENERIC_READ)) + dwShareMode |= FILE_SHARE_READ; + + /* Set security attributes. */ + SECURITY_ATTRIBUTES securityAttributes; + ZeroMemory (&securityAttributes, sizeof(SECURITY_ATTRIBUTES)); + securityAttributes.bInheritHandle = !(oflag & _O_NOINHERIT); + securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + + wchar_t* _filename = FS(create_device_name) (filename); + if (!_filename) + return -1; + + HANDLE hResult + = CreateFileW (_filename, dwDesiredAccess, dwShareMode, &securityAttributes, + dwCreationDisposition, dwFlagsAndAttributes, NULL); + + free (_filename); + if (INVALID_HANDLE_VALUE == hResult) + return setErrNoFromWin32Error (); + + /* Now we have a Windows handle, we have to convert it to an FD and apply + the remaining flags. */ + const int flag_mask = _O_APPEND | _O_RDONLY | _O_TEXT | _O_WTEXT; + int fd = _open_osfhandle ((intptr_t)hResult, oflag & flag_mask); + if (-1 == fd) + return setErrNoFromWin32Error (); + + /* Finally we can change the mode to the requested one. */ + const int mode_mask = _O_TEXT | _O_BINARY | _O_U16TEXT | _O_U8TEXT | _O_WTEXT; + if ((oflag & mode_mask) && (-1 == _setmode (fd, oflag & mode_mask))) + return setErrNoFromWin32Error (); + + return fd; +} + +int FS(translate_mode) (const wchar_t* mode) +{ + int oflag = 0; + int len = wcslen (mode); + int i; + #define IS_EXT(X) ((i < (len - 1)) && mode[i+1] == X) + + for (i = 0; i < len; i++) + { + switch (mode[i]) + { + case L'a': + if (IS_EXT (L'+')) + oflag |= _O_RDWR | _O_CREAT | _O_APPEND; + else + oflag |= _O_WRONLY | _O_CREAT | _O_APPEND; + break; + case L'r': + if (IS_EXT (L'+')) + oflag |= _O_RDWR; + else + oflag |= _O_RDONLY; + break; + case L'w': + if (IS_EXT (L'+')) + oflag |= _O_RDWR | _O_CREAT | _O_TRUNC; + else + oflag |= _O_WRONLY | _O_CREAT | _O_TRUNC; + break; + case L'b': + oflag |= _O_BINARY; + break; + case L't': + oflag |= _O_TEXT; + break; + case L'c': + case L'n': + oflag |= 0; + break; + case L'S': + oflag |= _O_SEQUENTIAL; + break; + case L'R': + oflag |= _O_RANDOM; + break; + case L'T': + oflag |= _O_SHORT_LIVED; + break; + case L'D': + oflag |= _O_TEMPORARY; + break; + default: + if (wcsncmp (mode, L"ccs=UNICODE", 11) == 0) + oflag |= _O_WTEXT; + else if (wcsncmp (mode, L"ccs=UTF-8", 9) == 0) + oflag |= _O_U8TEXT; + else if (wcsncmp (mode, L"ccs=UTF-16LE", 12) == 0) + oflag |= _O_U16TEXT; + else continue; + } + } + #undef IS_EXT + + return oflag; +} + +FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode) +{ + int shflag = 0; + int pmode = 0; + int oflag = FS(translate_mode) (mode); + + int fd = FS(swopen) (filename, oflag, shflag, pmode); + if (fd < 0) + return NULL; + + FILE* file = _wfdopen (fd, mode); + return file; +} + +FILE *FS(fopen) (const char* filename, const char* mode) +{ + wchar_t * const w_filename = FS(to_wide) (filename); + wchar_t * const w_mode = FS(to_wide) (mode); + + FILE *result = FS(fwopen) (w_filename, w_mode); + free (w_filename); + free (w_mode); + + return result; +} + +int FS(sopen) (const char* filename, int oflag, int shflag, int pmode) +{ + wchar_t * const w_filename = FS(to_wide) (filename); + int result = FS(swopen) (w_filename, oflag, shflag, pmode); + free (w_filename); + + return result; +} + +int FS(_stat) (const char *path, struct _stat *buffer) +{ + wchar_t * const w_path = FS(to_wide) (path); + int result = FS(_wstat) (w_path, buffer); + free (w_path); + + return result; +} + +int FS(_stat64) (const char *path, struct __stat64 *buffer) +{ + wchar_t * const w_path = FS(to_wide) (path); + int result = FS(_wstat64) (w_path, buffer); + free (w_path); + + return result; +} + +static __time64_t ftToPosix(FILETIME ft) +{ + /* takes the last modified date. */ + LARGE_INTEGER date, adjust; + date.HighPart = ft.dwHighDateTime; + date.LowPart = ft.dwLowDateTime; + + /* 100-nanoseconds = milliseconds * 10000. */ + /* A UNIX timestamp contains the number of seconds from Jan 1, 1970, while the + FILETIME documentation says: Contains a 64-bit value representing the + number of 100-nanosecond intervals since January 1, 1601 (UTC). + + Between Jan 1, 1601 and Jan 1, 1970 there are 11644473600 seconds */ + adjust.QuadPart = 11644473600000 * 10000; + + /* removes the diff between 1970 and 1601. */ + date.QuadPart -= adjust.QuadPart; + + /* converts back from 100-nanoseconds to seconds. */ + return (__time64_t)date.QuadPart / 10000000; +} + +int FS(_wstat) (const wchar_t *path, struct _stat *buffer) +{ + ZeroMemory (buffer, sizeof (struct _stat)); + wchar_t* _path = FS(create_device_name) (path); + if (!_path) + return -1; + + /* Construct shared mode. */ + DWORD dwShareMode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE; + DWORD dwDesiredAccess = FILE_READ_ATTRIBUTES; + DWORD dwFlagsAndAttributes = FILE_FLAG_BACKUP_SEMANTICS; + DWORD dwCreationDisposition = OPEN_EXISTING; + + SECURITY_ATTRIBUTES securityAttributes; + ZeroMemory (&securityAttributes, sizeof(SECURITY_ATTRIBUTES)); + securityAttributes.bInheritHandle = false; + securityAttributes.lpSecurityDescriptor = NULL; + securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + + HANDLE hResult + = CreateFileW (_path, dwDesiredAccess, dwShareMode, &securityAttributes, + dwCreationDisposition, dwFlagsAndAttributes, NULL); + + if (INVALID_HANDLE_VALUE == hResult) + { + free (_path); + return setErrNoFromWin32Error (); + } + + WIN32_FILE_ATTRIBUTE_DATA finfo; + ZeroMemory (&finfo, sizeof (WIN32_FILE_ATTRIBUTE_DATA)); + if(!GetFileAttributesExW (_path, GetFileExInfoStandard, &finfo)) + { + free (_path); + CloseHandle (hResult); + return setErrNoFromWin32Error (); + } + + unsigned short mode = _S_IREAD; + + if (finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + mode |= (_S_IFDIR | _S_IEXEC); + else + { + mode |= _S_IFREG; + DWORD type; + if (GetBinaryTypeW (_path, &type)) + mode |= _S_IEXEC; + } + + if (!(finfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + mode |= _S_IWRITE; + + buffer->st_mode = mode; + buffer->st_nlink = 1; + buffer->st_size = ((uint64_t)finfo.nFileSizeHigh << 32) + finfo.nFileSizeLow; + buffer->st_atime = ftToPosix (finfo.ftLastAccessTime); + buffer->st_mtime = buffer->st_ctime = ftToPosix (finfo.ftLastWriteTime); + free (_path); + CloseHandle (hResult); + return 0; +} + +int FS(_wstat64) (const wchar_t *path, struct __stat64 *buffer) +{ + struct _stat buf; + ZeroMemory (buffer, sizeof (struct __stat64)); + + int result = FS(_wstat) (path, &buf); + + buffer->st_mode = buf.st_mode; + buffer->st_nlink = 1; + buffer->st_size = buf.st_size; + buffer->st_atime = buf.st_atime; + buffer->st_mtime = buf.st_mtime; + + return result; +} + +int FS(_wrename) (const wchar_t *from, const wchar_t *to) +{ + wchar_t* const _from = FS(create_device_name) (from); + if (!_from) + return -1; + + wchar_t* const _to = FS(create_device_name) (to); + if (!_to) + { + free (_from); + return -1; + } + + if (MoveFileW(_from, _to) == 0) { + free (_from); + free (_to); + return setErrNoFromWin32Error (); + } + + + free (_from); + free (_to); + return 0; +} + +int FS(rename) (const char *from, const char *to) +{ + wchar_t * const w_from = FS(to_wide) (from); + wchar_t * const w_to = FS(to_wide) (to); + int result = FS(_wrename) (w_from, w_to); + free(w_from); + free(w_to); + + return result; +} + +int FS(unlink) (const char *filename) +{ + return FS(_unlink) (filename); +} + +int FS(_unlink) (const char *filename) +{ + wchar_t * const w_filename = FS(to_wide) (filename); + int result = FS(_wunlink) (w_filename); + free(w_filename); + + return result; +} + +int FS(_wunlink) (const wchar_t *filename) +{ + wchar_t* const _filename = FS(create_device_name) (filename); + if (!_filename) + return -1; + + if (DeleteFileW(_filename) == 0) { + free (_filename); + return setErrNoFromWin32Error (); + } + + + free (_filename); + return 0; +} +int FS(remove) (const char *path) +{ + return FS(_unlink) (path); +} +int FS(_wremove) (const wchar_t *path) +{ + return FS(_wunlink) (path); +} +#else +FILE *FS(fopen) (const char* filename, const char* mode) +{ + return fopen (filename, mode); +} +#endif diff --git a/rts-fs/fs.h b/rts-fs/fs.h new file mode 100644 index 00000000000..6c5f56ccdd7 --- /dev/null +++ b/rts-fs/fs.h @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------------- + * + * (c) Tamar Christina 2018-2019 + * + * Windows I/O routines for file opening. + * + * NOTE: Only modify this file in utils/fs/ and rerun configure. Do not edit + * this file in any other directory as it will be overwritten. + * + * ---------------------------------------------------------------------------*/ + +#pragma once + +#include + +#if !defined(FS_NAMESPACE) +#define FS_NAMESPACE hs +#endif + +/* Play some dirty tricks to get CPP to expand correctly. */ +#define FS_FULL(ns, name) __##ns##_##name +#define prefix FS_NAMESPACE +#define FS_L(p, n) FS_FULL(p, n) +#define FS(name) FS_L(prefix, name) + +#if defined(_WIN32) +#include +// N.B. defines some macro rewrites to, e.g., turn _wstat into +// _wstat64i32. We must include it here to ensure tat this rewrite applies to +// both the definition and use sites. +#include +#include + +wchar_t* FS(create_device_name) (const wchar_t*); +int FS(translate_mode) (const wchar_t*); +int FS(swopen) (const wchar_t* filename, int oflag, + int shflag, int pmode); +int FS(sopen) (const char* filename, int oflag, + int shflag, int pmode); +FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode); +FILE *FS(fopen) (const char* filename, const char* mode); +int FS(_stat) (const char *path, struct _stat *buffer); +int FS(_stat64) (const char *path, struct __stat64 *buffer); +int FS(_wstat) (const wchar_t *path, struct _stat *buffer); +int FS(_wstat64) (const wchar_t *path, struct __stat64 *buffer); +int FS(_wrename) (const wchar_t *from, const wchar_t *to); +int FS(rename) (const char *from, const char *to); +int FS(unlink) (const char *filename); +int FS(_unlink) (const char *filename); +int FS(_wunlink) (const wchar_t *filename); +int FS(remove) (const char *path); +int FS(_wremove) (const wchar_t *path); +#else +FILE *FS(fopen) (const char* filename, const char* mode); +#endif diff --git a/rts-fs/rts-fs.cabal b/rts-fs/rts-fs.cabal new file mode 100644 index 00000000000..f013754d3f4 --- /dev/null +++ b/rts-fs/rts-fs.cabal @@ -0,0 +1,17 @@ +cabal-version: 3.0 +name: rts-fs +version: 1.0.0.0 +license: NONE +author: Andrea Bedini +maintainer: andrea@andreabedini.com +build-type: Simple +extra-doc-files: README +extra-source-files: fs.h + +library + cc-options: -DFS_NAMESPACE=rts -DCOMPILING_RTS + cpp-options: -DFS_NAMESPACE=rts -DCOMPILING_RTS + c-sources: fs.c + include-dirs: . + install-includes: fs.h + default-language: Haskell2010 diff --git a/rts/include/rts/Bytecodes.h b/rts-headers/include/rts/Bytecodes.h similarity index 100% rename from rts/include/rts/Bytecodes.h rename to rts-headers/include/rts/Bytecodes.h diff --git a/rts/include/rts/storage/ClosureTypes.h b/rts-headers/include/rts/storage/ClosureTypes.h similarity index 100% rename from rts/include/rts/storage/ClosureTypes.h rename to rts-headers/include/rts/storage/ClosureTypes.h diff --git a/rts/include/rts/storage/FunTypes.h b/rts-headers/include/rts/storage/FunTypes.h similarity index 100% rename from rts/include/rts/storage/FunTypes.h rename to rts-headers/include/rts/storage/FunTypes.h diff --git a/rts/include/stg/MachRegs.h b/rts-headers/include/stg/MachRegs.h similarity index 100% rename from rts/include/stg/MachRegs.h rename to rts-headers/include/stg/MachRegs.h diff --git a/rts/include/stg/MachRegs/arm32.h b/rts-headers/include/stg/MachRegs/arm32.h similarity index 100% rename from rts/include/stg/MachRegs/arm32.h rename to rts-headers/include/stg/MachRegs/arm32.h diff --git a/rts/include/stg/MachRegs/arm64.h b/rts-headers/include/stg/MachRegs/arm64.h similarity index 100% rename from rts/include/stg/MachRegs/arm64.h rename to rts-headers/include/stg/MachRegs/arm64.h diff --git a/rts/include/stg/MachRegs/loongarch64.h b/rts-headers/include/stg/MachRegs/loongarch64.h similarity index 100% rename from rts/include/stg/MachRegs/loongarch64.h rename to rts-headers/include/stg/MachRegs/loongarch64.h diff --git a/rts/include/stg/MachRegs/ppc.h b/rts-headers/include/stg/MachRegs/ppc.h similarity index 100% rename from rts/include/stg/MachRegs/ppc.h rename to rts-headers/include/stg/MachRegs/ppc.h diff --git a/rts/include/stg/MachRegs/riscv64.h b/rts-headers/include/stg/MachRegs/riscv64.h similarity index 100% rename from rts/include/stg/MachRegs/riscv64.h rename to rts-headers/include/stg/MachRegs/riscv64.h diff --git a/rts/include/stg/MachRegs/s390x.h b/rts-headers/include/stg/MachRegs/s390x.h similarity index 100% rename from rts/include/stg/MachRegs/s390x.h rename to rts-headers/include/stg/MachRegs/s390x.h diff --git a/rts/include/stg/MachRegs/wasm32.h b/rts-headers/include/stg/MachRegs/wasm32.h similarity index 100% rename from rts/include/stg/MachRegs/wasm32.h rename to rts-headers/include/stg/MachRegs/wasm32.h diff --git a/rts/include/stg/MachRegs/x86.h b/rts-headers/include/stg/MachRegs/x86.h similarity index 100% rename from rts/include/stg/MachRegs/x86.h rename to rts-headers/include/stg/MachRegs/x86.h diff --git a/rts-headers/rts-headers.cabal b/rts-headers/rts-headers.cabal new file mode 100644 index 00000000000..6d1b89a7ca3 --- /dev/null +++ b/rts-headers/rts-headers.cabal @@ -0,0 +1,31 @@ +cabal-version: 3.4 +name: rts-headers +version: 1.0.3 +synopsis: The GHC runtime system +description: + The GHC runtime system. + + Code produced by GHC links this library to provide missing functionality + that cannot be written in Haskell itself. +license: BSD-3-Clause +maintainer: glasgow-haskell-users@haskell.org +build-type: Simple + + +library + include-dirs: + include + + install-includes: + rts/Bytecodes.h + rts/storage/ClosureTypes.h + rts/storage/FunTypes.h + stg/MachRegs.h + stg/MachRegs/arm32.h + stg/MachRegs/arm64.h + stg/MachRegs/loongarch64.h + stg/MachRegs/ppc.h + stg/MachRegs/riscv64.h + stg/MachRegs/s390x.h + stg/MachRegs/wasm32.h + stg/MachRegs/x86.h diff --git a/rts/.gitignore b/rts/.gitignore index 179d62d55cf..f1a295e18db 100644 --- a/rts/.gitignore +++ b/rts/.gitignore @@ -8,7 +8,6 @@ /package.conf.inplace.raw /package.conf.install /package.conf.install.raw -/fs.* /aclocal.m4 /autom4te.cache/ diff --git a/rts/configure.ac b/rts/configure.ac index e9181aaf552..27d02fb3273 100644 --- a/rts/configure.ac +++ b/rts/configure.ac @@ -520,3 +520,113 @@ cat $srcdir/rts.buildinfo.in \ || exit 1 rm -f external-symbols.flags ] + +dnl -------------------------------------------------------------- +dnl Generate derived constants +dnl -------------------------------------------------------------- + +AC_ARG_VAR([NM], [Path to the nm program]) +AC_PATH_PROG([NM], nm) +if test -z "$NM"; then + AC_MSG_ERROR([Cannot find nm]) +fi + +AC_ARG_VAR([OBJDUMP], [Path to the objdump program]) +AC_PATH_PROG([OBJDUMP], objdump) +if test -z "$OBJDUMP"; then + AC_MSG_ERROR([Cannot find objdump]) +fi + +AC_ARG_VAR([DERIVE_CONSTANTS], [Path to the deriveConstants program]) +AC_PATH_PROG([DERIVE_CONSTANTS], deriveConstants) +AS_IF([test "x$DERIVE_CONSTANTS" = x], [AC_MSG_ERROR([deriveConstants executable not found. Please install deriveConstants or set DERIVE_CONSTANTS environment variable.])]) + +AC_ARG_VAR([GENAPPLY], [Path to the genapply program]) +AC_PATH_PROG([GENAPPLY], genapply) +AS_IF([test "x$GENAPPLY" = x], [AC_MSG_ERROR([genapply executable not found. Please install genapply or set GENAPPLY environment variable.])]) + +AC_CHECK_PROGS([PYTHON], [python3 python python2]) +AS_IF([test "x$PYTHON" = x], [AC_MSG_ERROR([Python interpreter not found. Please install Python or set PYTHON environment variable.])]) + +AC_MSG_CHECKING([for DerivedConstants.h]) +dnl NOTE: dnl pass `-fcommon` to force symbols into the common section. If they end +dnl up in the ro data section `nm` won't list their size, and thus derivedConstants +dnl will fail. Recent clang (e.g. 16) will by default use `-fno-common`. +dnl +dnl FIXME: using a relative path here is TERRIBLE; Cabal should provide some +dnl env var for _build-dependencies_ headers! +dnl + +if $DERIVE_CONSTANTS \ + --gen-header \ + -o include/DerivedConstants.h \ + --target-os "$HostOS_CPP" \ + --gcc-program "$CC" \ + --nm-program "$NM" \ + --objdump-program "$OBJDUMP" \ + --tmpdir "$(mktemp -d)" \ + --gcc-flag "-fcommon" \ + --gcc-flag "-I$srcdir" \ + --gcc-flag "-I$srcdir/include" \ + --gcc-flag "-Iinclude" \ + --gcc-flag "-I$srcdir/../rts-headers/include" ; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $DERIVE_CONSTANTS --gen-header ...]) +fi + +AC_MSG_CHECKING([for AutoApply.cmm]) +if $GENAPPLY include/DerivedConstants.h > AutoApply.cmm; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $GENAPPLY include/DerivedConstants.h > AutoApply.cmm]) +fi + +AC_MSG_CHECKING([for AutoApply_V16.cmm]) +if $GENAPPLY include/DerivedConstants.h -V16 > AutoApply_V16.cmm; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $GENAPPLY include/DerivedConstants.h -V16 > AutoApply_V16.cmm]) +fi + +AC_MSG_CHECKING([for AutoApply_V32.cmm]) +if $GENAPPLY include/DerivedConstants.h -V32 > AutoApply_V32.cmm; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $GENAPPLY include/DerivedConstants.h -V32 > AutoApply_V32.cmm]) +fi + +AC_MSG_CHECKING([for AutoApply_V64.cmm]) +if $GENAPPLY include/DerivedConstants.h -V64 > AutoApply_V64.cmm; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $GENAPPLY include/DerivedConstants.h -V64 > AutoApply_V64.cmm]) +fi + +AC_MSG_CHECKING([for include/rts/EventLogConstants.h]) +if mkdir -p include/rts && $PYTHON $srcdir/gen_event_types.py --event-types-defines include/rts/EventLogConstants.h; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $PYTHON gen_event_types.py]) +fi + +AC_MSG_CHECKING([for include/rts/EventTypes.h]) +if mkdir -p include/rts && $PYTHON $srcdir/gen_event_types.py --event-types-array include/rts/EventTypes.h; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $PYTHON gen_event_types.py]) +fi + + +dnl -------------------------------------------------------------- +dnl ** Write config files +dnl -------------------------------------------------------------- + +AC_OUTPUT diff --git a/rts/include/stg/MachRegsForHost.h b/rts/include/stg/MachRegsForHost.h index 7c045c0214b..cd28215ea0f 100644 --- a/rts/include/stg/MachRegsForHost.h +++ b/rts/include/stg/MachRegsForHost.h @@ -84,4 +84,4 @@ #endif -#include "MachRegs.h" +#include "stg/MachRegs.h" diff --git a/rts/rts.cabal b/rts/rts.cabal index 899e65d712e..5691b6cc9d4 100644 --- a/rts/rts.cabal +++ b/rts/rts.cabal @@ -1,4 +1,4 @@ -cabal-version: 3.0 +cabal-version: 3.8 name: rts version: 1.0.3 synopsis: The GHC runtime system @@ -13,9 +13,234 @@ build-type: Configure extra-source-files: configure + config.guess + config.sub + ghcplatform.h.top.in + ghcplatform.h.bottom + ghcautoconf.h.autoconf.in configure.ac external-symbols.list.in rts.buildinfo.in + linker/ELFRelocs/AArch64.def + linker/ELFRelocs/ARM.def + linker/ELFRelocs/i386.def + linker/ELFRelocs/x86_64.def + win32/libHSffi.def + win32/libHSghc-internal.def + win32/libHSghc-prim.def + posix/ticker/Pthread.c + posix/ticker/Setitimer.c + posix/ticker/TimerCreate.c + posix/ticker/TimerFd.c + -- headers files that are not installed by the rts package but only used to + -- build the rts C code + xxhash.h + adjustor/AdjustorPool.h + Adjustor.h + Apply.h + Arena.h + ARMOutlineAtomicsSymbols.h + AutoApply.h + AutoApplyVecs.h + BeginPrivate.h + Capability.h + CheckUnload.h + CheckVectorSupport.h + CloneStack.h + Continuation.h + Disassembler.h + EndPrivate.h + eventlog/EventLog.h + Excn.h + FileLock.h + ForeignExports.h + fs_rts.h + GetEnv.h + GetTime.h + Globals.h + Hash.h + hooks/Hooks.h + include/Cmm.h + include/ghcconfig.h + include/HsFFI.h + include/MachDeps.h + include/rts/Adjustor.h + include/RtsAPI.h + include/rts/BlockSignals.h + include/rts/Config.h + include/rts/Constants.h + include/rts/EventLogFormat.h + include/rts/EventLogWriter.h + include/rts/ExecPage.h + include/rts/FileLock.h + include/rts/Flags.h + include/rts/ForeignExports.h + include/rts/GetTime.h + include/rts/ghc_ffi.h + include/rts/Globals.h + include/Rts.h + include/rts/Hpc.h + include/rts/IOInterface.h + include/rts/IPE.h + include/rts/Libdw.h + include/rts/LibdwPool.h + include/rts/Linker.h + include/rts/Main.h + include/rts/Messages.h + include/rts/NonMoving.h + include/rts/OSThreads.h + include/rts/Parallel.h + include/rts/PosixSource.h + include/rts/PrimFloat.h + include/rts/prof/CCS.h + include/rts/prof/Heap.h + include/rts/Profiling.h + include/rts/prof/LDV.h + include/rts/Signals.h + include/rts/SpinLock.h + include/rts/StableName.h + include/rts/StablePtr.h + include/rts/StaticPtrTable.h + include/rts/storage/Block.h + include/rts/storage/ClosureMacros.h + include/rts/storage/GC.h + include/rts/storage/HeapAlloc.h + include/rts/storage/Heap.h + include/rts/storage/InfoTables.h + include/rts/storage/MBlock.h + include/rts/storage/TSO.h + include/rts/Threads.h + include/rts/Ticky.h + include/rts/Time.h + include/rts/Timer.h + include/rts/TSANUtils.h + include/rts/TTY.h + include/rts/Types.h + include/rts/Utils.h + include/stg/DLL.h + include/Stg.h + include/stg/MachRegsForHost.h + include/stg/MiscClosures.h + include/stg/Prim.h + include/stg/Regs.h + include/stg/SMP.h + include/stg/Ticky.h + include/stg/Types.h + Interpreter.h + IOManager.h + IOManagerInternals.h + IPE.h + Jumps.h + LdvProfile.h + Libdw.h + LibdwPool.h + linker/CacheFlush.h + linker/elf_compat.h + linker/elf_got.h + linker/Elf.h + linker/elf_plt_aarch64.h + linker/elf_plt_arm.h + linker/elf_plt.h + linker/elf_plt_riscv64.h + linker/elf_reloc_aarch64.h + linker/elf_reloc.h + linker/elf_reloc_riscv64.h + linker/ElfTypes.h + linker/elf_util.h + linker/InitFini.h + LinkerInternals.h + linker/LoadNativeObjPosix.h + linker/M32Alloc.h + linker/MachO.h + linker/macho/plt_aarch64.h + linker/macho/plt.h + linker/MachOTypes.h + linker/MMap.h + linker/PEi386.h + linker/PEi386Types.h + linker/SymbolExtras.h + linker/util.h + linker/Wasm32Types.h + Messages.h + PathUtils.h + Pool.h + posix/Clock.h + posix/Select.h + posix/Signals.h + posix/TTY.h + Prelude.h + Printer.h + ProfHeap.h + ProfHeapInternal.h + ProfilerReport.h + ProfilerReportJson.h + Profiling.h + Proftimer.h + RaiseAsync.h + ReportMemoryMap.h + RetainerProfile.h + RetainerSet.h + RtsDllMain.h + RtsFlags.h + RtsSignals.h + RtsSymbolInfo.h + RtsSymbols.h + RtsUtils.h + Schedule.h + sm/BlockAlloc.h + sm/CNF.h + sm/Compact.h + sm/Evac.h + sm/GC.h + sm/GCTDecl.h + sm/GCThread.h + sm/GCUtils.h + sm/HeapUtils.h + sm/MarkStack.h + sm/MarkWeak.h + sm/NonMovingAllocate.h + sm/NonMovingCensus.h + sm/NonMoving.h + sm/NonMovingMark.h + sm/NonMovingScav.h + sm/NonMovingShortcut.h + sm/NonMovingSweep.h + sm/OSMem.h + SMPClosureOps.h + sm/Sanity.h + sm/Scav.h + sm/ShouldCompact.h + sm/Storage.h + sm/Sweep.h + Sparks.h + StableName.h + StablePtr.h + StaticPtrTable.h + Stats.h + StgPrimFloat.h + StgRun.h + STM.h + Task.h + ThreadLabels.h + ThreadPaused.h + Threads.h + Ticker.h + Ticky.h + Timer.h + TopHandler.h + Trace.h + TraverseHeap.h + Updates.h + Weak.h + win32/AsyncMIO.h + win32/AsyncWinIO.h + win32/AwaitEvent.h + win32/ConsoleHandler.h + win32/MIOManager.h + win32/ThrIOManager.h + win32/veh_excn.h + win32/WorkQueue.h + WSDeque.h extra-tmp-files: autom4te.cache @@ -37,9 +262,6 @@ flag librt flag libdl default: False manual: True -flag use-system-libffi - default: False - manual: True flag libffi-adjustors default: False manual: True @@ -79,11 +301,11 @@ flag smp flag find-ptr default: False manual: True --- Some cabal flags used to control the flavours we want to produce --- for libHSrts in hadrian. By default, we just produce vanilla and --- threaded. The flags "compose": if you enable debug and profiling, --- you will produce vanilla, _thr, _debug, _p but also _thr_p, --- _thr_debug_p and so on. +-- -- Some cabal flags used to control the flavours we want to produce +-- -- for libHSrts in hadrian. By default, we just produce vanilla and +-- -- threaded. The flags "compose": if you enable debug and profiling, +-- -- you will produce vanilla, _thr, _debug, _p but also _thr_p, +-- -- _thr_debug_p and so on. flag profiling default: False manual: True @@ -104,471 +326,473 @@ flag thread-sanitizer default: False manual: True -library - -- rts is a wired in package and - -- expects the unit-id to be - -- set without version - ghc-options: -this-unit-id rts - - exposed: True - exposed-modules: +common rts-base-config + ghc-options: -ghcversion-file=include/ghcversion.h -optc-DFS_NAMESPACE=rts + cmm-options: - if arch(javascript) + include-dirs: include . + includes: Rts.h + build-depends: + rts-headers, + rts-fs, + rts - include-dirs: include - - js-sources: - js/config.js - js/structs.js - js/arith.js - js/compact.js - js/debug.js - js/enum.js - js/environment.js - js/eventlog.js - js/gc.js - js/goog.js - js/hscore.js - js/md5.js - js/mem.js - js/node-exports.js - js/object.js - js/profiling.js - js/rts.js - js/stableptr.js - js/staticpointer.js - js/stm.js - js/string.js - js/thread.js - js/unicode.js - js/verify.js - js/weak.js - js/globals.js - js/time.js - - install-includes: HsFFI.h MachDeps.h Rts.h RtsAPI.h Stg.h - ghcautoconf.h ghcconfig.h ghcplatform.h ghcversion.h - DerivedConstants.h - stg/MachRegs.h - stg/MachRegs/arm32.h - stg/MachRegs/arm64.h - stg/MachRegs/loongarch64.h - stg/MachRegs/ppc.h - stg/MachRegs/riscv64.h - stg/MachRegs/s390x.h - stg/MachRegs/wasm32.h - stg/MachRegs/x86.h - stg/MachRegsForHost.h - stg/Types.h +common rts-c-sources-base + if !arch(javascript) + cmm-sources: + Apply.cmm + Compact.cmm + ContinuationOps.cmm + Exception.cmm + HeapStackCheck.cmm + Jumps_D.cmm + Jumps_V16.cmm + PrimOps.cmm + StgMiscClosures.cmm + StgStartup.cmm + StgStdThunks.cmm + Updates.cmm + -- Adjustor stuff + if flag(libffi-adjustors) + c-sources: adjustor/LibffiAdjustor.c else - -- If we are using an in-tree libffi then we must declare it as a bundled - -- library to ensure that Cabal installs it. - if !flag(use-system-libffi) - if os(windows) - extra-bundled-libraries: Cffi-6 + if arch(i386) + asm-sources: adjustor/Nativei386Asm.S + c-sources: adjustor/Nativei386.c + if arch(x86_64) + if os(mingw32) + asm-sources: adjustor/NativeAmd64MingwAsm.S + c-sources: adjustor/NativeAmd64Mingw.c else - extra-bundled-libraries: Cffi - - install-includes: ffi.h ffitarget.h - -- ^ see Note [Packaging libffi headers] in - -- GHC.Driver.CodeOutput. - - -- Here we declare several flavours to be available when passing the - -- suitable (combination of) flag(s) when configuring the RTS from hadrian, - -- using Cabal. - if flag(threaded) - extra-library-flavours: _thr - if flag(dynamic) - extra-dynamic-library-flavours: _thr - - if flag(profiling) - extra-library-flavours: _p - if flag(threaded) - extra-library-flavours: _thr_p - if flag(debug) - extra-library-flavours: _debug_p - if flag(threaded) - extra-library-flavours: _thr_debug_p - if flag(dynamic) - extra-dynamic-library-flavours: _p - if flag(threaded) - extra-dynamic-library-flavours: _thr_p - if flag(debug) - extra-dynamic-library-flavours: _debug_p - if flag(threaded) - extra-dynamic-library-flavours: _thr_debug_p - - if flag(debug) - extra-library-flavours: _debug - if flag(dynamic) - extra-dynamic-library-flavours: _debug - if flag(threaded) - extra-library-flavours: _thr_debug - if flag(dynamic) - extra-dynamic-library-flavours: _thr_debug - - if flag(thread-sanitizer) - cc-options: -fsanitize=thread - ld-options: -fsanitize=thread - - if os(linux) - -- the RTS depends upon libc. while this dependency is generally - -- implicitly added by `cc`, we must explicitly add it here to ensure - -- that it is ordered correctly with libpthread, since ghc-internal.cabal - -- also explicitly lists libc. See #19029. - extra-libraries: c - if flag(libm) - -- for ldexp() - extra-libraries: m - if flag(librt) - extra-libraries: rt - if flag(libdl) - extra-libraries: dl - if flag(use-system-libffi) - extra-libraries: ffi - if os(windows) - extra-libraries: - -- for the linker - wsock32 gdi32 winmm - -- for crash dump - dbghelp - -- for process information - psapi - -- TODO: Hadrian will use this cabal file, so drop WINVER from Hadrian's configs. - -- Minimum supported Windows version. - -- These numbers can be found at: - -- https://msdn.microsoft.com/en-us/library/windows/desktop/aa383745(v=vs.85).aspx - -- If we're compiling on windows, enforce that we only support Windows 7+ - -- Adding this here means it doesn't have to be done in individual .c files - -- and also centralizes the versioning. - cpp-options: -D_WIN32_WINNT=0x06010000 - cc-options: -D_WIN32_WINNT=0x06010000 - if flag(need-pthread) - -- for pthread_getthreadid_np, pthread_create, ... - extra-libraries: pthread - if flag(need-atomic) - -- for sub-word-sized atomic operations (#19119) - extra-libraries: atomic - if flag(libbfd) - -- for debugging - extra-libraries: bfd iberty - if flag(libdw) - -- for backtraces - extra-libraries: elf dw - if flag(libnuma) - extra-libraries: numa - if flag(libzstd) - if flag(static-libzstd) - if os(darwin) - buildable: False - else - extra-libraries: :libzstd.a - else - extra-libraries: zstd - if !flag(smp) - cpp-options: -DNOSMP - - include-dirs: include - includes: Rts.h - autogen-includes: ghcautoconf.h ghcplatform.h - install-includes: Cmm.h HsFFI.h MachDeps.h Jumps.h Rts.h RtsAPI.h RtsSymbols.h Stg.h - ghcautoconf.h ghcconfig.h ghcplatform.h ghcversion.h - -- ^ from include - DerivedConstants.h - rts/EventLogConstants.h - rts/EventTypes.h - -- ^ generated - rts/ghc_ffi.h - rts/Adjustor.h - rts/ExecPage.h - rts/BlockSignals.h - rts/Bytecodes.h - rts/Config.h - rts/Constants.h - rts/EventLogFormat.h - rts/EventLogWriter.h - rts/FileLock.h - rts/Flags.h - rts/ForeignExports.h - rts/GetTime.h - rts/Globals.h - rts/Hpc.h - rts/IOInterface.h - rts/Libdw.h - rts/LibdwPool.h - rts/Linker.h - rts/Main.h - rts/Messages.h - rts/NonMoving.h - rts/OSThreads.h - rts/Parallel.h - rts/PrimFloat.h - rts/Profiling.h - rts/IPE.h - rts/PosixSource.h - rts/Signals.h - rts/SpinLock.h - rts/StableName.h - rts/StablePtr.h - rts/StaticPtrTable.h - rts/TTY.h - rts/Threads.h - rts/Ticky.h - rts/Time.h - rts/Timer.h - rts/TSANUtils.h - rts/Types.h - rts/Utils.h - rts/prof/CCS.h - rts/prof/Heap.h - rts/prof/LDV.h - rts/storage/Block.h - rts/storage/ClosureMacros.h - rts/storage/ClosureTypes.h - rts/storage/Closures.h - rts/storage/FunTypes.h - rts/storage/Heap.h - rts/storage/HeapAlloc.h - rts/storage/GC.h - rts/storage/InfoTables.h - rts/storage/MBlock.h - rts/storage/TSO.h - stg/DLL.h - stg/MachRegs.h - stg/MachRegs/arm32.h - stg/MachRegs/arm64.h - stg/MachRegs/loongarch64.h - stg/MachRegs/ppc.h - stg/MachRegs/riscv64.h - stg/MachRegs/s390x.h - stg/MachRegs/wasm32.h - stg/MachRegs/x86.h - stg/MachRegsForHost.h - stg/MiscClosures.h - stg/Prim.h - stg/Regs.h - stg/SMP.h - stg/Ticky.h - stg/Types.h - - if os(osx) - ld-options: "-Wl,-search_paths_first" - -- See Note [Undefined symbols in the RTS] - "-Wl,-undefined,dynamic_lookup" - if !arch(x86_64) && !arch(aarch64) - ld-options: -read_only_relocs warning - - cmm-sources: Apply.cmm - Compact.cmm - ContinuationOps.cmm - Exception.cmm - HeapStackCheck.cmm - Jumps_D.cmm - Jumps_V16.cmm - Jumps_V32.cmm - Jumps_V64.cmm - PrimOps.cmm - StgMiscClosures.cmm - StgStartup.cmm - StgStdThunks.cmm - Updates.cmm - -- AutoApply is generated - AutoApply.cmm - AutoApply_V16.cmm - AutoApply_V32.cmm - AutoApply_V64.cmm - - -- Adjustor stuff - if flag(libffi-adjustors) + asm-sources: adjustor/NativeAmd64Asm.S + c-sources: adjustor/NativeAmd64.c + if !arch(x86_64) && !arch(i386) c-sources: adjustor/LibffiAdjustor.c - else - -- Use GHC's native adjustors - if arch(i386) - asm-sources: adjustor/Nativei386Asm.S - c-sources: adjustor/Nativei386.c - if arch(x86_64) - if os(mingw32) - asm-sources: adjustor/NativeAmd64MingwAsm.S - c-sources: adjustor/NativeAmd64Mingw.c + + if arch(ppc) || arch(ppc64) || arch(s390x) || arch(riscv64) || arch(loongarch64) + asm-sources: StgCRunAsm.S + + if arch(wasm32) + cc-options: -fvisibility=default -fvisibility-inlines-hidden + + c-sources: Adjustor.c + adjustor/AdjustorPool.c + ExecPage.c + Arena.c + Capability.c + CheckUnload.c + CheckVectorSupport.c + CloneStack.c + ClosureFlags.c + ClosureSize.c + Continuation.c + Disassembler.c + FileLock.c + ForeignExports.c + Globals.c + Hash.c + Heap.c + Hpc.c + HsFFI.c + Inlines.c + Interpreter.c + IOManager.c + LdvProfile.c + Libdw.c + LibdwPool.c + Linker.c + ReportMemoryMap.c + Messages.c + OldARMAtomic.c + PathUtils.c + Pool.c + Printer.c + ProfHeap.c + ProfilerReport.c + ProfilerReportJson.c + Profiling.c + IPE.c + Proftimer.c + RaiseAsync.c + RetainerProfile.c + RetainerSet.c + RtsAPI.c + RtsDllMain.c + RtsFlags.c + RtsMain.c + RtsMessages.c + RtsStartup.c + RtsSymbolInfo.c + RtsSymbols.c + RtsUtils.c + STM.c + Schedule.c + Sparks.c + SpinLock.c + StableName.c + StablePtr.c + StaticPtrTable.c + Stats.c + StgCRun.c + StgPrimFloat.c + Task.c + ThreadLabels.c + ThreadPaused.c + Threads.c + Ticky.c + Timer.c + TopHandler.c + Trace.c + TraverseHeap.c + TraverseHeapTest.c + TSANUtils.c + WSDeque.c + Weak.c + ZeroSlop.c + eventlog/EventLog.c + eventlog/EventLogWriter.c + hooks/FlagDefaults.c + hooks/LongGCSync.c + hooks/MallocFail.c + hooks/OnExit.c + hooks/OutOfHeap.c + hooks/StackOverflow.c + linker/CacheFlush.c + linker/Elf.c + linker/InitFini.c + linker/LoadArchive.c + linker/LoadNativeObjPosix.c + linker/M32Alloc.c + linker/MMap.c + linker/MachO.c + linker/macho/plt.c + linker/macho/plt_aarch64.c + linker/ProddableBlocks.c + linker/PEi386.c + linker/SymbolExtras.c + linker/elf_got.c + linker/elf_plt.c + linker/elf_plt_aarch64.c + linker/elf_plt_riscv64.c + linker/elf_plt_arm.c + linker/elf_reloc.c + linker/elf_reloc_aarch64.c + linker/elf_reloc_riscv64.c + linker/elf_tlsgd.c + linker/elf_util.c + sm/BlockAlloc.c + sm/CNF.c + sm/Compact.c + sm/Evac.c + sm/Evac_thr.c + sm/GC.c + sm/GCAux.c + sm/GCUtils.c + sm/MBlock.c + sm/MarkWeak.c + sm/NonMoving.c + sm/NonMovingAllocate.c + sm/NonMovingCensus.c + sm/NonMovingMark.c + sm/NonMovingScav.c + sm/NonMovingShortcut.c + sm/NonMovingSweep.c + sm/Sanity.c + sm/Scav.c + sm/Scav_thr.c + sm/Storage.c + sm/Sweep.c + + if os(windows) + c-sources: win32/AsyncMIO.c + win32/AsyncWinIO.c + win32/AwaitEvent.c + win32/ConsoleHandler.c + win32/GetEnv.c + win32/GetTime.c + win32/MIOManager.c + win32/OSMem.c + win32/OSThreads.c + win32/ThrIOManager.c + win32/Ticker.c + win32/WorkQueue.c + win32/veh_excn.c + elif arch(wasm32) + asm-sources: wasm/Wasm.S + c-sources: wasm/StgRun.c + wasm/GetTime.c + wasm/OSMem.c + wasm/OSThreads.c + wasm/JSFFI.c + wasm/JSFFIGlobals.c + -- Note: Select.c included for wasm32 + posix/Select.c + cmm-sources: wasm/jsval.cmm + wasm/blocker.cmm + wasm/scheduler.cmm + -- Posix-like + else + c-sources: posix/GetEnv.c + posix/GetTime.c + posix/Ticker.c + posix/OSMem.c + posix/OSThreads.c + posix/Select.c + posix/Signals.c + posix/TTY.c + +common rts-link-options + extra-libraries: ffi + extra-libraries-static: ffi + + if os(linux) + extra-libraries: c + if flag(libm) + extra-libraries: m + if flag(librt) + extra-libraries: rt + if flag(libdl) + extra-libraries: dl + if os(windows) + extra-libraries: + wsock32 gdi32 winmm + dbghelp + psapi + cpp-options: -D_WIN32_WINNT=0x06010000 + cc-options: -D_WIN32_WINNT=0x06010000 + if flag(need-pthread) + extra-libraries: pthread + if flag(need-atomic) + extra-libraries: atomic + if flag(libbfd) + extra-libraries: bfd iberty + if flag(libdw) + extra-libraries: elf dw + if flag(libnuma) + extra-libraries: numa + if flag(libzstd) + if flag(static-libzstd) + if os(darwin) + buildable: False else - asm-sources: adjustor/NativeAmd64Asm.S - c-sources: adjustor/NativeAmd64.c - - -- Use assembler STG entrypoint on architectures where it is used - if arch(ppc) || arch(ppc64) || arch(s390x) || arch(riscv64) || arch(loongarch64) - asm-sources: StgCRunAsm.S - - c-sources: Adjustor.c - adjustor/AdjustorPool.c - ExecPage.c - Arena.c - Capability.c - CheckUnload.c - CheckVectorSupport.c - CloneStack.c - ClosureFlags.c - ClosureSize.c - Continuation.c - Disassembler.c - FileLock.c - ForeignExports.c - Globals.c - Hash.c - Heap.c - Hpc.c - HsFFI.c - Inlines.c - Interpreter.c - IOManager.c - LdvProfile.c - Libdw.c - LibdwPool.c - Linker.c - ReportMemoryMap.c - Messages.c - OldARMAtomic.c - PathUtils.c - Pool.c - Printer.c - ProfHeap.c - ProfilerReport.c - ProfilerReportJson.c - Profiling.c - IPE.c - Proftimer.c - RaiseAsync.c - RetainerProfile.c - RetainerSet.c - RtsAPI.c - RtsDllMain.c - RtsFlags.c - RtsMain.c - RtsMessages.c - RtsStartup.c - RtsSymbolInfo.c - RtsSymbols.c - RtsUtils.c - STM.c - Schedule.c - Sparks.c - SpinLock.c - StableName.c - StablePtr.c - StaticPtrTable.c - Stats.c - StgCRun.c - StgPrimFloat.c - Task.c - ThreadLabels.c - ThreadPaused.c - Threads.c - Ticky.c - Timer.c - TopHandler.c - Trace.c - TraverseHeap.c - TraverseHeapTest.c - TSANUtils.c - WSDeque.c - Weak.c - ZeroSlop.c - eventlog/EventLog.c - eventlog/EventLogWriter.c - hooks/FlagDefaults.c - hooks/LongGCSync.c - hooks/MallocFail.c - hooks/OnExit.c - hooks/OutOfHeap.c - hooks/StackOverflow.c - linker/CacheFlush.c - linker/Elf.c - linker/InitFini.c - linker/LoadArchive.c - linker/LoadNativeObjPosix.c - linker/M32Alloc.c - linker/MMap.c - linker/MachO.c - linker/macho/plt.c - linker/macho/plt_aarch64.c - linker/ProddableBlocks.c - linker/PEi386.c - linker/SymbolExtras.c - linker/elf_got.c - linker/elf_plt.c - linker/elf_plt_aarch64.c - linker/elf_plt_riscv64.c - linker/elf_plt_arm.c - linker/elf_reloc.c - linker/elf_reloc_aarch64.c - linker/elf_reloc_riscv64.c - linker/elf_tlsgd.c - linker/elf_util.c - sm/BlockAlloc.c - sm/CNF.c - sm/Compact.c - sm/Evac.c - sm/Evac_thr.c - sm/GC.c - sm/GCAux.c - sm/GCUtils.c - sm/MBlock.c - sm/MarkWeak.c - sm/NonMoving.c - sm/NonMovingAllocate.c - sm/NonMovingCensus.c - sm/NonMovingMark.c - sm/NonMovingScav.c - sm/NonMovingShortcut.c - sm/NonMovingSweep.c - sm/Sanity.c - sm/Scav.c - sm/Scav_thr.c - sm/Storage.c - sm/Sweep.c - fs.c - -- I wish we had wildcards..., this would be: - -- *.c hooks/**/*.c sm/**/*.c eventlog/**/*.c linker/**/*.c - - if os(windows) - c-sources: win32/AsyncMIO.c - win32/AsyncWinIO.c - win32/AwaitEvent.c - win32/ConsoleHandler.c - win32/GetEnv.c - win32/GetTime.c - win32/MIOManager.c - win32/OSMem.c - win32/OSThreads.c - win32/ThrIOManager.c - win32/Ticker.c - win32/WorkQueue.c - win32/veh_excn.c - -- win32/**/*.c - elif arch(wasm32) - asm-sources: wasm/Wasm.S - c-sources: wasm/StgRun.c - wasm/GetTime.c - wasm/OSMem.c - wasm/OSThreads.c - wasm/JSFFI.c - wasm/JSFFIGlobals.c - posix/Select.c - cmm-sources: wasm/jsval.cmm - wasm/blocker.cmm - wasm/scheduler.cmm + extra-libraries: :libzstd.a + else + extra-libraries: zstd + + if os(osx) + ld-options: "-Wl,-search_paths_first" + "-Wl,-undefined,dynamic_lookup" + if !arch(x86_64) && !arch(aarch64) + ld-options: -read_only_relocs warning + +common rts-global-build-flags + ghc-options: -DCOMPILING_RTS + cpp-options: -DCOMPILING_RTS + if !flag(smp) + ghc-options: -DNOSMP + cpp-options: -DNOSMP + if flag(thread-sanitizer) + cc-options: -fsanitize=thread + ld-options: -fsanitize=thread + +common rts-debug-flags + ghc-options: -optc-DDEBUG + cpp-options: -DDEBUG -fno-omit-frame-pointer -g3 -O0 + +common rts-threaded-flags + ghc-options: -DTHREADED_RTS + cpp-options: -DTHREADED_RTS + +-- the _main_ library needs to deal with all the _configure_ time stuff. +library + ghc-options: -this-unit-id rts -ghcversion-file=include/ghcversion.h -optc-DFS_NAMESPACE=rts + cmm-options: -this-unit-id rts + + autogen-includes: + ghcautoconf.h + ghcplatform.h + DerivedConstants.h + rts/EventLogConstants.h + rts/EventTypes.h + + install-includes: + ghcautoconf.h + ghcplatform.h + DerivedConstants.h + rts/EventLogConstants.h + rts/EventTypes.h + + install-includes: + -- Common headers for non-JS builds + Cmm.h HsFFI.h MachDeps.h Jumps.h Rts.h RtsAPI.h RtsSymbols.h Stg.h + ghcconfig.h ghcversion.h + rts/ghc_ffi.h + rts/Adjustor.h + rts/ExecPage.h + rts/BlockSignals.h + rts/Config.h + rts/Constants.h + rts/EventLogFormat.h + rts/EventLogWriter.h + rts/FileLock.h + rts/Flags.h + rts/ForeignExports.h + rts/GetTime.h + rts/Globals.h + rts/Hpc.h + rts/IOInterface.h + rts/Libdw.h + rts/LibdwPool.h + rts/Linker.h + rts/Main.h + rts/Messages.h + rts/NonMoving.h + rts/OSThreads.h + rts/Parallel.h + rts/PrimFloat.h + rts/Profiling.h + rts/IPE.h + rts/PosixSource.h + rts/Signals.h + rts/SpinLock.h + rts/StableName.h + rts/StablePtr.h + rts/StaticPtrTable.h + rts/TTY.h + rts/Threads.h + rts/Ticky.h + rts/Time.h + rts/Timer.h + rts/TSANUtils.h + rts/Types.h + rts/Utils.h + rts/prof/CCS.h + rts/prof/Heap.h + rts/prof/LDV.h + rts/storage/Block.h + rts/storage/ClosureMacros.h + rts/storage/Closures.h + rts/storage/Heap.h + rts/storage/HeapAlloc.h + rts/storage/GC.h + rts/storage/InfoTables.h + rts/storage/MBlock.h + rts/storage/TSO.h + stg/DLL.h + stg/MiscClosures.h + stg/Prim.h + stg/Regs.h + stg/SMP.h + stg/Ticky.h + stg/Types.h + + include-dirs: include . + + build-depends: + rts-headers, + rts-fs + + if !arch(javascript) + -- FIXME: by virtue of being part of the rts main library, these do not get + -- the flags (debug, threaded, ...) as the sub libraries. Thus we are + -- likely missing -DDEBUG, -DTHREADED_RTS, etc. + -- One solution to this would be to turn all of these into `.h` files, and + -- then have the `AutoApply.cmm` in `rts-c-sources-base` include them. This + -- would mean they are included in the sublibraries which will in turn apply + -- the sublibrary specific (c)flags. + autogen-cmm-sources: + AutoApply.cmm + AutoApply_V16.cmm + + if arch(x86_64) + cmm-sources: + Jumps_V32.cmm (-mavx2) + Jumps_V64.cmm (-mavx512f) + autogen-cmm-sources: + AutoApply_V32.cmm (-mavx2) + AutoApply_V64.cmm (-mavx512f) else - c-sources: posix/GetEnv.c - posix/GetTime.c - posix/Ticker.c - posix/OSMem.c - posix/OSThreads.c - posix/Select.c - posix/Signals.c - posix/TTY.c - -- ticker/*.c - -- We don't want to compile posix/ticker/*.c, these will be #included - -- from Ticker.c + cmm-sources: + Jumps_V32.cmm + Jumps_V64.cmm + autogen-cmm-sources: + AutoApply_V32.cmm + AutoApply_V64.cmm + +common ghcjs + import: rts-base-config + + -- Keep original JS specific settings for the main library + include-dirs: include + js-sources: + js/config.js + js/structs.js + js/arith.js + js/compact.js + js/debug.js + js/enum.js + js/environment.js + js/eventlog.js + js/gc.js + js/goog.js + js/hscore.js + js/md5.js + js/mem.js + js/node-exports.js + js/object.js + js/profiling.js + js/rts.js + js/stableptr.js + js/staticpointer.js + js/stm.js + js/string.js + js/thread.js + js/unicode.js + js/verify.js + js/weak.js + js/globals.js + js/time.js + + -- Add JS specific install-includes again + install-includes: HsFFI.h MachDeps.h Rts.h RtsAPI.h Stg.h + ghcconfig.h + ghcversion.h + stg/MachRegsForHost.h + stg/Types.h + +-- this is basiclly the "vanilla" version +library nonthreaded-nodebug + if arch(javascript) + import: ghcjs + else + import: rts-base-config, rts-c-sources-base, rts-link-options, rts-global-build-flags + + visibility: public + + ghc-options: -optc-DRtsWay="v" + + +library threaded-nodebug + import: rts-base-config, rts-c-sources-base, rts-link-options, rts-global-build-flags, rts-threaded-flags + visibility: public + build-depends: rts + if arch(javascript) + buildable: False + +library nonthreaded-debug + import: rts-base-config, rts-c-sources-base, rts-link-options, rts-global-build-flags, rts-debug-flags + visibility: public + build-depends: rts + if arch(javascript) + buildable: False + +library threaded-debug + import: rts-base-config, rts-c-sources-base, rts-link-options, rts-global-build-flags, rts-threaded-flags, rts-debug-flags + visibility: public + build-depends: rts + if arch(javascript) + buildable: False -- Note [Undefined symbols in the RTS] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/utils/iserv/cbits/iservmain.c b/utils/ghc-iserv/cbits/iservmain.c similarity index 100% rename from utils/iserv/cbits/iservmain.c rename to utils/ghc-iserv/cbits/iservmain.c diff --git a/utils/ghc-iserv/ghc-iserv.cabal b/utils/ghc-iserv/ghc-iserv.cabal new file mode 100644 index 00000000000..7875446c5b7 --- /dev/null +++ b/utils/ghc-iserv/ghc-iserv.cabal @@ -0,0 +1,44 @@ +-- WARNING: ghc-iserv.cabal is automatically generated from ghc-iserv.cabal.in +-- by ../../configure. Make sure you are editing ghc-iserv.cabal.in, not +-- ghc-iserv.cabal. + +Name: ghc-iserv +Version: 9.13 +Copyright: XXX +License: BSD3 +-- XXX License-File: LICENSE +Author: XXX +Maintainer: XXX +Synopsis: iserv allows GHC to delegate Template Haskell computations +Description: + GHC can be provided with a path to the iserv binary with + @-pgmi=/path/to/iserv-bin@, and will in combination with + @-fexternal-interpreter@, compile Template Haskell though the + @iserv-bin@ delegate. This is very similar to how ghcjs has been + compiling Template Haskell, by spawning a separate delegate (so + called runner on the javascript vm) and evaluating the splices + there. + +Category: Development +build-type: Simple +cabal-version: >=1.10 + +Executable ghc-iserv + Default-Language: Haskell2010 + ghc-options: -no-hs-main + Main-Is: Main.hs + C-Sources: cbits/iservmain.c + Hs-Source-Dirs: src + include-dirs: . + Build-Depends: array >= 0.5 && < 0.6, + base >= 4 && < 5, + binary >= 0.7 && < 0.11, + bytestring >= 0.10 && < 0.13, + containers >= 0.5 && < 0.8, + deepseq >= 1.4 && < 1.6, + ghci == 9.13 + + if os(windows) + Cpp-Options: -DWINDOWS + else + Build-Depends: unix >= 2.7 && < 2.9 diff --git a/utils/iserv/iserv.cabal.in b/utils/ghc-iserv/ghc-iserv.cabal.in similarity index 85% rename from utils/iserv/iserv.cabal.in rename to utils/ghc-iserv/ghc-iserv.cabal.in index 0f5d77456ae..5488db57efa 100644 --- a/utils/iserv/iserv.cabal.in +++ b/utils/ghc-iserv/ghc-iserv.cabal.in @@ -1,8 +1,8 @@ --- WARNING: iserv.cabal is automatically generated from iserv.cabal.in by --- ../../configure. Make sure you are editing iserv.cabal.in, not --- iserv.cabal. +-- WARNING: ghc-iserv.cabal is automatically generated from ghc-iserv.cabal.in +-- by ../../configure. Make sure you are editing ghc-iserv.cabal.in, not +-- ghc-iserv.cabal. -Name: iserv +Name: ghc-iserv Version: @ProjectVersion@ Copyright: XXX License: BSD3 @@ -23,7 +23,7 @@ Category: Development build-type: Simple cabal-version: >=1.10 -Executable iserv +Executable ghc-iserv Default-Language: Haskell2010 ghc-options: -no-hs-main Main-Is: Main.hs diff --git a/utils/iserv/src/Main.hs b/utils/ghc-iserv/src/Main.hs similarity index 100% rename from utils/iserv/src/Main.hs rename to utils/ghc-iserv/src/Main.hs From 422366990a3ee59d5e25bb1cf04a5548f2296a39 Mon Sep 17 00:00:00 2001 From: Stable Haskell Team Date: Thu, 28 Aug 2025 20:20:24 +0900 Subject: [PATCH 3/3] feat: Complete multi-target support and compiler enhancements This commit completes the multi-target support infrastructure with comprehensive changes across the compiler, build system, and runtime components. These changes enable GHC to efficiently target multiple platforms including native, JavaScript, and cross-compilation scenarios. Core Compiler Changes: - GHC.Driver.DynFlags: Multi-target configuration support - GHC.Driver.Session: Enhanced session management for targets - GHC.Driver.Make: Updated build orchestration for stages - GHC.Driver.Downsweep: Improved module dependency handling - GHC.ByteCode.Asm: Cross-platform bytecode assembly - GHC.Iface.Load: Added Hooks parameter for interface loading - GHC.Unit.State: Multi-target package database handling LLVM Integration: - GHC.CmmToLlvm.*: Refactored LLVM backend configuration - Removed Version/Bounds.hs.in template - Dynamic LLVM version detection - Improved LLVM toolchain integration JavaScript Backend: - GHC.Driver.Config.StgToJS: JavaScript code generation config - Enhanced JavaScript runtime support - Integration with multi-stage build system Linker and Code Generation: - GHC.Linker.Dynamic: Cross-platform dynamic linking - GHC.Linker.Static: Static linking improvements - GHC.Linker.ExtraObj: Object file handling - GHC.Driver.CodeOutput: Multi-target code emission - CodeGen.Platform.h: Platform-specific code generation Build System: - ghc-pkg: Added --target flag support - deriveConstants: Cross-compilation aware - genprimopcode: Target-specific primop generation - Setup.hs files: Updated for new build infrastructure - packages: Updated submodule references Libraries: - system-cxx-std-lib: New C++ standard library wrapper - ghc-internal: Updated configuration - ghc-boot: Build system adjustments - ghc-prim: Cross-compilation support Testing Infrastructure: - Updated test driver for multi-target scenarios - Fixed platform-specific tests - Adjusted test expectations for new architecture - Added T10279h.hs test helper External Dependencies: - Removed libffi-tarballs (using system packages) - Updated Cabal submodule - Updated hsc2hs for cross-compilation Utilities: - unlit: Cross-platform compatibility - ghc-toolchain: Target detection improvements - config.guess/config.sub: GNU config files for RTS - Added .envrc for development environment - Added configure script for build configuration Contributors: - Moritz Angermann: Multi-target architecture and cross-compilation - Sylvain Henry: JavaScript backend integration - Andrea Bedini: Build system improvements - Julian Ospald: Testing infrastructure and utilities This completes the foundational work for GHC's multi-target support, enabling efficient compilation for diverse platforms while maintaining backward compatibility and build reproducibility. --- .envrc | 7 + .gitmodules | 7 +- compiler/CodeGen.Platform.h | 2 +- compiler/GHC/Builtin/PrimOps.hs | 10 +- compiler/GHC/ByteCode/Asm.hs | 2 +- compiler/GHC/CmmToLlvm.hs | 34 +- compiler/GHC/CmmToLlvm/Base.hs | 14 +- compiler/GHC/CmmToLlvm/Config.hs | 1 - compiler/GHC/CmmToLlvm/Version.hs | 8 - compiler/GHC/CmmToLlvm/Version/Bounds.hs.in | 19 - compiler/GHC/Driver/CodeOutput.hs | 7 +- compiler/GHC/Driver/Config/CmmToLlvm.hs | 1 - compiler/GHC/Driver/Config/Linker.hs | 11 +- compiler/GHC/Driver/Config/StgToJS.hs | 2 +- compiler/GHC/Driver/Downsweep.hs | 2 +- compiler/GHC/Driver/DynFlags.hs | 15 +- compiler/GHC/Driver/Errors/Ppr.hs | 8 +- compiler/GHC/Driver/Flags.hs | 4 +- compiler/GHC/Driver/Make.hs | 2 +- compiler/GHC/Driver/Session.hs | 7 +- compiler/GHC/Iface/Errors/Ppr.hs | 16 +- compiler/GHC/Iface/Load.hs | 137 +- compiler/GHC/Iface/Make.hs | 2 +- compiler/GHC/Iface/Recomp.hs | 2 +- compiler/GHC/Linker/Dynamic.hs | 6 +- compiler/GHC/Linker/ExtraObj.hs | 13 +- compiler/GHC/Linker/Loader.hs | 16 +- compiler/GHC/Linker/Static.hs | 8 +- compiler/GHC/Runtime/Loader.hs | 2 +- compiler/GHC/SysTools/Process.hs | 2 +- compiler/GHC/SysTools/Tasks.hs | 10 +- compiler/GHC/Unit/Info.hs | 19 +- compiler/GHC/Unit/Module/ModIface.hs | 6 +- compiler/GHC/Unit/State.hs | 106 +- compiler/Setup.hs | 29 +- compiler/ghc.cabal.in | 27 +- configure | 3073 +++++++++++++++++ ghc/GHC/Driver/Session/Mode.hs | 8 +- ghc/Main.hs | 54 +- ghc/ghc-bin.cabal.in | 11 +- hadrian/src/Hadrian/Haskell/Cabal/Parse.hs | 3 +- hadrian/src/Rules/Generate.hs | 11 +- hadrian/src/Rules/Lint.hs | 3 +- .../src/Settings/Builders/GenPrimopCode.hs | 2 + libffi-tarballs | 1 - libraries/Cabal | 2 +- libraries/base/tests/IO/T12010/test.T | 1 + libraries/base/tests/IO/all.T | 2 +- .../base/tests/perf/encodingAllocations.hs | 6 +- libraries/ghc-boot/Setup.hs | 17 +- libraries/ghc-boot/ghc-boot.cabal.in | 2 +- libraries/ghc-compact/tests/all.T | 2 +- libraries/ghc-heap/tests/all.T | 3 +- libraries/ghc-internal/configure.ac | 30 +- libraries/ghc-internal/ghc-internal.cabal.in | 13 +- libraries/ghc-internal/include/HsBase.h | 6 +- libraries/ghc-prim/ghc-prim.cabal | 3 + .../system-cxx-std-lib.cabal | 21 + packages | 1 - rts/config.guess | 1812 ++++++++++ rts/config.sub | 1971 +++++++++++ testsuite/driver/testlib.py | 33 +- testsuite/ghc-config/ghc-config.hs | 4 + testsuite/mk/test.mk | 7 + .../tests/codeGen/should_run/T25374/all.T | 2 +- testsuite/tests/driver/T20604/T20604.stdout | 3 +- testsuite/tests/driver/T21097b/Makefile | 2 +- testsuite/tests/driver/all.T | 4 +- testsuite/tests/ffi/should_run/T1288_c.c | 1 + testsuite/tests/ffi/should_run/T1288_ghci_c.c | 1 + testsuite/tests/ffi/should_run/T2276_c.c | 1 + testsuite/tests/ffi/should_run/T2276_ghci_c.c | 1 + testsuite/tests/ghci/linking/all.T | 3 +- testsuite/tests/ghci/linking/dyn/all.T | 4 +- testsuite/tests/ghci/prog001/prog001.T | 3 +- testsuite/tests/ghci/prog002/prog002.T | 3 +- testsuite/tests/ghci/prog010/all.T | 3 +- testsuite/tests/ghci/scripts/T7388.hs | 2 + testsuite/tests/ghci/scripts/T7388.script | 3 + testsuite/tests/ghci/scripts/all.T | 3 +- testsuite/tests/plugins/all.T | 6 +- testsuite/tests/plugins/plugins02.stderr | 2 +- testsuite/tests/rts/T8308/all.T | 2 +- testsuite/tests/rts/all.T | 18 +- testsuite/tests/rts/linker/T20494-obj.c | 5 +- testsuite/tests/rts/linker/all.T | 10 +- testsuite/tests/th/T10279.hs | 3 +- testsuite/tests/th/T10279.stderr | 14 +- testsuite/tests/th/T10279h.hs | 4 + testsuite/tests/th/T16180.hs | 2 + testsuite/tests/th/all.T | 2 +- utils/deriveConstants/Main.hs | 1 + utils/fs/README | 4 - utils/fs/fs.c | 590 ---- utils/fs/fs.h | 55 - utils/genprimopcode/Main.hs | 16 +- utils/genprimopcode/genprimopcode.cabal | 2 + utils/ghc-pkg/Main.hs | 63 +- utils/ghc-toolchain/exe/Main.hs | 227 +- .../ghc-toolchain/src/GHC/Toolchain/Target.hs | 6 + utils/hsc2hs | 2 +- utils/unlit/unlit.c | 4 +- utils/unlit/unlit.cabal | 12 +- 103 files changed, 7739 insertions(+), 1016 deletions(-) create mode 100644 .envrc delete mode 100644 compiler/GHC/CmmToLlvm/Version/Bounds.hs.in create mode 100755 configure delete mode 160000 libffi-tarballs create mode 100644 libraries/system-cxx-std-lib/system-cxx-std-lib.cabal create mode 100755 rts/config.guess create mode 100755 rts/config.sub create mode 100644 testsuite/tests/th/T10279h.hs delete mode 100644 utils/fs/README delete mode 100644 utils/fs/fs.c delete mode 100644 utils/fs/fs.h diff --git a/.envrc b/.envrc new file mode 100644 index 00000000000..637e3f13a49 --- /dev/null +++ b/.envrc @@ -0,0 +1,7 @@ +# Check if nix-direnv is already loaded; if not, source it +if ! has nix_direnv_reload; then + source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.7/direnvrc" "sha256-bn8WANE5a91RusFmRI7kS751ApelG02nMcwRekC/qzc=" +fi + +# Use the specified flake to enter the Nix development environment +use flake github:input-output-hk/devx#ghc98-minimal-ghc \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 46f1db3e7cc..fa49daaaa4e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,8 +8,9 @@ ignore = untracked [submodule "libraries/Cabal"] path = libraries/Cabal - url = https://gitlab.haskell.org/ghc/packages/Cabal.git + url = https://github.com/stable-haskell/cabal ignore = untracked + branch = stable-haskell/feature/cross-compile [submodule "libraries/containers"] path = libraries/containers url = https://gitlab.haskell.org/ghc/packages/containers.git @@ -99,10 +100,6 @@ path = utils/hsc2hs url = https://gitlab.haskell.org/ghc/hsc2hs.git ignore = untracked -[submodule "libffi-tarballs"] - path = libffi-tarballs - url = https://gitlab.haskell.org/ghc/libffi-tarballs.git - ignore = untracked [submodule "gmp-tarballs"] path = libraries/ghc-internal/gmp/gmp-tarballs url = https://gitlab.haskell.org/ghc/gmp-tarballs.git diff --git a/compiler/CodeGen.Platform.h b/compiler/CodeGen.Platform.h index fb093626496..8e78dab34b6 100644 --- a/compiler/CodeGen.Platform.h +++ b/compiler/CodeGen.Platform.h @@ -7,7 +7,7 @@ import GHC.Utils.Panic.Plain #endif import GHC.Platform.Reg -#include "MachRegs.h" +#include "stg/MachRegs.h" #if defined(MACHREGS_i386) || defined(MACHREGS_x86_64) diff --git a/compiler/GHC/Builtin/PrimOps.hs b/compiler/GHC/Builtin/PrimOps.hs index d4d98242759..2273d34f9c3 100644 --- a/compiler/GHC/Builtin/PrimOps.hs +++ b/compiler/GHC/Builtin/PrimOps.hs @@ -25,7 +25,9 @@ module GHC.Builtin.PrimOps ( getPrimOpResultInfo, isComparisonPrimOp, PrimOpResultInfo(..), - PrimCall(..) + PrimCall(..), + + primOpPrimModule, primOpWrappersModule ) where import GHC.Prelude @@ -171,6 +173,12 @@ primOpDocs :: [(FastString, String)] primOpDeprecations :: [(OccName, FastString)] #include "primop-deprecations.hs-incl" +primOpPrimModule :: String +#include "primop-prim-module.hs-incl" + +primOpWrappersModule :: String +#include "primop-wrappers-module.hs-incl" + {- ************************************************************************ * * diff --git a/compiler/GHC/ByteCode/Asm.hs b/compiler/GHC/ByteCode/Asm.hs index 5636d4ee427..2dde73a6f07 100644 --- a/compiler/GHC/ByteCode/Asm.hs +++ b/compiler/GHC/ByteCode/Asm.hs @@ -533,7 +533,7 @@ countSmall big x = count big False x -- Bring in all the bci_ bytecode constants. -#include "Bytecodes.h" +#include "rts/Bytecodes.h" largeArgInstr :: Word16 -> Word16 largeArgInstr bci = bci_FLAG_LARGE_ARGS .|. bci diff --git a/compiler/GHC/CmmToLlvm.hs b/compiler/GHC/CmmToLlvm.hs index 72a3161dec3..b85d620433b 100644 --- a/compiler/GHC/CmmToLlvm.hs +++ b/compiler/GHC/CmmToLlvm.hs @@ -38,8 +38,8 @@ import GHC.Utils.Panic import GHC.Utils.Logger import qualified GHC.Data.Stream as Stream -import Control.Monad ( when, forM_ ) -import Data.Maybe ( fromMaybe, catMaybes, isNothing ) +import Control.Monad ( forM_ ) +import Data.Maybe ( catMaybes ) import System.IO -- ----------------------------------------------------------------------------- @@ -57,36 +57,8 @@ llvmCodeGen logger cfg h dus cmm_stream -- Pass header showPass logger "LLVM CodeGen" - -- get llvm version, cache for later use - let mb_ver = llvmCgLlvmVersion cfg - - -- warn if unsupported - forM_ mb_ver $ \ver -> do - debugTraceMsg logger 2 - (text "Using LLVM version:" <+> text (llvmVersionStr ver)) - let doWarn = llvmCgDoWarn cfg - when (not (llvmVersionSupported ver) && doWarn) $ putMsg logger $ - "You are using an unsupported version of LLVM!" $$ - "Currently only" <+> text (llvmVersionStr supportedLlvmVersionLowerBound) <+> - "up to" <+> text (llvmVersionStr supportedLlvmVersionUpperBound) <+> "(non inclusive) is supported." <+> - "System LLVM version: " <> text (llvmVersionStr ver) $$ - "We will try though..." - - when (isNothing mb_ver) $ do - let doWarn = llvmCgDoWarn cfg - when doWarn $ putMsg logger $ - "Failed to detect LLVM version!" $$ - "Make sure LLVM is installed correctly." $$ - "We will try though..." - - -- HACK: the Nothing case here is potentially wrong here but we - -- currently don't use the LLVM version to guide code generation - -- so this is okay. - let llvm_ver :: LlvmVersion - llvm_ver = fromMaybe supportedLlvmVersionLowerBound mb_ver - -- run code generation - (a, _) <- runLlvm logger cfg llvm_ver bufh dus $ + (a, _) <- runLlvm logger cfg bufh dus $ llvmCodeGen' cfg cmm_stream bFlush bufh diff --git a/compiler/GHC/CmmToLlvm/Base.hs b/compiler/GHC/CmmToLlvm/Base.hs index 23f9e911520..d3e46b66407 100644 --- a/compiler/GHC/CmmToLlvm/Base.hs +++ b/compiler/GHC/CmmToLlvm/Base.hs @@ -18,7 +18,7 @@ module GHC.CmmToLlvm.Base ( LlvmM, runLlvm, withClearVars, varLookup, varInsert, markStackReg, checkStackReg, - funLookup, funInsert, getLlvmVer, + funLookup, funInsert, dumpIfSetLlvm, renderLlvm, markUsedVar, getUsedVars, ghcInternalFunctions, getPlatform, getConfig, @@ -277,8 +277,7 @@ llvmPtrBits platform = widthInBits $ typeWidth $ gcWord platform -- data LlvmEnv = LlvmEnv - { envVersion :: LlvmVersion -- ^ LLVM version - , envConfig :: !LlvmCgConfig -- ^ Configuration for LLVM code gen + { envConfig :: !LlvmCgConfig -- ^ Configuration for LLVM code gen , envLogger :: !Logger -- ^ Logger , envOutput :: BufHandle -- ^ Output buffer , envTag :: !Char -- ^ Tag for creating unique values @@ -331,8 +330,8 @@ liftUDSMT m = LlvmM $ \env -> do x <- m return (x, env) -- | Get initial Llvm environment. -runLlvm :: Logger -> LlvmCgConfig -> LlvmVersion -> BufHandle -> DSM.DUniqSupply -> LlvmM a -> IO (a, DSM.DUniqSupply) -runLlvm logger cfg ver out us m = do +runLlvm :: Logger -> LlvmCgConfig -> BufHandle -> DSM.DUniqSupply -> LlvmM a -> IO (a, DSM.DUniqSupply) +runLlvm logger cfg out us m = do ((a, _), us') <- DSM.runUDSMT us $ runLlvmM m env return (a, us') where env = LlvmEnv { envFunMap = emptyUFM @@ -340,7 +339,6 @@ runLlvm logger cfg ver out us m = do , envStackRegs = [] , envUsedVars = [] , envAliases = emptyUniqSet - , envVersion = ver , envConfig = cfg , envLogger = logger , envOutput = out @@ -388,10 +386,6 @@ getMetaUniqueId :: LlvmM MetaId getMetaUniqueId = LlvmM $ \env -> return (envFreshMeta env, env { envFreshMeta = succ $ envFreshMeta env }) --- | Get the LLVM version we are generating code for -getLlvmVer :: LlvmM LlvmVersion -getLlvmVer = getEnv envVersion - -- | Dumps the document if the corresponding flag has been set by the user dumpIfSetLlvm :: DumpFlag -> String -> DumpFormat -> Outp.SDoc -> LlvmM () dumpIfSetLlvm flag hdr fmt doc = do diff --git a/compiler/GHC/CmmToLlvm/Config.hs b/compiler/GHC/CmmToLlvm/Config.hs index 1e7e04144f9..e1ef61a52a2 100644 --- a/compiler/GHC/CmmToLlvm/Config.hs +++ b/compiler/GHC/CmmToLlvm/Config.hs @@ -25,7 +25,6 @@ data LlvmCgConfig = LlvmCgConfig , llvmCgAvxEnabled :: !Bool , llvmCgBmiVersion :: Maybe BmiVersion -- ^ (x86) BMI instructions , llvmCgLlvmVersion :: Maybe LlvmVersion -- ^ version of Llvm we're using - , llvmCgDoWarn :: !Bool -- ^ True ==> warn unsupported Llvm version , llvmCgLlvmTarget :: !String -- ^ target triple passed to LLVM , llvmCgLlvmConfig :: !LlvmConfig -- ^ Supported LLVM configurations. -- see Note [LLVM configuration] diff --git a/compiler/GHC/CmmToLlvm/Version.hs b/compiler/GHC/CmmToLlvm/Version.hs index 9c3412f9316..a77977e47c4 100644 --- a/compiler/GHC/CmmToLlvm/Version.hs +++ b/compiler/GHC/CmmToLlvm/Version.hs @@ -1,9 +1,6 @@ module GHC.CmmToLlvm.Version ( LlvmVersion(..) - , supportedLlvmVersionLowerBound - , supportedLlvmVersionUpperBound , parseLlvmVersion - , llvmVersionSupported , llvmVersionStr , llvmVersionList ) @@ -12,7 +9,6 @@ where import GHC.Prelude import GHC.CmmToLlvm.Version.Type -import GHC.CmmToLlvm.Version.Bounds import Data.Char (isDigit) import Data.List (intercalate) @@ -32,10 +28,6 @@ parseLlvmVersion = where (ver_str, rest) = span isDigit s -llvmVersionSupported :: LlvmVersion -> Bool -llvmVersionSupported v = - v >= supportedLlvmVersionLowerBound && v < supportedLlvmVersionUpperBound - llvmVersionStr :: LlvmVersion -> String llvmVersionStr = intercalate "." . map show . llvmVersionList diff --git a/compiler/GHC/CmmToLlvm/Version/Bounds.hs.in b/compiler/GHC/CmmToLlvm/Version/Bounds.hs.in deleted file mode 100644 index 19f4e4d37a9..00000000000 --- a/compiler/GHC/CmmToLlvm/Version/Bounds.hs.in +++ /dev/null @@ -1,19 +0,0 @@ -module GHC.CmmToLlvm.Version.Bounds - ( supportedLlvmVersionLowerBound - , supportedLlvmVersionUpperBound - ) -where - -import GHC.Prelude () - -import GHC.CmmToLlvm.Version.Type - -import qualified Data.List.NonEmpty as NE - --- | The (inclusive) lower bound on the LLVM Version that is currently supported. -supportedLlvmVersionLowerBound :: LlvmVersion -supportedLlvmVersionLowerBound = LlvmVersion (@LlvmMinVersion@ NE.:| []) - --- | The (not-inclusive) upper bound bound on the LLVM Version that is currently supported. -supportedLlvmVersionUpperBound :: LlvmVersion -supportedLlvmVersionUpperBound = LlvmVersion (@LlvmMaxVersion@ NE.:| []) diff --git a/compiler/GHC/Driver/CodeOutput.hs b/compiler/GHC/Driver/CodeOutput.hs index ff5a25c3bae..023c4e1e365 100644 --- a/compiler/GHC/Driver/CodeOutput.hs +++ b/compiler/GHC/Driver/CodeOutput.hs @@ -255,12 +255,11 @@ outputJS _ _ _ _ _ = pgmError $ "codeOutput: Hit JavaScript case. We should neve -} {- -Note [Packaging libffi headers] +Note [libffi headers] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The C code emitted by GHC for libffi adjustors must depend upon the ffi_arg type, -defined in . For this reason, we must ensure that is available -in binary distributions. To do so, we install these headers as part of the -`rts` package. +defined in . On systems where GHC uses the libffi adjustors, the libffi +library, and headers must be installed. -} outputForeignStubs diff --git a/compiler/GHC/Driver/Config/CmmToLlvm.hs b/compiler/GHC/Driver/Config/CmmToLlvm.hs index c0a21c9cb1f..666e4342250 100644 --- a/compiler/GHC/Driver/Config/CmmToLlvm.hs +++ b/compiler/GHC/Driver/Config/CmmToLlvm.hs @@ -29,7 +29,6 @@ initLlvmCgConfig logger config_cache dflags = do ArchX86 -> bmiVersion dflags _ -> Nothing , llvmCgLlvmVersion = version - , llvmCgDoWarn = wopt Opt_WarnUnsupportedLlvmVersion dflags , llvmCgLlvmTarget = platformMisc_llvmTarget $! platformMisc dflags , llvmCgLlvmConfig = llvm_config } diff --git a/compiler/GHC/Driver/Config/Linker.hs b/compiler/GHC/Driver/Config/Linker.hs index bf4cc95f2db..489f3ba5bdf 100644 --- a/compiler/GHC/Driver/Config/Linker.hs +++ b/compiler/GHC/Driver/Config/Linker.hs @@ -20,8 +20,8 @@ initFrameworkOpts dflags = FrameworkOpts } -- | Initialize linker configuration from DynFlags -initLinkerConfig :: DynFlags -> LinkerConfig -initLinkerConfig dflags = +initLinkerConfig :: DynFlags -> Bool -> LinkerConfig +initLinkerConfig dflags require_cxx = let -- see Note [Solaris linker] ld_filter = case platformOS (targetPlatform dflags) of @@ -46,8 +46,13 @@ initLinkerConfig dflags = (p,pre_args) = pgm_l dflags post_args = map Option (getOpts dflags opt_l) + -- sneakily switch to C++ compiler when we need C++ standard lib + -- FIXME: ld flags may be totally inappropriate for the C++ compiler? + ld_prog = if require_cxx then pgm_cxx dflags else p + + in LinkerConfig - { linkerProgram = p + { linkerProgram = ld_prog , linkerOptionsPre = pre_args , linkerOptionsPost = post_args , linkerTempDir = tmpDir dflags diff --git a/compiler/GHC/Driver/Config/StgToJS.hs b/compiler/GHC/Driver/Config/StgToJS.hs index a737f9a242f..c27c1378537 100644 --- a/compiler/GHC/Driver/Config/StgToJS.hs +++ b/compiler/GHC/Driver/Config/StgToJS.hs @@ -34,7 +34,7 @@ initStgToJSConfig dflags = StgToJSConfig , csRuntimeAssert = False -- settings , csContext = initSDocContext dflags defaultDumpStyle - , csLinkerConfig = initLinkerConfig dflags + , csLinkerConfig = initLinkerConfig dflags False -- no C++ linking } -- | Default linker configuration diff --git a/compiler/GHC/Driver/Downsweep.hs b/compiler/GHC/Driver/Downsweep.hs index dafe1f834dc..d6f99f00fe4 100644 --- a/compiler/GHC/Driver/Downsweep.hs +++ b/compiler/GHC/Driver/Downsweep.hs @@ -506,7 +506,7 @@ loopFixedModule key loc done = do -- part of the compiler. lookupIfaceByModuleHsc hsc_env (mnkToModule key) >>= \case Just iface -> return (M.Succeeded iface) - Nothing -> readIface (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule key) (ml_hi_file loc) + Nothing -> readIface (hsc_hooks hsc_env) (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule key) (ml_hi_file loc) case read_result of M.Succeeded iface -> do -- Computer information about this node diff --git a/compiler/GHC/Driver/DynFlags.hs b/compiler/GHC/Driver/DynFlags.hs index 876ae7f72e2..e9f462f44fa 100644 --- a/compiler/GHC/Driver/DynFlags.hs +++ b/compiler/GHC/Driver/DynFlags.hs @@ -64,6 +64,7 @@ module GHC.Driver.DynFlags ( -- baseUnitId, + rtsWayUnitId, -- * Include specifications @@ -875,7 +876,8 @@ packageFlagsChanged idflags1 idflags0 = packageGFlags dflags = map (`gopt` dflags) [ Opt_HideAllPackages , Opt_HideAllPluginPackages - , Opt_AutoLinkPackages ] + , Opt_AutoLinkPackages + , Opt_NoRts ] instance Outputable PackageFlag where ppr (ExposePackage n arg rn) = text n <> braces (ppr arg <+> ppr rn) @@ -1472,6 +1474,17 @@ versionedFilePath platform = uniqueSubdir platform baseUnitId :: DynFlags -> UnitId baseUnitId dflags = unitSettings_baseUnitId (unitSettings dflags) +rtsWayUnitId :: DynFlags -> UnitId +rtsWayUnitId dflags | ways dflags `hasWay` WayThreaded + , ways dflags `hasWay` WayDebug + = stringToUnitId "rts:threaded-debug" + | ways dflags `hasWay` WayThreaded + = stringToUnitId "rts:threaded-nodebug" + | ways dflags `hasWay` WayDebug + = stringToUnitId "rts:nonthreaded-debug" + | otherwise + = stringToUnitId "rts:nonthreaded-nodebug" + -- SDoc ------------------------------------------- -- | Initialize the pretty-printing options diff --git a/compiler/GHC/Driver/Errors/Ppr.hs b/compiler/GHC/Driver/Errors/Ppr.hs index 3d83e44b132..33c990140ea 100644 --- a/compiler/GHC/Driver/Errors/Ppr.hs +++ b/compiler/GHC/Driver/Errors/Ppr.hs @@ -34,7 +34,6 @@ import GHC.HsToCore.Errors.Types (DsMessage) import GHC.Iface.Errors.Types import GHC.Tc.Errors.Ppr () -- instance Diagnostic TcRnMessage import GHC.Iface.Errors.Ppr () -- instance Diagnostic IfaceMessage -import GHC.CmmToLlvm.Version (llvmVersionStr, supportedLlvmVersionLowerBound, supportedLlvmVersionUpperBound) -- -- Suggestions @@ -276,12 +275,7 @@ instance Diagnostic DriverMessage where , nest 2 $ ppr node ] DriverNoConfiguredLLVMToolchain -> mkSimpleDecorated $ - text "GHC was not configured with a supported LLVM toolchain" $$ - text ("Make sure you have installed LLVM between [" - ++ llvmVersionStr supportedLlvmVersionLowerBound - ++ " and " - ++ llvmVersionStr supportedLlvmVersionUpperBound - ++ ") and reinstall GHC to make -fllvm work") + text "GHC was not configured with a supported LLVM toolchain" diagnosticReason = \case DriverUnknownMessage m diff --git a/compiler/GHC/Driver/Flags.hs b/compiler/GHC/Driver/Flags.hs index 666f138cb9d..b5d8230e0a8 100644 --- a/compiler/GHC/Driver/Flags.hs +++ b/compiler/GHC/Driver/Flags.hs @@ -859,6 +859,7 @@ data GeneralFlag -- temporary flags | Opt_AutoLinkPackages + | Opt_NoRts | Opt_ImplicitImportQualified -- keeping stuff @@ -1038,7 +1039,6 @@ data WarningFlag = | Opt_WarnMissedSpecs | Opt_WarnAllMissedSpecs | Opt_WarnUnsupportedCallingConventions - | Opt_WarnUnsupportedLlvmVersion | Opt_WarnMissedExtraSharedLib | Opt_WarnInlineRuleShadowing | Opt_WarnTypedHoles @@ -1172,7 +1172,6 @@ warnFlagNames wflag = case wflag of Opt_WarnMisplacedPragmas -> "misplaced-pragmas" :| [] Opt_WarnUnsafe -> "unsafe" :| [] Opt_WarnUnsupportedCallingConventions -> "unsupported-calling-conventions" :| [] - Opt_WarnUnsupportedLlvmVersion -> "unsupported-llvm-version" :| [] Opt_WarnMissedExtraSharedLib -> "missed-extra-shared-lib" :| [] Opt_WarnUntickedPromotedConstructors -> "unticked-promoted-constructors" :| [] Opt_WarnUnusedDoBind -> "unused-do-bind" :| [] @@ -1347,7 +1346,6 @@ standardWarnings -- see Note [Documenting warning flags] Opt_WarnDodgyForeignImports, Opt_WarnInlineRuleShadowing, Opt_WarnAlternativeLayoutRuleTransitional, - Opt_WarnUnsupportedLlvmVersion, Opt_WarnMissedExtraSharedLib, Opt_WarnTabs, Opt_WarnUnrecognisedWarningFlags, diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs index da026b01400..70035a4d710 100644 --- a/compiler/GHC/Driver/Make.hs +++ b/compiler/GHC/Driver/Make.hs @@ -1603,7 +1603,7 @@ executeCompileNode k n !old_hmi hug mrehydrate_mods mni = do executeCompileNodeFixed hsc_env MakeEnv{diag_wrapper, env_messager} mod loc = wrapAction diag_wrapper hsc_env $ do forM_ env_messager $ \hscMessage -> hscMessage hsc_env (k, n) UpToDate (ModuleNode [] (ModuleNodeFixed mod loc)) - read_result <- readIface (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule mod) (ml_hi_file loc) + read_result <- readIface (hsc_hooks hsc_env) (hsc_logger hsc_env) (hsc_dflags hsc_env) (hsc_NC hsc_env) (mnkToModule mod) (ml_hi_file loc) case read_result of M.Failed interface_err -> let mn = mnkModuleName mod diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs index 9eeb5876c9b..d7bb26a572c 100644 --- a/compiler/GHC/Driver/Session.hs +++ b/compiler/GHC/Driver/Session.hs @@ -1311,6 +1311,8 @@ dynamic_flags_deps = [ (NoArg (unSetGeneralFlag Opt_AutoLinkPackages)) , make_ord_flag defGhcFlag "no-hs-main" (NoArg (setGeneralFlag Opt_NoHsMain)) + , make_ord_flag defGhcFlag "no-rts" + (NoArg (setGeneralFlag Opt_NoRts)) , make_ord_flag defGhcFlag "fno-state-hack" (NoArg (setGeneralFlag Opt_G_NoStateHack)) , make_ord_flag defGhcFlag "fno-opt-coercion" @@ -2335,7 +2337,6 @@ wWarningFlagsDeps = [minBound..maxBound] >>= \x -> case x of Opt_WarnMisplacedPragmas -> warnSpec x Opt_WarnUnsafe -> warnSpec' x setWarnUnsafe Opt_WarnUnsupportedCallingConventions -> warnSpec x - Opt_WarnUnsupportedLlvmVersion -> warnSpec x Opt_WarnMissedExtraSharedLib -> warnSpec x Opt_WarnUntickedPromotedConstructors -> warnSpec x Opt_WarnUnusedDoBind -> warnSpec x @@ -3409,7 +3410,9 @@ picCCOpts dflags = else []) -- gcc may be configured to have PIC on by default, let's be -- explicit here, see #15847 - | otherwise -> ["-fno-PIC"] + -- FIXME: actually no, because -fPIC may be required for ASLR too! + -- Zig cc doesn't support `-fno-pic` in this case + | otherwise -> [] -- ["-fno-PIC"] pieCCLDOpts :: DynFlags -> [String] pieCCLDOpts dflags diff --git a/compiler/GHC/Iface/Errors/Ppr.hs b/compiler/GHC/Iface/Errors/Ppr.hs index d9f07343d24..ab4301ac3e3 100644 --- a/compiler/GHC/Iface/Errors/Ppr.hs +++ b/compiler/GHC/Iface/Errors/Ppr.hs @@ -42,6 +42,7 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Iface.Errors.Types +import qualified Data.List as List defaultIfaceMessageOpts :: IfaceMessageOpts defaultIfaceMessageOpts = IfaceMessageOpts { ifaceShowTriedFiles = False @@ -174,14 +175,12 @@ cantFindErrorX pkg_hidden_hint may_show_locations mod_or_interface (CantFindInst looks_like_srcpkgid = -- Unsafely coerce a unit id (i.e. an installed package component -- identifier) into a PackageId and see if it means anything. - case cands of - (pkg:pkgs) -> - parens (text "This unit ID looks like the source package ID;" $$ - text "the real unit ID is" <+> quotes (ftext (unitIdFS (unitId pkg))) $$ - (if null pkgs then empty - else text "and" <+> int (length pkgs) <+> text "other candidate" <> plural pkgs)) + case List.sortOn unitPackageNameString cands of -- Todo: also check if it looks like a package name! [] -> empty + pkgs -> + parens (text "This unit-id looks like a source package name-version;" <+> + text "candidates real unit-ids are:" $$ vcat (map (quotes . ftext . unitIdFS . unitId) pkgs)) in hsep [ text "no unit id matching" <+> quotes (ppr pkg) , text "was found"] $$ looks_like_srcpkgid @@ -336,8 +335,8 @@ hiModuleNameMismatchWarn requested_mod read_mod ] ] | otherwise = - -- ToDo: This will fail to have enough qualification when the package IDs - -- are the same + -- Display fully qualified unit names by enabling ppr-debug + updSDocContext (\ctx -> ctx { sdocPprDebug = True}) $ withPprStyle (mkUserStyle alwaysQualify AllTheWay) $ -- we want the Modules below to be qualified with package names, -- so reset the NamePprCtx setting. @@ -345,7 +344,6 @@ hiModuleNameMismatchWarn requested_mod read_mod , ppr requested_mod , text "differs from name found in the interface file" , ppr read_mod - , parens (text "if these names look the same, try again with -dppr-debug") ] dynamicHashMismatchError :: Module -> ModLocation -> SDoc diff --git a/compiler/GHC/Iface/Load.hs b/compiler/GHC/Iface/Load.hs index aa2319f170c..129ce98a49c 100644 --- a/compiler/GHC/Iface/Load.hs +++ b/compiler/GHC/Iface/Load.hs @@ -895,6 +895,7 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do mhome_unit = hsc_home_unit_maybe hsc_env dflags = hsc_dflags hsc_env logger = hsc_logger hsc_env + hooks = hsc_hooks hsc_env trace_if logger (sep [hsep [text "Reading", @@ -905,61 +906,53 @@ findAndReadIface hsc_env doc_str mod wanted_mod hi_boot_file = do ppr mod <> semi], nest 4 (text "reason:" <+> doc_str)]) - -- Check for GHC.Prim, and return its static interface - -- See Note [GHC.Prim] in primops.txt.pp. - -- TODO: make this check a function - if mod `installedModuleEq` gHC_PRIM - then do - let iface = getGhcPrimIface hsc_env - return (Succeeded (iface, panic "GHC.Prim ModLocation (findAndReadIface)")) - else do - -- Look for the file - mb_found <- liftIO (findExactModule hsc_env mod hi_boot_file) - case mb_found of - InstalledFound loc -> do - -- See Note [Home module load error] - case mhome_unit of - Just home_unit - | isHomeInstalledModule home_unit mod - , not (isOneShot (ghcMode dflags)) - -> return (Failed (HomeModError mod loc)) - _ -> do - r <- read_file logger name_cache unit_state dflags wanted_mod (ml_hi_file loc) - case r of - Failed err - -> return (Failed $ BadIfaceFile err) - Succeeded (iface,_fp) - -> do - r2 <- load_dynamic_too_maybe logger name_cache unit_state - (setDynamicNow dflags) wanted_mod - iface loc - case r2 of - Failed sdoc -> return (Failed sdoc) - Succeeded {} -> return $ Succeeded (iface, loc) - err -> do - trace_if logger (text "...not found") - return $ Failed $ cannotFindInterface - unit_state - mhome_unit - profile - (moduleName mod) - err + -- Look for the file + mb_found <- liftIO (findExactModule hsc_env mod hi_boot_file) + case mb_found of + InstalledFound loc -> do + -- See Note [Home module load error] + case mhome_unit of + Just home_unit + | isHomeInstalledModule home_unit mod + , not (isOneShot (ghcMode dflags)) + -> return (Failed (HomeModError mod loc)) + _ -> do + r <- read_file hooks logger name_cache unit_state dflags wanted_mod (ml_hi_file loc) + case r of + Failed err + -> return (Failed $ BadIfaceFile err) + Succeeded (iface,_fp) + -> do + r2 <- load_dynamic_too_maybe hooks logger name_cache unit_state + (setDynamicNow dflags) wanted_mod + iface loc + case r2 of + Failed sdoc -> return (Failed sdoc) + Succeeded {} -> return $ Succeeded (iface, loc) + err -> do + trace_if logger (text "...not found") + return $ Failed $ cannotFindInterface + unit_state + mhome_unit + profile + (moduleName mod) + err -- | Check if we need to try the dynamic interface for -dynamic-too -load_dynamic_too_maybe :: Logger -> NameCache -> UnitState -> DynFlags +load_dynamic_too_maybe :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags -> Module -> ModIface -> ModLocation -> IO (MaybeErr MissingInterfaceError ()) -load_dynamic_too_maybe logger name_cache unit_state dflags wanted_mod iface loc +load_dynamic_too_maybe hooks logger name_cache unit_state dflags wanted_mod iface loc -- Indefinite interfaces are ALWAYS non-dynamic. | not (moduleIsDefinite (mi_module iface)) = return (Succeeded ()) - | gopt Opt_BuildDynamicToo dflags = load_dynamic_too logger name_cache unit_state dflags wanted_mod iface loc + | gopt Opt_BuildDynamicToo dflags = load_dynamic_too hooks logger name_cache unit_state dflags wanted_mod iface loc | otherwise = return (Succeeded ()) -load_dynamic_too :: Logger -> NameCache -> UnitState -> DynFlags +load_dynamic_too :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags -> Module -> ModIface -> ModLocation -> IO (MaybeErr MissingInterfaceError ()) -load_dynamic_too logger name_cache unit_state dflags wanted_mod iface loc = do - read_file logger name_cache unit_state dflags wanted_mod (ml_dyn_hi_file loc) >>= \case +load_dynamic_too hooks logger name_cache unit_state dflags wanted_mod iface loc = do + read_file hooks logger name_cache unit_state dflags wanted_mod (ml_dyn_hi_file loc) >>= \case Succeeded (dynIface, _) | mi_mod_hash iface == mi_mod_hash dynIface -> return (Succeeded ()) @@ -973,10 +966,10 @@ load_dynamic_too logger name_cache unit_state dflags wanted_mod iface loc = do -read_file :: Logger -> NameCache -> UnitState -> DynFlags +read_file :: Hooks -> Logger -> NameCache -> UnitState -> DynFlags -> Module -> FilePath -> IO (MaybeErr ReadInterfaceError (ModIface, FilePath)) -read_file logger name_cache unit_state dflags wanted_mod file_path = do +read_file hooks logger name_cache unit_state dflags wanted_mod file_path = do -- Figure out what is recorded in mi_module. If this is -- a fully definite interface, it'll match exactly, but @@ -987,7 +980,7 @@ read_file logger name_cache unit_state dflags wanted_mod file_path = do (_, Just indef_mod) -> instModuleToModule unit_state (uninstantiateInstantiatedModule indef_mod) - read_result <- readIface logger dflags name_cache wanted_mod' file_path + read_result <- readIface hooks logger dflags name_cache wanted_mod' file_path case read_result of Failed err -> return (Failed err) Succeeded iface -> return (Succeeded (iface, file_path)) @@ -1014,29 +1007,37 @@ flagsToIfCompression dflags -- Failed err <=> file not found, or unreadable, or illegible -- Succeeded iface <=> successfully found and parsed readIface - :: Logger + :: Hooks + -> Logger -> DynFlags -> NameCache -> Module -> FilePath -> IO (MaybeErr ReadInterfaceError ModIface) -readIface logger dflags name_cache wanted_mod file_path = do +readIface hooks logger dflags name_cache wanted_mod file_path = do trace_if logger (text "readIFace" <+> text file_path) - let profile = targetProfile dflags - res <- tryMost $ readBinIface profile name_cache CheckHiWay QuietBinIFace file_path - case res of - Right iface - -- NB: This check is NOT just a sanity check, it is - -- critical for correctness of recompilation checking - -- (it lets us tell when -this-unit-id has changed.) - | wanted_mod == actual_mod - -> return (Succeeded iface) - | otherwise -> return (Failed err) - where - actual_mod = mi_module iface - err = HiModuleNameMismatchWarn file_path wanted_mod actual_mod - - Left exn -> return (Failed (ExceptionOccurred file_path exn)) + -- Check for GHC.Prim, and return its static interface + -- See Note [GHC.Prim] in primops.txt.pp. + if wanted_mod == gHC_PRIM + then do + -- TODO: should we check for the existence of the file? + return (Succeeded (getGhcPrimIface hooks)) + else do + let profile = targetProfile dflags + res <- tryMost $ readBinIface profile name_cache CheckHiWay QuietBinIFace file_path + case res of + Right iface + -- NB: This check is NOT just a sanity check, it is + -- critical for correctness of recompilation checking + -- (it lets us tell when -this-unit-id has changed.) + | wanted_mod == actual_mod + -> return (Succeeded iface) + | otherwise -> return (Failed err) + where + actual_mod = mi_module iface + err = HiModuleNameMismatchWarn file_path wanted_mod actual_mod + + Left exn -> return (Failed (ExceptionOccurred file_path exn)) {- ********************************************************* @@ -1247,8 +1248,8 @@ instance Outputable WhereFrom where -- This is a helper function that takes into account the hook allowing ghc-prim -- interface to be extended via the ghc-api. Afaik it was introduced for GHCJS -- so that it can add its own primitive types. -getGhcPrimIface :: HscEnv -> ModIface -getGhcPrimIface hsc_env = - case ghcPrimIfaceHook (hsc_hooks hsc_env) of +getGhcPrimIface :: Hooks -> ModIface +getGhcPrimIface hooks = + case ghcPrimIfaceHook hooks of Nothing -> ghcPrimIface Just h -> h diff --git a/compiler/GHC/Iface/Make.hs b/compiler/GHC/Iface/Make.hs index 75153f547fd..e83a322c986 100644 --- a/compiler/GHC/Iface/Make.hs +++ b/compiler/GHC/Iface/Make.hs @@ -156,7 +156,7 @@ mkFullIface hsc_env partial_iface mb_stg_infos mb_cmm_infos stubs foreign_files putDumpFileMaybe (hsc_logger hsc_env) Opt_D_dump_hi "FINAL INTERFACE" FormatText (pprModIface unit_state full_iface) final_iface <- shareIface (hsc_NC hsc_env) (flagsToIfCompression $ hsc_dflags hsc_env) full_iface - return final_iface + return $ final_iface -- | Compress an 'ModIface' and share as many values as possible, depending on the 'CompressionIFace' level. -- See Note [Sharing of ModIface]. diff --git a/compiler/GHC/Iface/Recomp.hs b/compiler/GHC/Iface/Recomp.hs index a65eb39cbfd..f8081a21945 100644 --- a/compiler/GHC/Iface/Recomp.hs +++ b/compiler/GHC/Iface/Recomp.hs @@ -304,7 +304,7 @@ check_old_iface hsc_env mod_summary maybe_iface loadIface read_dflags iface_path = do let ncu = hsc_NC hsc_env - read_result <- readIface logger read_dflags ncu (ms_mod mod_summary) iface_path + read_result <- readIface (hsc_hooks hsc_env) logger read_dflags ncu (ms_mod mod_summary) iface_path case read_result of Failed err -> do let msg = readInterfaceErrorDiagnostic err diff --git a/compiler/GHC/Linker/Dynamic.hs b/compiler/GHC/Linker/Dynamic.hs index b8aedd90acf..c7cbacbb645 100644 --- a/compiler/GHC/Linker/Dynamic.hs +++ b/compiler/GHC/Linker/Dynamic.hs @@ -24,6 +24,7 @@ import GHC.Linker.Unit import GHC.Linker.External import GHC.Utils.Logger import GHC.Utils.TmpFs +import GHC.Data.FastString import Control.Monad (when) import System.FilePath @@ -85,7 +86,7 @@ linkDynLib logger tmpfs dflags0 unit_env o_files dep_packages -- WASM_DYLINK_NEEDED, otherwise dyld can't load it. -- -- - let pkgs_without_rts = filter ((/= rtsUnitId) . unitId) pkgs_with_rts + let pkgs_without_rts = filter ((/= PackageName (fsLit "rts")) . unitPackageName) pkgs_with_rts pkgs | ArchWasm32 <- arch = pkgs_with_rts | OSMinGW32 <- os = pkgs_with_rts @@ -105,7 +106,8 @@ linkDynLib logger tmpfs dflags0 unit_env o_files dep_packages pkg_framework_opts <- getUnitFrameworkOpts unit_env (map unitId pkgs) let framework_opts = getFrameworkOpts (initFrameworkOpts dflags) platform - let linker_config = initLinkerConfig dflags + let require_cxx = any ((==) (PackageName (fsLit "system-cxx-std-lib")) . unitPackageName) pkgs + let linker_config = initLinkerConfig dflags require_cxx case os of OSMinGW32 -> do diff --git a/compiler/GHC/Linker/ExtraObj.hs b/compiler/GHC/Linker/ExtraObj.hs index a26a31eed7c..db0fe4f2ab1 100644 --- a/compiler/GHC/Linker/ExtraObj.hs +++ b/compiler/GHC/Linker/ExtraObj.hs @@ -63,8 +63,17 @@ mkExtraObj logger tmpfs dflags unit_state extn xs -- we're compiling C or assembler. When compiling C, we pass the usual -- set of include directories and PIC flags. cOpts = map Option (picCCOpts dflags) - ++ map (FileOption "-I" . ST.unpack) - (unitIncludeDirs $ unsafeLookupUnit unit_state rtsUnit) + ++ map (FileOption "-I") + (collectIncludeDirs $ depClosure unit_state [unsafeLookupUnit unit_state rtsUnit]) + depClosure :: UnitState -> [UnitInfo] -> [UnitInfo] + depClosure us initial = go [] initial + where + go seen [] = seen + go seen (ui:uis) + | ui `elem` seen = go seen uis + | otherwise = + let deps = map (unsafeLookupUnitId us) (unitDepends ui) + in go (ui:seen) (deps ++ uis) -- When linking a binary, we need to create a C main() function that -- starts everything off. This used to be compiled statically as part diff --git a/compiler/GHC/Linker/Loader.hs b/compiler/GHC/Linker/Loader.hs index bb5116e2f05..51a5c304fb8 100644 --- a/compiler/GHC/Linker/Loader.hs +++ b/compiler/GHC/Linker/Loader.hs @@ -48,6 +48,7 @@ import GHC.Driver.Session import GHC.Driver.Ppr import GHC.Driver.Config.Diagnostic import GHC.Driver.Config.Finder +import GHC.Driver.DynFlags (rtsWayUnitId) import GHC.Tc.Utils.Monad @@ -168,8 +169,8 @@ getLoaderState :: Interp -> IO (Maybe LoaderState) getLoaderState interp = readMVar (loader_state (interpLoader interp)) -emptyLoaderState :: LoaderState -emptyLoaderState = LoaderState +emptyLoaderState :: DynFlags -> LoaderState +emptyLoaderState dflags = LoaderState { linker_env = LinkerEnv { closure_env = emptyNameEnv , itbl_env = emptyNameEnv @@ -185,7 +186,14 @@ emptyLoaderState = LoaderState -- -- The linker's symbol table is populated with RTS symbols using an -- explicit list. See rts/Linker.c for details. - where init_pkgs = unitUDFM rtsUnitId (LoadedPkgInfo rtsUnitId [] [] [] emptyUniqDSet) + where init_pkgs = let addToUDFM' (k, v) m = addToUDFM m k v + in foldr addToUDFM' emptyUDFM [ + (rtsUnitId, (LoadedPkgInfo rtsUnitId [] [] [] emptyUniqDSet)) + -- FIXME? Should this be the rtsWayUnitId of the current ghc, or the one + -- for the target build? I think target-build seems right, but I'm + -- not fully convinced. + , (rtsWayUnitId dflags, (LoadedPkgInfo (rtsWayUnitId dflags) [] [] [] emptyUniqDSet)) + ] extendLoadedEnv :: Interp -> [(Name,ForeignHValue)] -> IO () extendLoadedEnv interp new_bindings = @@ -325,7 +333,7 @@ initLoaderState interp hsc_env = do reallyInitLoaderState :: Interp -> HscEnv -> IO LoaderState reallyInitLoaderState interp hsc_env = do -- Initialise the linker state - let pls0 = emptyLoaderState + let pls0 = emptyLoaderState (hsc_dflags hsc_env) case platformArch (targetPlatform (hsc_dflags hsc_env)) of -- FIXME: we don't initialize anything with the JS interpreter. diff --git a/compiler/GHC/Linker/Static.hs b/compiler/GHC/Linker/Static.hs index ef356d72435..8a634258e7f 100644 --- a/compiler/GHC/Linker/Static.hs +++ b/compiler/GHC/Linker/Static.hs @@ -33,6 +33,8 @@ import GHC.Linker.Static.Utils import GHC.Driver.Config.Linker import GHC.Driver.Session +import GHC.Data.FastString + import System.FilePath import System.Directory import Control.Monad @@ -192,7 +194,9 @@ linkBinary' staticLink logger tmpfs dflags unit_env o_files dep_units = do OSMinGW32 | gopt Opt_GenManifest dflags -> maybeCreateManifest logger tmpfs dflags output_fn _ -> return [] - let linker_config = initLinkerConfig dflags + let require_cxx = any ((==) (PackageName (fsLit "system-cxx-std-lib")) . unitPackageName) pkgs + + let linker_config = initLinkerConfig dflags require_cxx let link dflags args = do runLink logger tmpfs linker_config args -- Make sure to honour -fno-use-rpaths if set on darwin as well; see #20004 @@ -289,7 +293,7 @@ linkStaticLib logger dflags unit_env o_files dep_units = do | gopt Opt_LinkRts dflags = pkg_cfgs_init | otherwise - = filter ((/= rtsUnitId) . unitId) pkg_cfgs_init + = filter ((/= PackageName (fsLit "rts")) . unitPackageName) pkg_cfgs_init archives <- concatMapM (collectArchives namever ways_) pkg_cfgs diff --git a/compiler/GHC/Runtime/Loader.hs b/compiler/GHC/Runtime/Loader.hs index a6b236441e4..5dc5a838efb 100644 --- a/compiler/GHC/Runtime/Loader.hs +++ b/compiler/GHC/Runtime/Loader.hs @@ -219,7 +219,7 @@ loadPlugin' occ_name plugin_name hsc_env mod_name [ text "The value", ppr name , text "with type", ppr actual_type , text "did not have the type" - , text "GHC.Plugins.Plugin" + , ppr (mkTyConTy plugin_tycon) , text "as required"]) Right (plugin, links, pkgs) -> return (plugin, mod_iface, links, pkgs) } } } } } diff --git a/compiler/GHC/SysTools/Process.hs b/compiler/GHC/SysTools/Process.hs index cebd46aeb02..226f14b460e 100644 --- a/compiler/GHC/SysTools/Process.hs +++ b/compiler/GHC/SysTools/Process.hs @@ -217,7 +217,7 @@ handleProc pgm phase_name proc = do does_not_exist = throwGhcExceptionIO $ - InstallationError (phase_name ++ ": could not execute: " ++ pgm) + InstallationError (phase_name ++ ": could not execute: `" ++ pgm ++ "'") withPipe :: ((Handle, Handle) -> IO a) -> IO a withPipe = bracket createPipe $ \ (readEnd, writeEnd) -> do diff --git a/compiler/GHC/SysTools/Tasks.hs b/compiler/GHC/SysTools/Tasks.hs index 97c6ae9d584..9a54c6c61ee 100644 --- a/compiler/GHC/SysTools/Tasks.hs +++ b/compiler/GHC/SysTools/Tasks.hs @@ -31,7 +31,7 @@ module GHC.SysTools.Tasks import GHC.Prelude import GHC.ForeignSrcLang -import GHC.CmmToLlvm.Version (LlvmVersion, llvmVersionStr, supportedLlvmVersionUpperBound, parseLlvmVersion, supportedLlvmVersionLowerBound) +import GHC.CmmToLlvm.Version (LlvmVersion, parseLlvmVersion) import GHC.Settings @@ -346,14 +346,10 @@ figureLlvmVersion logger dflags = traceSystoolCommand logger "llc" $ do debugTraceMsg logger 2 (text "Error (figuring out LLVM version):" <+> text (show err)) + -- TODO: review this errorMsg logger $ vcat [ text "Warning:", nest 9 $ - text "Couldn't figure out LLVM version!" $$ - text ("Make sure you have installed LLVM between [" - ++ llvmVersionStr supportedLlvmVersionLowerBound - ++ " and " - ++ llvmVersionStr supportedLlvmVersionUpperBound - ++ ")") ] + text "Couldn't figure out LLVM version!" ] return Nothing) -- See Note [Merging object files for GHCi] in GHC.Driver.Pipeline. diff --git a/compiler/GHC/Unit/Info.hs b/compiler/GHC/Unit/Info.hs index 04ac54b5d31..b224704a5d5 100644 --- a/compiler/GHC/Unit/Info.hs +++ b/compiler/GHC/Unit/Info.hs @@ -205,14 +205,13 @@ libraryDirsForWay ws | otherwise = map ST.unpack . unitLibraryDirs unitHsLibs :: GhcNameVersion -> Ways -> UnitInfo -> [String] -unitHsLibs namever ways0 p = map (mkDynName . addSuffix . ST.unpack) (unitLibraries p) +unitHsLibs namever ways0 p = map (mkDynName . ST.unpack) (unitLibraries p) where ways1 = removeWay WayDyn ways0 -- the name of a shared library is libHSfoo-ghc.so -- we leave out the _dyn, because it is superfluous tag = waysTag (fullWays ways1) - rts_tag = waysTag ways1 mkDynName x | not (ways0 `hasWay` WayDyn) = x @@ -225,19 +224,3 @@ unitHsLibs namever ways0 p = map (mkDynName . addSuffix . ST.unpack) (unitLibrar | otherwise = panic ("Don't understand library name " ++ x) - -- Add _thr and other rts suffixes to packages named - -- `rts` or `rts-1.0`. Why both? Traditionally the rts - -- package is called `rts` only. However the tooling - -- usually expects a package name to have a version. - -- As such we will gradually move towards the `rts-1.0` - -- package name, at which point the `rts` package name - -- will eventually be unused. - -- - -- This change elevates the need to add custom hooks - -- and handling specifically for the `rts` package. - addSuffix rts@"HSrts" = rts ++ (expandTag rts_tag) - addSuffix rts@"HSrts-1.0.3" = rts ++ (expandTag rts_tag) - addSuffix other_lib = other_lib ++ (expandTag tag) - - expandTag t | null t = "" - | otherwise = '_':t diff --git a/compiler/GHC/Unit/Module/ModIface.hs b/compiler/GHC/Unit/Module/ModIface.hs index 25001860431..eee1249742a 100644 --- a/compiler/GHC/Unit/Module/ModIface.hs +++ b/compiler/GHC/Unit/Module/ModIface.hs @@ -43,6 +43,7 @@ module GHC.Unit.Module.ModIface , mi_hash_fn ) , pattern ModIface + , get_mi_mod_info , set_mi_mod_info , set_mi_module , set_mi_sig_of @@ -978,6 +979,9 @@ completePublicModIface decls abi_hashes cache partial = partial , mi_caches_ = cache } +get_mi_mod_info :: ModIface_ phase -> IfaceModInfo +get_mi_mod_info iface = mi_mod_info_ iface + set_mi_mod_info :: IfaceModInfo -> ModIface_ phase -> ModIface_ phase set_mi_mod_info val iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = val } @@ -1083,8 +1087,6 @@ set_mi_mod_info_field :: (IfaceModInfo -> IfaceModInfo) -> ModIface_ phase -> Mo set_mi_mod_info_field f iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = f (mi_mod_info_ iface) } - - -- | Invalidate any byte array buffer we might have. clear_mi_hi_bytes :: ModIface_ phase -> ModIface_ phase clear_mi_hi_bytes iface = iface diff --git a/compiler/GHC/Unit/State.hs b/compiler/GHC/Unit/State.hs index 463247e72f9..6f71555dc4d 100644 --- a/compiler/GHC/Unit/State.hs +++ b/compiler/GHC/Unit/State.hs @@ -112,6 +112,7 @@ import Data.Graph (stronglyConnComp, SCC(..)) import Data.Char ( toUpper ) import Data.List ( intersperse, partition, sortBy, isSuffixOf, sortOn ) import Data.Set (Set) +import Data.String (fromString) import Data.Monoid (First(..)) import qualified Data.Semigroup as Semigroup import qualified Data.Set as Set @@ -370,7 +371,7 @@ initUnitConfig dflags cached_dbs home_units = -- Since "base" is not wired in, then the unit-id is discovered -- from the settings file by default, but can be overriden by power-users -- by specifying `-base-unit-id` flag. - | otherwise = filter (hu_id /=) [baseUnitId dflags, ghcInternalUnitId, rtsUnitId] + | otherwise = filter (hu_id /=) [baseUnitId dflags, ghcInternalUnitId, rtsWayUnitId dflags, rtsUnitId] -- if the home unit is indefinite, it means we are type-checking it only -- (not producing any code). Hence we can use virtual units instantiated @@ -644,7 +645,7 @@ initUnits logger dflags cached_dbs home_units = do (unit_state,dbs) <- withTiming logger (text "initializing unit database") forceUnitInfoMap - $ mkUnitState logger (initUnitConfig dflags cached_dbs home_units) + $ mkUnitState logger dflags (initUnitConfig dflags cached_dbs home_units) putDumpFileMaybe logger Opt_D_dump_mod_map "Module Map" FormatText (updSDocContext (\ctx -> ctx {sdocLineLength = 200}) @@ -1093,6 +1094,7 @@ type WiringMap = UniqMap UnitId UnitId findWiredInUnits :: Logger + -> [UnitId] -- wired in unit ids -> UnitPrecedenceMap -> [UnitInfo] -- database -> VisibilityMap -- info on what units are visible @@ -1100,13 +1102,22 @@ findWiredInUnits -> IO ([UnitInfo], -- unit database updated for wired in WiringMap) -- map from unit id to wired identity -findWiredInUnits logger prec_map pkgs vis_map = do +findWiredInUnits logger unitIdsToFind prec_map pkgs vis_map = do -- Now we must find our wired-in units, and rename them to -- their canonical names (eg. base-1.0 ==> base), as described -- in Note [Wired-in units] in GHC.Unit.Types let matches :: UnitInfo -> UnitId -> Bool - pc `matches` pid = unitPackageName pc == PackageName (unitIdFS pid) + pc `matches` pid | (pkg, comp) <- break (==':') (unitIdString pid) + , not (null comp) + = unitPackageName pc == PackageName (fromString pkg) + -- note: GenericUnitInfo uses the same type for + -- unitPackageName and unitComponentName + && unitComponentName pc == Just (PackageName (fromString (drop 1 comp))) + pc `matches` pid + = unitPackageName pc == PackageName (unitIdFS pid) + && unitComponentName pc == Nothing + -- find which package corresponds to each wired-in package -- delete any other packages with the same name @@ -1126,7 +1137,8 @@ findWiredInUnits logger prec_map pkgs vis_map = do -- available. -- findWiredInUnit :: [UnitInfo] -> UnitId -> IO (Maybe (UnitId, UnitInfo)) - findWiredInUnit pkgs wired_pkg = firstJustsM [try all_exposed_ps, try all_ps, notfound] + findWiredInUnit pkgs wired_pkg = do + firstJustsM [try all_exposed_ps, try all_ps, notfound] where all_ps = [ p | p <- pkgs, p `matches` wired_pkg ] all_exposed_ps = [ p | p <- all_ps, (mkUnit p) `elemUniqMap` vis_map ] @@ -1151,7 +1163,7 @@ findWiredInUnits logger prec_map pkgs vis_map = do return (wired_pkg, pkg) - mb_wired_in_pkgs <- mapM (findWiredInUnit pkgs) wiredInUnitIds + mb_wired_in_pkgs <- mapM (findWiredInUnit pkgs) unitIdsToFind let wired_in_pkgs = catMaybes mb_wired_in_pkgs @@ -1239,8 +1251,10 @@ instance Outputable UnusableUnitReason where ppr IgnoredWithFlag = text "[ignored with flag]" ppr (BrokenDependencies uids) = brackets (text "broken" <+> ppr uids) ppr (CyclicDependencies uids) = brackets (text "cyclic" <+> ppr uids) - ppr (IgnoredDependencies uids) = brackets (text "ignored" <+> ppr uids) - ppr (ShadowedDependencies uids) = brackets (text "shadowed" <+> ppr uids) + ppr (IgnoredDependencies uids) = brackets (text $ "unusable because the -ignore-package flag was used to " ++ + "ignore at least one of its dependencies:") $$ + nest 2 (hsep (map ppr uids)) + ppr (ShadowedDependencies uids) = brackets (text "unusable due to shadowed" <+> ppr uids) type UnusableUnits = UniqMap UnitId (UnitInfo, UnusableUnitReason) @@ -1464,9 +1478,10 @@ validateDatabase cfg pkg_map1 = mkUnitState :: Logger + -> DynFlags -> UnitConfig -> IO (UnitState,[UnitDatabase UnitId]) -mkUnitState logger cfg = do +mkUnitState logger dflags cfg = do {- Plan. @@ -1621,8 +1636,72 @@ mkUnitState logger cfg = do -- it modifies the unit ids of wired in packages, but when we process -- package arguments we need to key against the old versions. -- - (pkgs2, wired_map) <- findWiredInUnits logger prec_map pkgs1 vis_map2 - let pkg_db = mkUnitInfoMap pkgs2 + (pkgs2, wired_map) <- findWiredInUnits logger (rtsWayUnitId dflags:wiredInUnitIds) prec_map pkgs1 vis_map2 + + -- + -- Sanity check. If the rtsWayUnitId is not in the database, then we have a + -- problem. The RTS is effectively missing. + unless (null pkgs1 || gopt Opt_NoRts dflags || anyUniqMap (== rtsWayUnitId dflags) wired_map) $ do + pprPanic "mkUnitState" $ + vcat + [ text "debug details:" + , nest 2 $ vcat + [ text "pkgs1_count =" <+> ppr (length pkgs1) + , text "Opt_NoRts =" <+> ppr (gopt Opt_NoRts dflags) + , text "ghcLink =" <+> text (show (ghcLink dflags)) + , text "platform =" <+> text (show (targetPlatform dflags)) + , text "rtsWayUnitId=" <+> ppr (rtsWayUnitId dflags) + , text "has_rts =" <+> ppr (anyUniqMap (== rtsWayUnitId dflags) wired_map) + , text "wired_map =" <+> ppr wired_map + , text "pkgs1 units (pre-wiring):" $$ nest 2 (pprWithCommas (\p -> ppr (unitId p) <+> parens (ppr (unitPackageName p))) pkgs1) + , text "pkgs2 units (post-wiring):" $$ nest 2 (pprWithCommas (\p -> ppr (unitId p) <+> parens (ppr (unitPackageName p))) pkgs2) + ] + ] + <> text "; The RTS for " <> ppr (rtsWayUnitId dflags) + <> text " is missing from the package database while building unit " + <> ppr (homeUnitId_ dflags) + <> text " (home units: " <> ppr (Set.toList (unitConfigHomeUnits cfg)) <> text ")." + <> text " Please check your installation." + <> text " If this target doesn't need the RTS (e.g. building a shared library), you can add -no-rts to the relevant package's ghc-options in cabal.project to bypass this check." + + let pkgs3 = if gopt Opt_NoRts dflags && not (anyUniqMap (== ghcInternalUnitId) wired_map) + then pkgs2 + else + -- At this point we should have `ghcInternalUnitId`, and the `rtsWiredUnitId dflags`. + -- The graph looks something like this: + -- ghc-internal + -- '- rtsWayUnitId dflags + -- '- rts ... + -- Notably the rtsWayUnitId is chosen by GHC _after_ the build plan by e.g. cabal + -- has been constructed. We still need to ensure that ordering when linking + -- is correct. As such we'll manually make rtsWayUnitId dflags a dependency + -- of ghcInternalUnitId. + + -- pkgs2: [UnitInfo] = [GenUnitInfo UnitId] = [GenericUnitInfo PackageId PackageName UnitId ModuleName (GenModule (GenUnit UnitId))] + -- GenericUnitInfo { unitId: UnitId, ..., unitAbiHash: ShortText, unitDepends: [UnitId], unitAbiDepends: [(UnitId, ShortText)], ... } + -- ghcInternalUnitId: UnitId + -- rtsWayUnitId dflags: UnitId + let rtsWayUnitIdHash = case [ unitAbiHash pkg | pkg <- pkgs2 + , unitId pkg == rtsWayUnitId dflags] of + [] -> panic "rtsWayUnitId not found in wired-in packages" + [x] -> x + _ -> panic "rtsWayUnitId found multiple times in wired-in packages" + ghcInternalUnit = case [ pkg | pkg <- pkgs2 + , unitId pkg == ghcInternalUnitId ] of + [] -> panic "ghcInternalUnitId not found in wired-in packages" + [x] -> x + _ -> panic "ghcInternalUnitId found multiple times in wired-in packages" + + -- update ghcInternalUnit to depend on rtsWayUnitId dflags + ghcInternalUnit' = ghcInternalUnit + { unitDepends = rtsWayUnitId dflags : unitDepends ghcInternalUnit + , unitAbiDepends = (rtsWayUnitId dflags, rtsWayUnitIdHash) : unitAbiDepends ghcInternalUnit + } + in map (\pkg -> if unitId pkg == ghcInternalUnitId + then ghcInternalUnit' + else pkg) pkgs2 + + let pkg_db = mkUnitInfoMap pkgs3 -- Update the visibility map, so we treat wired packages as visible. let vis_map = updateVisibilityMap wired_map vis_map2 @@ -1656,7 +1735,7 @@ mkUnitState logger cfg = do return (updateVisibilityMap wired_map plugin_vis_map2) let pkgname_map = listToUFM [ (unitPackageName p, unitInstanceOf p) - | p <- pkgs2 + | p <- pkgs3 ] -- The explicitUnits accurately reflects the set of units we have turned -- on; as such, it also is the only way one can come up with requirements. @@ -1754,7 +1833,8 @@ mkModuleNameProvidersMap logger cfg pkg_map closure vis_map = -- (e.g., hidden packages, causing #14717) -- -- * Folding on pkg_map is awkward because if we have an - -- Backpack instantiation, we need to possibly add a + -- Backpack instantiation, we need to + -- possibly add a -- package from pkg_map multiple times to the actual -- ModuleNameProvidersMap. Also, we don't really want -- definite package instantiations to show up in the diff --git a/compiler/Setup.hs b/compiler/Setup.hs index 42a58b5bb63..1614cd0227f 100644 --- a/compiler/Setup.hs +++ b/compiler/Setup.hs @@ -1,4 +1,5 @@ {-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE CPP #-} module Main where import Distribution.Simple @@ -11,6 +12,9 @@ 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.Process @@ -53,13 +57,22 @@ primopIncls = , ("primop-vector-tycons.hs-incl" , "--primop-vector-tycons") , ("primop-docs.hs-incl" , "--wired-in-docs") , ("primop-deprecations.hs-incl" , "--wired-in-deprecations") + , ("primop-prim-module.hs-incl" , "--prim-module") + , ("primop-wrappers-module.hs-incl" , "--wrappers-module") ] ghcAutogen :: Verbosity -> LocalBuildInfo -> IO () ghcAutogen verbosity lbi@LocalBuildInfo{pkgDescrFile,withPrograms,componentNameMap} = 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 <$> pkgDescrFile + let Just compilerRoot = (takeDirectory . fromSymPath) <$> pkgDescrFile -- Require the necessary programs (gcc ,withPrograms) <- requireProgram normal gccProgram withPrograms @@ -79,25 +92,31 @@ ghcAutogen verbosity lbi@LocalBuildInfo{pkgDescrFile,withPrograms,componentNameM -- Call genprimopcode to generate *.hs-incl forM_ primopIncls $ \(file,command) -> do contents <- readProcess "genprimopcode" [command] primopsStr - rewriteFileEx verbosity (buildDir lbi file) contents + rewriteFileEx verbosity (fromSymPath (buildDir lbi) file) contents -- Write GHC.Platform.Constants - let platformConstantsPath = autogenPackageModulesDir lbi "GHC/Platform/Constants.hs" + let platformConstantsPath = fromSymPath (autogenPackageModulesDir lbi) "GHC/Platform/Constants.hs" targetOS = case lookup "target os" settings of Nothing -> error "no target os in settings" Just os -> os createDirectoryIfMissingVerbose verbosity True (takeDirectory platformConstantsPath) +#if MIN_VERSION_Cabal(3,15,0) + -- temp files are now always created in system temp directory + -- (cf 8161f5f99dbe5d6c7564d9e163754935ddde205d) + withTempFile "Constants_tmp.hs" $ \tmp h -> do +#else withTempFile (takeDirectory platformConstantsPath) "Constants_tmp.hs" $ \tmp h -> do +#endif hClose h callProcess "deriveConstants" ["--gen-haskell-type","-o",tmp,"--target-os",targetOS] - renameFile tmp platformConstantsPath + copyFile tmp platformConstantsPath let cProjectUnitId = case Map.lookup (CLibName LMainLibName) componentNameMap of Just [LibComponentLocalBuildInfo{componentUnitId}] -> unUnitId componentUnitId _ -> error "Couldn't find unique cabal library when building ghc" -- Write GHC.Settings.Config - configHsPath = autogenPackageModulesDir lbi "GHC/Settings/Config.hs" + configHsPath = fromSymPath (autogenPackageModulesDir lbi) "GHC/Settings/Config.hs" configHs = generateConfigHs cProjectUnitId settings createDirectoryIfMissingVerbose verbosity True (takeDirectory configHsPath) rewriteFileEx verbosity configHsPath configHs diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in index 769b5d9d630..205f140fee1 100644 --- a/compiler/ghc.cabal.in +++ b/compiler/ghc.cabal.in @@ -32,25 +32,9 @@ extra-source-files: GHC/Builtin/primops.txt.pp Unique.h CodeGen.Platform.h - -- Shared with rts via hard-link at configure time. This is safer - -- for Windows, where symlinks don't work out of the box, so we - -- can't just commit some in git. - Bytecodes.h - ClosureTypes.h - FunTypes.h - MachRegs.h - MachRegs/arm32.h - MachRegs/arm64.h - MachRegs/loongarch64.h - MachRegs/ppc.h - MachRegs/riscv64.h - MachRegs/s390x.h - MachRegs/wasm32.h - MachRegs/x86.h - custom-setup - setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.14, directory, process, filepath, containers + setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.16, directory, process, filepath, containers Flag internal-interpreter Description: Build with internal interpreter support. @@ -67,6 +51,7 @@ Flag dynamic-system-linker Flag build-tool-depends Description: Use build-tool-depends Default: True + Manual: True Flag with-libzstd Default: False @@ -94,12 +79,8 @@ Flag bootstrap Library Default-Language: GHC2021 Exposed: False + Includes: Unique.h - -- CodeGen.Platform.h -- invalid as C, skip - -- shared with rts via symlink - Bytecodes.h - ClosureTypes.h - FunTypes.h if flag(build-tool-depends) build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants @@ -131,6 +112,7 @@ Library semaphore-compat, stm, rts, + rts-headers, ghc-boot == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, ghci == @ProjectVersionMunged@ @@ -351,7 +333,6 @@ Library GHC.CmmToLlvm.Ppr GHC.CmmToLlvm.Regs GHC.CmmToLlvm.Version - GHC.CmmToLlvm.Version.Bounds GHC.CmmToLlvm.Version.Type GHC.Cmm.Dominators GHC.Cmm.Reducibility diff --git a/configure b/configure new file mode 100755 index 00000000000..28faf2ddb45 --- /dev/null +++ b/configure @@ -0,0 +1,3073 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.72 for ghc-builder 0.1.0. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, +# Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else case e in #( + e) case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as 'sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed 'exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else case e in #( + e) case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : + +else case e in #( + e) exitcode=1; echo positional parameters were not saved. ;; +esac +fi +test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null +then : + as_have_required=yes +else case e in #( + e) as_have_required=no ;; +esac +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : + +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$as_shell as_have_required=yes + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : + break 2 +fi +fi + done;; + esac + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else case e in #( + e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi ;; +esac +fi + + + if test "x$CONFIG_SHELL" != x +then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed 'exec'. +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." + else + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and +$0: your-email@example.com about your system, including any +$0: error possibly output before this message. Then install +$0: a modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi ;; +esac +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else case e in #( + e) as_fn_append () + { + eval $1=\$$1\$2 + } ;; +esac +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else case e in #( + e) as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } ;; +esac +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + t clear + :clear + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated + +# Sed expression to map a string onto a valid variable name. +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='ghc-builder' +PACKAGE_TARNAME='ghc-builder' +PACKAGE_VERSION='0.1.0' +PACKAGE_STRING='ghc-builder 0.1.0' +PACKAGE_BUGREPORT='your-email@example.com' +PACKAGE_URL='' + +ac_unique_file="." +ac_subst_vars='LTLIBOBJS +LIBOBJS +PYTHON +SourceRoot +Suffix +ProjectPatchLevel2 +ProjectPatchLevel1 +ProjectPatchLevel +ProjectVersionForLib +ProjectVersionMunged +ProjectVersionInt +ProjectVersion +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_project_version +with_project_version_int +with_project_version_munged +with_project_version_for_lib +with_project_patch_level +with_project_patch_level1 +with_project_patch_level2 +' + ac_precious_vars='build_alias +host_alias +target_alias' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: '$ac_useropt'" + ac_useropt_orig=$ac_useropt + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: '$ac_option' +Try '$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: '$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: '$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +'configure' configures ghc-builder 0.1.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print 'checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for '--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or '..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, 'make install' will install all the files in +'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc. You can specify +an installation prefix other than '$ac_default_prefix' using '--prefix', +for instance '--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/ghc-builder] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ghc-builder 0.1.0:";; + esac + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-project-version=VER + GHC version (default: 9.13) + --with-project-version-int=VER + GHC version as int (default: 913) + --with-project-version-munged=VER + GHC version "munged" (default: 9.13) + --with-project-version-for-lib=VER + GHC version for libraries (default: 9.1300) + --with-project-patch-level=VER + GHC patchlevel version (default: 0) + --with-project-patch-level1=VER + GHC patchlevel1 version (default: 0) + --with-project-patch-level2=VER + GHC patchlevel2 version (default: 0) + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +ghc-builder configure 0.1.0 +generated by GNU Autoconf 2.72 + +Copyright (C) 2023 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by ghc-builder $as_me 0.1.0, which was +generated by GNU Autoconf 2.72. Invocation command line was + + $ $0$ac_configure_args_raw + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" + # Save into config.log some information that might help in debugging. + { + echo + + printf "%s\n" "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + printf "%s\n" "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + printf "%s\n" "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + printf "%s\n" "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + printf "%s\n" "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +printf "%s\n" "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h + +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + ac_site_files="$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" +else + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" +fi + +for ac_site_file in $ac_site_files +do + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See 'config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file' + and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + # A representative .in file + # Recommended place for config.guess, config.sub + # For any custom m4 macros +# AM_INIT_AUTOMAKE([-Wall -Werror foreign]) # Using some automake conventions + +# --- Define GHC Build Options --- +# Usage: ./configure ProjectVersion=X.Y ... + +# Check whether --with-project-version was given. +if test ${with_project_version+y} +then : + withval=$with_project_version; ProjectVersion="$withval" +else case e in #( + e) ProjectVersion="9.13" ;; +esac +fi + + +# Check whether --with-project-version-int was given. +if test ${with_project_version_int+y} +then : + withval=$with_project_version_int; ProjectVersionInt="$withval" +else case e in #( + e) ProjectVersionInt="913" ;; +esac +fi + + +# Check whether --with-project-version-munged was given. +if test ${with_project_version_munged+y} +then : + withval=$with_project_version_munged; ProjectVersionMunged="$withval" +else case e in #( + e) ProjectVersionMunged="9.13" ;; +esac +fi + + +# Check whether --with-project-version-for-lib was given. +if test ${with_project_version_for_lib+y} +then : + withval=$with_project_version_for_lib; ProjectVersionForLib="$withval" +else case e in #( + e) ProjectVersionForLib="9.1300" ;; +esac +fi + + +# Check whether --with-project-patch-level was given. +if test ${with_project_patch_level+y} +then : + withval=$with_project_patch_level; ProjectPatchLevel="$withval" +else case e in #( + e) ProjectPatchLevel="0" ;; +esac +fi + + +# Check whether --with-project-patch-level1 was given. +if test ${with_project_patch_level1+y} +then : + withval=$with_project_patch_level1; ProjectPatchLevel1="$withval" +else case e in #( + e) ProjectPatchLevel1="0" ;; +esac +fi + + +# Check whether --with-project-patch-level2 was given. +if test ${with_project_patch_level2+y} +then : + withval=$with_project_patch_level2; ProjectPatchLevel2="$withval" +else case e in #( + e) ProjectPatchLevel2="0" ;; +esac +fi + + +# Export these variables for substitution by AC_SUBST + + + + + + + + +# For ghc-boot-th.cabal.in +Suffix="" + +SourceRoot="." + + +# --- Define Programs --- +# We don't need to check for CC, MAKE_SET, and others for now, we only want substitution. +# AC_PROG_CC +# AC_PROG_MAKE_SET # To ensure 'set' works in Makefiles for undefined variables +for ac_prog in python3 python python2 +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PYTHON+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$PYTHON"; then + ac_cv_prog_PYTHON="$PYTHON" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_PYTHON="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +PYTHON=$ac_cv_prog_PYTHON +if test -n "$PYTHON"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +printf "%s\n" "$PYTHON" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$PYTHON" && break +done + +if test "x$PYTHON" = x +then : + as_fn_error $? "Python interpreter not found. Please install Python or set PYTHON environment variable." "$LINENO" 5 +fi + + +# --- Files to generate --- +# config.status will create these files by substituting @VAR@ placeholders. +ac_config_files="$ac_config_files ghc/ghc-bin.cabal:ghc/ghc-bin.cabal.in compiler/ghc.cabal:compiler/ghc.cabal.in libraries/ghc-boot/ghc-boot.cabal:libraries/ghc-boot/ghc-boot.cabal.in libraries/ghc-boot-th/ghc-boot-th.cabal:libraries/ghc-boot-th/ghc-boot-th.cabal.in libraries/ghc-heap/ghc-heap.cabal:libraries/ghc-heap/ghc-heap.cabal.in libraries/template-haskell/template-haskell.cabal:libraries/template-haskell/template-haskell.cabal.in libraries/ghci/ghci.cabal:libraries/ghci/ghci.cabal.in utils/ghc-pkg/ghc-pkg.cabal:utils/ghc-pkg/ghc-pkg.cabal.in utils/ghc-iserv/ghc-iserv.cabal:utils/ghc-iserv/ghc-iserv.cabal.in utils/runghc/runghc.cabal:utils/runghc/runghc.cabal.in libraries/ghc-internal/ghc-internal.cabal:libraries/ghc-internal/ghc-internal.cabal.in libraries/ghc-experimental/ghc-experimental.cabal:libraries/ghc-experimental/ghc-experimental.cabal.in libraries/base/base.cabal:libraries/base/base.cabal.in rts/include/ghcversion.h:rts/include/ghcversion.h.in" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# 'ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* 'ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # 'set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # 'set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[][ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else case e in #( + e) case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac ;; +esac +fi + + + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. +as_nl=' +' +export as_nl +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi + +# The user is always right. +if ${PATH_SEPARATOR+false} :; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as 'sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + printf "%s\n" "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else case e in #( + e) as_fn_append () + { + eval $1=\$$1\$2 + } ;; +esac +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else case e in #( + e) as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } ;; +esac +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated + +# Sed expression to map a string onto a valid variable name. +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by ghc-builder $as_me 0.1.0, which was +generated by GNU Autoconf 2.72. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +'$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to ." + +_ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config='$ac_cs_config_escaped' +ac_cs_version="\\ +ghc-builder config.status 0.1.0 +configured by $0, generated by GNU Autoconf 2.72, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2023 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + printf "%s\n" "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + printf "%s\n" "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + printf "%s\n" "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: '$1' +Try '$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + printf "%s\n" "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "ghc/ghc-bin.cabal") CONFIG_FILES="$CONFIG_FILES ghc/ghc-bin.cabal:ghc/ghc-bin.cabal.in" ;; + "compiler/ghc.cabal") CONFIG_FILES="$CONFIG_FILES compiler/ghc.cabal:compiler/ghc.cabal.in" ;; + "libraries/ghc-boot/ghc-boot.cabal") CONFIG_FILES="$CONFIG_FILES libraries/ghc-boot/ghc-boot.cabal:libraries/ghc-boot/ghc-boot.cabal.in" ;; + "libraries/ghc-boot-th/ghc-boot-th.cabal") CONFIG_FILES="$CONFIG_FILES libraries/ghc-boot-th/ghc-boot-th.cabal:libraries/ghc-boot-th/ghc-boot-th.cabal.in" ;; + "libraries/ghc-heap/ghc-heap.cabal") CONFIG_FILES="$CONFIG_FILES libraries/ghc-heap/ghc-heap.cabal:libraries/ghc-heap/ghc-heap.cabal.in" ;; + "libraries/template-haskell/template-haskell.cabal") CONFIG_FILES="$CONFIG_FILES libraries/template-haskell/template-haskell.cabal:libraries/template-haskell/template-haskell.cabal.in" ;; + "libraries/ghci/ghci.cabal") CONFIG_FILES="$CONFIG_FILES libraries/ghci/ghci.cabal:libraries/ghci/ghci.cabal.in" ;; + "utils/ghc-pkg/ghc-pkg.cabal") CONFIG_FILES="$CONFIG_FILES utils/ghc-pkg/ghc-pkg.cabal:utils/ghc-pkg/ghc-pkg.cabal.in" ;; + "utils/ghc-iserv/ghc-iserv.cabal") CONFIG_FILES="$CONFIG_FILES utils/ghc-iserv/ghc-iserv.cabal:utils/ghc-iserv/ghc-iserv.cabal.in" ;; + "utils/runghc/runghc.cabal") CONFIG_FILES="$CONFIG_FILES utils/runghc/runghc.cabal:utils/runghc/runghc.cabal.in" ;; + "libraries/ghc-internal/ghc-internal.cabal") CONFIG_FILES="$CONFIG_FILES libraries/ghc-internal/ghc-internal.cabal:libraries/ghc-internal/ghc-internal.cabal.in" ;; + "libraries/ghc-experimental/ghc-experimental.cabal") CONFIG_FILES="$CONFIG_FILES libraries/ghc-experimental/ghc-experimental.cabal:libraries/ghc-experimental/ghc-experimental.cabal.in" ;; + "libraries/base/base.cabal") CONFIG_FILES="$CONFIG_FILES libraries/base/base.cabal:libraries/base/base.cabal.in" ;; + "rts/include/ghcversion.h") CONFIG_FILES="$CONFIG_FILES rts/include/ghcversion.h:rts/include/ghcversion.h.in" ;; + + *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to '$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with './config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain ':'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is 'configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`printf "%s\n" "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +printf "%s\n" X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when '$srcdir' = '.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +# After running ./configure, the following command can be used to see configured values: +# ./config.status --config + diff --git a/ghc/GHC/Driver/Session/Mode.hs b/ghc/GHC/Driver/Session/Mode.hs index e2d9c28e935..33850aab89f 100644 --- a/ghc/GHC/Driver/Session/Mode.hs +++ b/ghc/GHC/Driver/Session/Mode.hs @@ -32,12 +32,16 @@ data PreStartupMode | ShowNumVersion -- ghc --numeric-version | ShowSupportedExtensions -- ghc --supported-extensions | ShowOptions Bool {- isInteractive -} -- ghc --show-options + | PrintPrimModule -- ghc --print-prim-module + | PrintPrimWrappersModule -- ghc --print-prim-wrappers-module -showVersionMode, showNumVersionMode, showSupportedExtensionsMode, showOptionsMode :: Mode +showVersionMode, showNumVersionMode, showSupportedExtensionsMode, showOptionsMode, printPrimModule, printPrimWrappersModule :: Mode showVersionMode = mkPreStartupMode ShowVersion showNumVersionMode = mkPreStartupMode ShowNumVersion showSupportedExtensionsMode = mkPreStartupMode ShowSupportedExtensions showOptionsMode = mkPreStartupMode (ShowOptions False) +printPrimModule = mkPreStartupMode PrintPrimModule +printPrimWrappersModule = mkPreStartupMode PrintPrimWrappersModule mkPreStartupMode :: PreStartupMode -> Mode mkPreStartupMode = Left @@ -203,6 +207,8 @@ mode_flags = , defFlag "-numeric-version" (PassFlag (setMode showNumVersionMode)) , defFlag "-info" (PassFlag (setMode showInfoMode)) , defFlag "-show-options" (PassFlag (setMode showOptionsMode)) + , defFlag "-print-prim-module" (PassFlag (setMode printPrimModule)) + , defFlag "-print-prim-wrappers-module" (PassFlag (setMode printPrimWrappersModule)) , defFlag "-supported-languages" (PassFlag (setMode showSupportedExtensionsMode)) , defFlag "-supported-extensions" (PassFlag (setMode showSupportedExtensionsMode)) , defFlag "-show-packages" (PassFlag (setMode showUnitsMode)) diff --git a/ghc/Main.hs b/ghc/Main.hs index e6582de2d5b..53f858df39a 100644 --- a/ghc/Main.hs +++ b/ghc/Main.hs @@ -37,6 +37,8 @@ import GHC.Driver.Config.Diagnostic import GHC.Platform import GHC.Platform.Host +import GHC.Builtin.PrimOps (primOpPrimModule, primOpWrappersModule) + #if defined(HAVE_INTERNAL_INTERPRETER) import GHCi.UI ( interactiveUI, ghciWelcomeMsg, defaultGhciSettings ) #endif @@ -58,6 +60,7 @@ import GHC.Types.PkgQual import GHC.Utils.Error import GHC.Utils.Panic import GHC.Utils.Outputable as Outputable +import GHC.Utils.Misc ( split ) import GHC.Utils.Monad ( liftIO ) import GHC.Utils.Binary ( openBinMem, put_ ) import GHC.Utils.Logger @@ -83,12 +86,14 @@ import GHC.Driver.Session.Units -- Standard Haskell libraries import System.IO +import System.FilePath +import System.Directory import System.Environment import System.Exit import Control.Monad import Control.Monad.Trans.Class import Control.Monad.Trans.Except (throwE, runExceptT) -import Data.List ( isPrefixOf, partition, intercalate ) +import Data.List ( isPrefixOf, isSuffixOf, partition, intercalate ) import Prelude import qualified Data.List.NonEmpty as NE @@ -112,13 +117,50 @@ main = do configureHandleEncoding GHC.defaultErrorHandler defaultFatalMessager defaultFlushOut $ do -- 1. extract the -B flag from the args + prog0 <- getProgName argv0 <- getArgs - let (minusB_args, argv1) = partition ("-B" `isPrefixOf`) argv0 + -- either pass @--target=...@ to select the target, or use a symbolic + -- or (copy of the executable) name that ends with @-ghc@. E.g. + -- x86_64-unknown-linux-ghc would select the x86_64-unknown-linux target. + let (target_args, argv1) = partition ("-target=" `isPrefixOf`) argv0 + mbTarget | not (null target_args) = Just (drop 8 (last target_args)) + | "-ghc" `isSuffixOf` prog0 + , parts <- split '-' prog0 + , length parts > 2 = Just (take (length prog0 - 4) prog0) + | otherwise = Nothing + + + let (minusB_args, argv1') = partition ("-B" `isPrefixOf`) argv1 mbMinusB | null minusB_args = Nothing | otherwise = Just (drop 2 (last minusB_args)) - let argv2 = map (mkGeneralLocated "on the commandline") argv1 + let (list_targets_args, argv1'') = partition (== "-list-targets") argv1' + list_targets = not (null list_targets_args) + + -- find top directory for the given target. Or default to usual topdir. + targettopdir <- Just <$> do + topdir <- findTopDir mbMinusB + let targets_dir = topdir "targets" + -- list targets when asked + when list_targets $ do + putStrLn $ "Installed targets (in " ++ targets_dir ++ "):" + doesDirectoryExist targets_dir >>= \case + True -> do + ds <- listDirectory targets_dir + forM_ ds (\d -> putStrLn $ " - " ++ d) + False -> pure () + exitSuccess + -- otherwise select the appropriate target + case mbTarget of + Nothing -> pure topdir + Just target -> do + let r = targets_dir target "lib" + doesDirectoryExist r >>= \case + True -> pure r + False -> throwGhcException (UsageError $ "Couldn't find specific target `" ++ target ++ "' in `" ++ r ++ "'") + + let argv2 = map (mkGeneralLocated "on the commandline") argv1'' -- 2. Parse the "mode" flags (--make, --interactive etc.) (mode, units, argv3, flagWarnings) <- parseModeFlags argv2 @@ -134,13 +176,15 @@ main = do case mode of Left preStartupMode -> do case preStartupMode of - ShowSupportedExtensions -> showSupportedExtensions mbMinusB + ShowSupportedExtensions -> showSupportedExtensions targettopdir ShowVersion -> showVersion ShowNumVersion -> putStrLn cProjectVersion ShowOptions isInteractive -> showOptions isInteractive + PrintPrimModule -> liftIO $ putStrLn primOpPrimModule + PrintPrimWrappersModule -> liftIO $ putStrLn primOpWrappersModule Right postStartupMode -> -- start our GHC session - GHC.runGhc mbMinusB $ do + GHC.runGhc targettopdir $ do dflags <- GHC.getSessionDynFlags diff --git a/ghc/ghc-bin.cabal.in b/ghc/ghc-bin.cabal.in index 466e5f37ce5..80e1e7f077f 100644 --- a/ghc/ghc-bin.cabal.in +++ b/ghc/ghc-bin.cabal.in @@ -1,3 +1,4 @@ +Cabal-Version: 3.0 -- WARNING: ghc-bin.cabal is automatically generated from ghc-bin.cabal.in by -- ./configure. Make sure you are editing ghc-bin.cabal.in, not ghc-bin.cabal. @@ -15,7 +16,6 @@ Description: to the Glasgow Haskell Compiler. Category: Development Build-Type: Simple -Cabal-Version: >=1.10 Flag internal-interpreter Description: Build with internal interpreter support. @@ -45,6 +45,15 @@ Executable ghc ghc-boot == @ProjectVersionMunged@, ghc == @ProjectVersionMunged@ + if impl(ghc > 9.12) + -- we need to depend on the specific rts we want to link our + -- final GHC against. + -- TODO: add debug flag and extend those extra cases. + if flag(threaded) + Build-Depends: rts:threaded-nodebug + else + Build-Depends: rts:nonthreaded-nodebug + if os(windows) Build-Depends: Win32 >= 2.3 && < 2.15 else diff --git a/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs index 1a0177d8cfc..2a9ce973caa 100644 --- a/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs +++ b/hadrian/src/Hadrian/Haskell/Cabal/Parse.hs @@ -126,8 +126,9 @@ biModules pd = go [ comp | comp@(bi,_,_,_) <- -- -- Put another way, while Hadrian knows these are generated, Cabal -- should just think they are regular source files. +-- TODO: Review if this is necessary extraPreConfigureDeps :: [String] -extraPreConfigureDeps = ["compiler/GHC/CmmToLlvm/Version/Bounds.hs"] +extraPreConfigureDeps = [] -- TODO: Track command line arguments and package configuration flags. -- | Configure a package using the Cabal library by collecting all the command diff --git a/hadrian/src/Rules/Generate.hs b/hadrian/src/Rules/Generate.hs index a8e5a88e8e9..9193b2152e2 100644 --- a/hadrian/src/Rules/Generate.hs +++ b/hadrian/src/Rules/Generate.hs @@ -77,9 +77,6 @@ rtsDependencies = do compilerDependencies :: Expr [FilePath] compilerDependencies = do - let fixed = ("compiler" -/-) <$> - [ "GHC/CmmToLlvm/Version/Bounds.hs" - ] stage <- getStage ghcPath <- expr $ buildPath (vanillaContext stage compiler) let buildSpecific = (ghcPath -/-) <$> @@ -101,10 +98,12 @@ compilerDependencies = do , "primop-vector-uniques.hs-incl" , "primop-docs.hs-incl" , "primop-deprecations.hs-incl" + , "primop-prim-module.hs-incl" + , "primop-wrappers-module.hs-incl" , "GHC/Platform/Constants.hs" , "GHC/Settings/Config.hs" ] - pure $ fixed ++ buildSpecific + pure buildSpecific generatedDependencies :: Expr [FilePath] generatedDependencies = do @@ -388,10 +387,6 @@ templateRules = do , interpolateSetting "LlvmMinVersion" LlvmMinVersion , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion ] - templateRule "compiler/GHC/CmmToLlvm/Version/Bounds.hs" $ mconcat - [ interpolateVar "LlvmMinVersion" $ replaceEq '.' ',' <$> setting LlvmMinVersion - , interpolateVar "LlvmMaxVersion" $ replaceEq '.' ',' <$> setting LlvmMaxVersion - ] bindistRules bindistRules :: Rules () diff --git a/hadrian/src/Rules/Lint.hs b/hadrian/src/Rules/Lint.hs index a8b1660556a..65b703685cd 100644 --- a/hadrian/src/Rules/Lint.hs +++ b/hadrian/src/Rules/Lint.hs @@ -91,8 +91,7 @@ compiler = do let compilerDir = "compiler" let ghcautoconf = stage1RtsInc "ghcautoconf.h" let ghcplatform = stage1RtsInc "ghcplatform.h" - let ghcLlvmVersion = compilerDir "GHC/CmmToLlvm/Version/Bounds.hs" - need $ mconcat [[ghcautoconf, ghcplatform, ghcLlvmVersion], hsIncls stage1Compiler, [machDeps]] + need $ mconcat [[ghcautoconf, ghcplatform], hsIncls stage1Compiler, [machDeps]] let includeDirs = [ stage1RtsInc , compilerDir diff --git a/hadrian/src/Settings/Builders/GenPrimopCode.hs b/hadrian/src/Settings/Builders/GenPrimopCode.hs index d38dcf30385..625fadeba5b 100644 --- a/hadrian/src/Settings/Builders/GenPrimopCode.hs +++ b/hadrian/src/Settings/Builders/GenPrimopCode.hs @@ -24,4 +24,6 @@ genPrimopCodeBuilderArgs = builder GenPrimopCode ? mconcat , output "//primop-vector-tycons.hs-incl" ? arg "--primop-vector-tycons" , output "//primop-docs.hs-incl" ? arg "--wired-in-docs" , output "//primop-deprecations.hs-incl" ? arg "--wired-in-deprecations" + , output "//primop-prim-module.hs-incl" ? arg "--prim-module" + , output "//primop-wrappers-module.hs-incl" ? arg "--wrappers-module" , output "//primop-usage.hs-incl" ? arg "--usage" ] diff --git a/libffi-tarballs b/libffi-tarballs deleted file mode 160000 index ac7fa3132d3..00000000000 --- a/libffi-tarballs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ac7fa3132d382056837cad297ab4c66418febb69 diff --git a/libraries/Cabal b/libraries/Cabal index 703582f80f6..bc52b097aa2 160000 --- a/libraries/Cabal +++ b/libraries/Cabal @@ -1 +1 @@ -Subproject commit 703582f80f6d7f0c914ef4b885affcfc7b7b6ec8 +Subproject commit bc52b097aa2f26aa440fcacdb506843987bba346 diff --git a/libraries/base/tests/IO/T12010/test.T b/libraries/base/tests/IO/T12010/test.T index e33e69036a8..bb926dc72dd 100644 --- a/libraries/base/tests/IO/T12010/test.T +++ b/libraries/base/tests/IO/T12010/test.T @@ -4,5 +4,6 @@ test('T12010', extra_ways(['threaded1']), when(wordsize(32), fragile(16572)), js_broken(22374), + req_target_debug_rts, cmd_prefix('WAY_FLAGS="' + ' '.join(config.way_flags['threaded1']) + '"')], makefile_test, []) diff --git a/libraries/base/tests/IO/all.T b/libraries/base/tests/IO/all.T index 5b28156c96b..992b5dfbac4 100644 --- a/libraries/base/tests/IO/all.T +++ b/libraries/base/tests/IO/all.T @@ -114,7 +114,7 @@ test('countReaders001', js_broken(22261), compile_and_run, ['']) test('concio001', [normal, multi_cpu_race], makefile_test, ['test.concio001']) -test('concio001.thr', [extra_files(['concio001.hs']), multi_cpu_race], +test('concio001.thr', [extra_files(['concio001.hs']), multi_cpu_race, req_target_threaded_rts], makefile_test, ['test.concio001.thr']) test('T2122', [], compile_and_run, ['']) diff --git a/libraries/base/tests/perf/encodingAllocations.hs b/libraries/base/tests/perf/encodingAllocations.hs index 58b31b08533..1389a8ffad7 100755 --- a/libraries/base/tests/perf/encodingAllocations.hs +++ b/libraries/base/tests/perf/encodingAllocations.hs @@ -13,7 +13,11 @@ import Distribution.Simple.Utils main :: IO () -main = withTempFile "encodingAllocations.tmp" (loop 1000000) +main = withTempFile +#if !MIN_VERSION_Cabal(3,15,0) + "." +#endif + "encodingAllocations.tmp" (const $ loop 1000000) loop :: Int -> FilePath -> Handle -> IO () loop 0 !_ !_ = pure () diff --git a/libraries/ghc-boot/Setup.hs b/libraries/ghc-boot/Setup.hs index 0995ee3f8ff..715b7e55359 100644 --- a/libraries/ghc-boot/Setup.hs +++ b/libraries/ghc-boot/Setup.hs @@ -1,6 +1,6 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE LambdaCase #-} -{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE CPP #-} module Main where import Distribution.Simple @@ -10,6 +10,9 @@ 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 @@ -31,13 +34,19 @@ main = defaultMainWithHooks ghcHooks 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 <$> pkgDescrFile + let Just compilerRoot = (takeDirectory . fromSymPath) <$> pkgDescrFile let platformHostFile = "GHC/Platform/Host.hs" - platformHostPath = autogenPackageModulesDir lbi platformHostFile + platformHostPath = fromSymPath (autogenPackageModulesDir lbi) platformHostFile ghcVersionFile = "GHC/Version.hs" - ghcVersionPath = autogenPackageModulesDir lbi ghcVersionFile + ghcVersionPath = fromSymPath (autogenPackageModulesDir lbi) ghcVersionFile -- Get compiler settings settings <- lookupEnv "HADRIAN_SETTINGS" >>= \case diff --git a/libraries/ghc-boot/ghc-boot.cabal.in b/libraries/ghc-boot/ghc-boot.cabal.in index d61f6809fef..992c7834739 100644 --- a/libraries/ghc-boot/ghc-boot.cabal.in +++ b/libraries/ghc-boot/ghc-boot.cabal.in @@ -28,7 +28,7 @@ build-type: Custom extra-source-files: changelog.md custom-setup - setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.14, directory, filepath + setup-depends: base >= 3 && < 5, Cabal >= 1.6 && <3.16, directory, filepath source-repository head type: git diff --git a/libraries/ghc-compact/tests/all.T b/libraries/ghc-compact/tests/all.T index 9a666161ff9..2bb90c4dbf1 100644 --- a/libraries/ghc-compact/tests/all.T +++ b/libraries/ghc-compact/tests/all.T @@ -1,5 +1,5 @@ setTestOpts( - [extra_ways(['sanity', 'compacting_gc']), + [extra_ways(['compacting_gc'] + (['sanity'] if debug_rts() else [])), js_skip # compact API not supported by the JS backend ]) diff --git a/libraries/ghc-heap/tests/all.T b/libraries/ghc-heap/tests/all.T index 5722182d5f6..5b8b755ae81 100644 --- a/libraries/ghc-heap/tests/all.T +++ b/libraries/ghc-heap/tests/all.T @@ -94,7 +94,8 @@ test('stack_misc_closures', [ extra_files(['stack_misc_closures_c.c', 'stack_misc_closures_prim.cmm', 'TestUtils.hs']), ignore_stdout, - ignore_stderr + ignore_stderr, + req_target_debug_rts # Debug RTS to use checkSTACK() ], multi_compile_and_run, ['stack_misc_closures', diff --git a/libraries/ghc-internal/configure.ac b/libraries/ghc-internal/configure.ac index b87652f61d2..80f60072a42 100644 --- a/libraries/ghc-internal/configure.ac +++ b/libraries/ghc-internal/configure.ac @@ -6,6 +6,8 @@ AC_CONFIG_SRCDIR([include/HsBase.h]) AC_CONFIG_HEADERS([include/HsBaseConfig.h include/EventConfig.h]) +CPPFLAGS="-I$srcdir $CPPFLAGS" + AC_PROG_CC dnl make extensions visible to allow feature-tests to detect them later on AC_USE_SYSTEM_EXTENSIONS @@ -402,10 +404,32 @@ AS_IF([test "x$with_libcharset" != xno], fi -dnl Calling AC_CHECK_TYPE(T) makes AC_CHECK_SIZEOF(T) abort on failure -dnl instead of considering sizeof(T) as 0. -AC_CHECK_TYPE([struct MD5Context], [], [AC_MSG_ERROR([internal error])], [#include "include/md5.h"]) AC_CHECK_SIZEOF([struct MD5Context], [], [#include "include/md5.h"]) +AS_IF([test "$ac_cv_sizeof_struct_MD5Context" -eq 0],[ + AC_MSG_ERROR([cannot determine sizeof(struct MD5Context)]) +]) + +AC_ARG_VAR([GHC], [Path to the ghc program]) +AC_PATH_PROG([GHC], ghc) +if test -z "$GHC"; then + AC_MSG_ERROR([Cannot find ghc]) +fi + +AC_MSG_CHECKING([for GHC/Internal/Prim.hs]) +if mkdir -p GHC/Internal && $GHC --print-prim-module > GHC/Internal/Prim.hs; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $GHC --print-prim-module > GHC/Internal/Prim.hs]) +fi + +AC_MSG_CHECKING([for GHC/Internal/PrimopWrappers.hs]) +if mkdir -p GHC/Internal && $GHC --print-prim-wrappers-module > GHC/Internal/PrimopWrappers.hs; then + AC_MSG_RESULT([created]) +else + AC_MSG_RESULT([failed to create]) + AC_MSG_ERROR([Failed to run $GHC --print-prim-wrappers-module > GHC/Internal/PrimopWrappers.hs]) +fi AC_SUBST(EXTRA_LIBS) AC_CONFIG_FILES([ghc-internal.buildinfo include/HsIntegerGmp.h]) diff --git a/libraries/ghc-internal/ghc-internal.cabal.in b/libraries/ghc-internal/ghc-internal.cabal.in index 5ee7770a454..403a969aca5 100644 --- a/libraries/ghc-internal/ghc-internal.cabal.in +++ b/libraries/ghc-internal/ghc-internal.cabal.in @@ -39,7 +39,6 @@ extra-source-files: include/HsBaseConfig.h.in include/ieee-flpt.h include/md5.h - include/fs.h include/winio_structs.h include/WordSize.h include/HsIntegerGmp.h.in @@ -119,7 +118,8 @@ Library Unsafe build-depends: - rts == 1.0.* + rts == 1.0.*, + rts-fs == 1.0.* exposed-modules: GHC.Internal.ClosureTypes @@ -343,9 +343,11 @@ Library GHC.Internal.Tuple GHC.Internal.Types - autogen-modules: - GHC.Internal.Prim - GHC.Internal.PrimopWrappers + -- Cabal expects autogen modules to be some specific directories, not in the + -- source dirs... + -- autogen-modules: + -- GHC.Internal.Prim + -- GHC.Internal.PrimopWrappers other-modules: GHC.Internal.Data.Typeable.Internal @@ -432,7 +434,6 @@ Library cbits/md5.c cbits/primFloat.c cbits/sysconf.c - cbits/fs.c cbits/strerror.c cbits/atomic.c cbits/bswap.c diff --git a/libraries/ghc-internal/include/HsBase.h b/libraries/ghc-internal/include/HsBase.h index 0e159237e39..f7155b72cf0 100644 --- a/libraries/ghc-internal/include/HsBase.h +++ b/libraries/ghc-internal/include/HsBase.h @@ -515,16 +515,16 @@ extern void __hscore_set_saved_termios(int fd, void* ts); #if defined(_WIN32) /* Defined in fs.c. */ -extern int __hs_swopen (const wchar_t* filename, int oflag, int shflag, +extern int __rts_swopen (const wchar_t* filename, int oflag, int shflag, int pmode); INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) { int result = -1; if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND)) - result = __hs_swopen(file,how | _O_NOINHERIT,_SH_DENYNO,mode); + result = __rts_swopen(file,how | _O_NOINHERIT,_SH_DENYNO,mode); // _O_NOINHERIT: see #2650 else - result = __hs_swopen(file,how | _O_NOINHERIT,_SH_DENYNO,mode); + result = __rts_swopen(file,how | _O_NOINHERIT,_SH_DENYNO,mode); // _O_NOINHERIT: see #2650 /* This call is very important, otherwise the I/O system will not propagate diff --git a/libraries/ghc-prim/ghc-prim.cabal b/libraries/ghc-prim/ghc-prim.cabal index 8cb39c0b932..add096d36d0 100644 --- a/libraries/ghc-prim/ghc-prim.cabal +++ b/libraries/ghc-prim/ghc-prim.cabal @@ -8,6 +8,9 @@ category: GHC maintainer: libraries@haskell.org bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new synopsis: GHC primitives +-- We can't use Custom build-type with boot packages: building Setup.hs with +-- cabal-install requires that base, Cabal, directory, process, filepath, +-- containers, etc. libraries be available, but they aren't when we bootstrap. build-type: Simple description: This package used to contain the primitive types and operations supplied by diff --git a/libraries/system-cxx-std-lib/system-cxx-std-lib.cabal b/libraries/system-cxx-std-lib/system-cxx-std-lib.cabal new file mode 100644 index 00000000000..72f86a4d0b6 --- /dev/null +++ b/libraries/system-cxx-std-lib/system-cxx-std-lib.cabal @@ -0,0 +1,21 @@ +cabal-version: 2.0 +name: system-cxx-std-lib +version: 1.0 +license: BSD-3-Clause +synopsis: A placeholder for the system's C++ standard library implementation. +description: Building against C++ libraries requires that the C++ standard + library be included when linking. Typically when compiling a C++ + project this is done automatically by the C++ compiler. However, + as GHC uses the C compiler for linking, users needing the C++ + standard library must declare this dependency explicitly. + . + This "virtual" package can be used to depend upon the host system's + C++ standard library implementation in a platform agnostic manner. +category: System +build-type: Simple + +library + -- empty library: this is just a placeholder for GHC to use to inject C++ + -- standard libraries when linking with the C toolchain, or to directly use + -- the C++ toolchain to link. + diff --git a/packages b/packages index 4f02d0133c0..d6bb0cd77e1 100644 --- a/packages +++ b/packages @@ -37,7 +37,6 @@ # localpath tag remotepath upstreamurl # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ghc-tarballs windows ghc-tarballs.git - -libffi-tarballs - - - utils/hsc2hs - - ssh://git@github.com/haskell/hsc2hs.git libraries/array - - - libraries/binary - - https://github.com/kolmodin/binary.git diff --git a/rts/config.guess b/rts/config.guess new file mode 100755 index 00000000000..f6d217a49f8 --- /dev/null +++ b/rts/config.guess @@ -0,0 +1,1812 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2024 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2024-01-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to . + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system '$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2024 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Just in case it came from the environment. +GUESS= + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case $UNAME_SYSTEM in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + #endif + EOF + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + GUESS=$machine-${os}${release}${abi-} + ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; + *:ekkoBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; + *:SolidBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; + macppc:MirBSD:*:*) + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; + *:MirBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; + alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; + Amiga*:UNIX_System_V:4.0:*) + GUESS=m68k-unknown-sysv4 + ;; + *:[Aa]miga[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; + *:[Mm]orph[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-morphos + ;; + *:OS/390:*:*) + GUESS=i370-ibm-openedition + ;; + *:z/VM:*:*) + GUESS=s390-ibm-zvmoe + ;; + *:OS400:*:*) + GUESS=powerpc-ibm-os400 + ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + GUESS=arm-unknown-riscos + ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + GUESS=hppa1.1-hitachi-hiuxmpp + ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; + NILE*:*:*:dcosx) + GUESS=pyramid-pyramid-svr4 + ;; + DRS?6000:unix:4.0:6*) + GUESS=sparc-icl-nx6 + ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; + s390x:SunOS:*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; + sun4H:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; + sun4*:SunOS:*:*) + case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like '4.1.3-JL'. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; + sun3*:SunOS:*:*) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in + sun3) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) + GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac + ;; + aushp:SunOS:*:*) + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; + m68k:machten:*:*) + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; + powerpc:machten:*:*) + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; + RISC*:Mach:*:*) + GUESS=mips-dec-mach_bsd4.3 + ;; + RISC*:ULTRIX:*:*) + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; + VAX*:ULTRIX*:*:*) + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; + Motorola:PowerMAX_OS:*:*) + GUESS=powerpc-motorola-powermax + ;; + Motorola:*:4.3:PL8-*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:Power_UNIX:*:*) + GUESS=powerpc-harris-powerunix + ;; + m88k:CX/UX:7*:*) + GUESS=m88k-harris-cxux7 + ;; + m88k:*:4*:R4*) + GUESS=m88k-motorola-sysv4 + ;; + m88k:*:3*:R3*) + GUESS=m88k-motorola-sysv3 + ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + GUESS=m88k-dg-dgux$UNAME_RELEASE + else + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else + GUESS=i586-dg-dgux$UNAME_RELEASE + fi + ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + GUESS=m88k-dolphin-sysv3 + ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + GUESS=m88k-motorola-sysv3 + ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + GUESS=m88k-tektronix-sysv3 + ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + GUESS=m68k-tektronix-bsd + ;; + *:IRIX*:*:*) + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + GUESS=i386-ibm-aix + ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + GUESS=$SYSTEM_NAME + else + GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + GUESS=rs6000-ibm-aix3.2.4 + else + GUESS=rs6000-ibm-aix3.2 + fi + ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; + *:AIX:*:*) + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + GUESS=rs6000-bull-bosx + ;; + DPX/2?00:B.O.S.:*:*) + GUESS=m68k-bull-sysv3 + ;; + 9000/[34]??:4.3bsd:1.*:*) + GUESS=m68k-hp-bsd + ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + GUESS=m68k-hp-bsd4.4 + ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; + 9000/8??:4.3bsd:*:*) + GUESS=hppa1.0-hp-bsd + ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; + hp8??:OSF1:*:*) + GUESS=hppa1.0-hp-osf + ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk + else + GUESS=$UNAME_MACHINE-unknown-osf1 + fi + ;; + parisc*:Lites*:*:*) + GUESS=hppa1.1-hp-lites + ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + GUESS=c1-convex-bsd + ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + GUESS=c34-convex-bsd + ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + GUESS=c38-convex-bsd + ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + GUESS=c4-convex-bsd + ;; + CRAY*Y-MP:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; + CRAY*T3E:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; + CRAY*SV1:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; + *:UNICOS/mp:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; + sparc*:BSD/OS:*:*) + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; + *:BSD/OS:*:*) + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; + i*:CYGWIN*:*) + GUESS=$UNAME_MACHINE-pc-cygwin + ;; + *:MINGW64*:*) + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; + *:MINGW*:*) + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; + i*:PW*:*) + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + GUESS=i586-pc-interix$UNAME_RELEASE + ;; + authenticamd | genuineintel | EM64T) + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; + IA64) + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; + esac ;; + i*:UWIN*:*) + GUESS=$UNAME_MACHINE-pc-uwin + ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + GUESS=x86_64-pc-cygwin + ;; + prep*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; + *:GNU:*:*) + # the GNU system + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI + ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi + ;; + avr32*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + cris:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + crisv32:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + frv:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + hexagon:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:Linux:*:*) + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; + ia64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m32r*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m68*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + padre:Linux:*:*) + GUESS=sparc-unknown-linux-$LIBC + ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + GUESS=hppa64-unknown-linux-$LIBC + ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; + esac + ;; + ppc64:Linux:*:*) + GUESS=powerpc64-unknown-linux-$LIBC + ;; + ppc:Linux:*:*) + GUESS=powerpc-unknown-linux-$LIBC + ;; + ppc64le:Linux:*:*) + GUESS=powerpc64le-unknown-linux-$LIBC + ;; + ppcle:Linux:*:*) + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + s390:Linux:*:* | s390x:Linux:*:*) + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; + sh64*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sh*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + tile*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + vax:Linux:*:*) + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; + x86_64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac + fi + GUESS=$CPU-pc-linux-$LIBCABI + ;; + xtensa*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + GUESS=i386-sequent-sysv4 + ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; + i*86:OS/2:*:*) + # If we were able to find 'uname', then EMX Unix compatibility + # is probably installed. + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; + i*86:XTS-300:*:STOP) + GUESS=$UNAME_MACHINE-unknown-stop + ;; + i*86:atheos:*:*) + GUESS=$UNAME_MACHINE-unknown-atheos + ;; + i*86:syllable:*:*) + GUESS=$UNAME_MACHINE-pc-syllable + ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; + i*86:*DOS:*:*) + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi + ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv32 + fi + ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + GUESS=i586-pc-msdosdjgpp + ;; + Intel:Mach:3*:*) + GUESS=i386-pc-mach3 + ;; + paragon:*:*:*) + GUESS=i860-intel-osf1 + ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi + ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + GUESS=m68010-convergent-sysv + ;; + mc68k:UNIX:SYSTEM5:3.51m) + GUESS=m68k-convergent-sysv + ;; + M680?0:D-NIX:5.3:*) + GUESS=m68k-diab-dnix + ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; + mc68030:UNIX_System_V:4.*:*) + GUESS=m68k-atari-sysv4 + ;; + TSUNAMI:LynxOS:2.*:*) + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; + rs6000:LynxOS:2.*:*) + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; + SM[BE]S:UNIX_SV:*:*) + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; + RM*:ReliantUNIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + RM*:SINIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 + else + GUESS=ns32k-sni-sysv + fi + ;; + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort + # says + GUESS=i586-unisys-sysv4 + ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + GUESS=hppa1.1-stratus-sysv4 + ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + GUESS=i860-stratus-sysv4 + ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=$UNAME_MACHINE-stratus-vos + ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=hppa1.1-stratus-vos + ;; + mc68*:A/UX:*:*) + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; + news*:NEWS-OS:6*:*) + GUESS=mips-sony-newsos6 + ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE + else + GUESS=mips-unknown-sysv$UNAME_RELEASE + fi + ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + GUESS=powerpc-be-beos + ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + GUESS=powerpc-apple-beos + ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + GUESS=i586-pc-beos + ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + GUESS=i586-pc-haiku + ;; + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku + ;; + SX-4:SUPER-UX:*:*) + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; + SX-5:SUPER-UX:*:*) + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; + SX-6:SUPER-UX:*:*) + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; + SX-7:SUPER-UX:*:*) + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; + SX-8:SUPER-UX:*:*) + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; + SX-8R:SUPER-UX:*:*) + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; + Power*:Rhapsody:*:*) + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; + *:Rhapsody:*:*) + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; + *:QNX:*:4*) + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; + NSE-*:NONSTOP_KERNEL:*:*) + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; + *:NonStop-UX:*:*) + GUESS=mips-compaq-nonstopux + ;; + BS2000:POSIX*:*:*) + GUESS=bs2000-siemens-sysv + ;; + DS/*:UNIX_System_V:*:*) + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype + fi + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; + *:TOPS-10:*:*) + GUESS=pdp10-unknown-tops10 + ;; + *:TENEX:*:*) + GUESS=pdp10-unknown-tenex + ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + GUESS=pdp10-dec-tops20 + ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + GUESS=pdp10-xkl-tops20 + ;; + *:TOPS-20:*:*) + GUESS=pdp10-unknown-tops20 + ;; + *:ITS:*:*) + GUESS=pdp10-unknown-its + ;; + SEI:*:*:SEIUX) + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; + *:DragonFly:*:*) + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) + GUESS=i386-pc-xenix + ;; + i*86:skyos:*:*) + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; + i*86:rdos:*:*) + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; + x86_64:VMkernel:*:*) + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/rts/config.sub b/rts/config.sub new file mode 100755 index 00000000000..2c6a07ab3c3 --- /dev/null +++ b/rts/config.sub @@ -0,0 +1,1971 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2024 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2024-01-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2024 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x"$basic_os" != x +then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +obj= +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 + fi + ;; + *) + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) + ;; + windows*-msvc*-) + ;; + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 + ;; + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 + ;; + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) + ;; + *-eabi*- | *-gnueabi*-) + ;; + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) + # Blank kernel with real OS is always fine. + ;; + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py index 01d4e9c1e4a..7de90d8e60f 100644 --- a/testsuite/driver/testlib.py +++ b/testsuite/driver/testlib.py @@ -362,6 +362,20 @@ def req_ghc_smp( name, opts ): if not config.ghc_has_smp: opts.skip = True +def req_target_debug_rts( name, opts ): + """ + Mark a test as requiring the debug rts (e.g. compile with -debug or -ticky) + """ + if not config.debug_rts: + opts.skip = True + +def req_target_threaded_rts( name, opts ): + # FIXME: this is probably wrong: we should have a different flag for the + # compiler's rts and the target rts... + if not config.ghc_with_threaded_rts: + opts.skip = True + + def req_target_smp( name, opts ): """ Mark a test as requiring smp when run on the target. If the target does @@ -1376,9 +1390,13 @@ def normalizer(s: str) -> str: def normalise_version_( *pkgs ): def normalise_version__( str ): + # First strip the ghc-version_ prefix if present at the start of package names + # Use word boundary to ensure we only match actual package name prefixes + str_no_ghc_prefix = re.sub(r'\bghc-[0-9.]+_([a-zA-Z])', r'\1', str) # (name)(-version)(-hash)(-components) - return re.sub('(' + '|'.join(map(re.escape,pkgs)) + r')-[0-9.]+(-[0-9a-zA-Z+]+)?(-[0-9a-zA-Z]+)?', - r'\1--', str) + ver_hash = re.sub('(' + '|'.join(map(re.escape,pkgs)) + r')-[0-9.]+(-[0-9a-zA-Z+]+)?(-[0-9a-zA-Z+]+)?', + r'\1--', str_no_ghc_prefix) + return re.sub(r'\bghc_([a-zA-Z-]+--)', r'\1', ver_hash) return normalise_version__ def normalise_version( *pkgs ): @@ -2853,7 +2871,7 @@ def is_match(pat, actual): # Note [Null device handling] # ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# On windows the null device is 'nul' instead of '/dev/null'. +# On Windows the null device is 'nul' instead of '/dev/null'. # This can in principle be easily solved by using os.devnull. # Not doing so causes issues when python tries to read/write/open # the null device. @@ -2882,6 +2900,11 @@ def normalise_callstacks(s: str) -> str: def repl(matches): location = matches.group(1) location = normalise_slashes_(location) + # backtrace paths contain the package path when building with Hadrian + location = re.sub(r'libraries/\w+(-\w+)*/', '', location) + location = re.sub(r'utils/\w+(-\w+)*/', '', location) + location = re.sub(r'compiler/', '', location) + location = re.sub(r'\./', '', location) return ', called at {0}:: in :'.format(location) # Ignore line number differences in call stacks (#10834). s = re.sub(callSite_re, repl, s) @@ -2988,8 +3011,6 @@ def normalise_errmsg(s: str) -> str: s = re.sub('.*strip: changes being made to the file will invalidate the code signature in.*\n','',s) # clang may warn about unused argument when used as assembler s = re.sub('.*warning: argument unused during compilation:.*\n', '', s) - # Emscripten displays cache info and old emcc doesn't support EMCC_LOGGING=0 - s = re.sub('cache:INFO: .*\n', '', s) return s @@ -3110,7 +3131,7 @@ def normalise_output( s: str ) -> str: def normalise_asm( s: str ) -> str: lines = s.split('\n') - # Only keep insuctions and labels not starting with a dot. + # Only keep instructions and labels not starting with a dot. metadata = re.compile('^[ \t]*\\..*$') out = [] for line in lines: diff --git a/testsuite/ghc-config/ghc-config.hs b/testsuite/ghc-config/ghc-config.hs index 4d76b6eaca8..6bd306f0770 100644 --- a/testsuite/ghc-config/ghc-config.hs +++ b/testsuite/ghc-config/ghc-config.hs @@ -10,6 +10,10 @@ main = do info <- readProcess ghc ["+RTS", "--info"] "" let fields = read info :: [(String,String)] getGhcFieldOrFail fields "HostOS" "Host OS" + getGhcFieldOrFail fields "WORDSIZE" "Word size" + getGhcFieldOrFail fields "TARGETPLATFORM" "Host platform" + getGhcFieldOrFail fields "TargetOS_CPP" "Host OS" + getGhcFieldOrFail fields "TargetARCH_CPP" "Host architecture" getGhcFieldOrFail fields "RTSWay" "RTS way" -- support for old GHCs (pre 9.13): infer target platform by querying the rts... diff --git a/testsuite/mk/test.mk b/testsuite/mk/test.mk index 0d8899fe51b..9fb28a05ad8 100644 --- a/testsuite/mk/test.mk +++ b/testsuite/mk/test.mk @@ -124,6 +124,13 @@ else RUNTEST_OPTS += -e ghc_with_dynamic_rts=False endif +ifeq "$(filter thr, $(GhcRTSWays))" "debug" +RUNTEST_OPTS += -e config.debug_rts=True +else +RUNTEST_OPTS += -e config.debug_rts=False +endif + + ifeq "$(GhcWithInterpreter)" "NO" RUNTEST_OPTS += -e config.have_interp=False else ifeq "$(GhcStage)" "1" diff --git a/testsuite/tests/codeGen/should_run/T25374/all.T b/testsuite/tests/codeGen/should_run/T25374/all.T index 1e4c3e9860b..0e02dc0d263 100644 --- a/testsuite/tests/codeGen/should_run/T25374/all.T +++ b/testsuite/tests/codeGen/should_run/T25374/all.T @@ -1,3 +1,3 @@ # This shouldn't crash the disassembler -test('T25374', [extra_hc_opts('+RTS -Di -RTS'), ignore_stderr, unless(debug_rts(), skip)], ghci_script, ['']) +test('T25374', [extra_hc_opts('+RTS -Di -RTS'), ignore_stderr, req_target_debug_rts], ghci_script, ['']) diff --git a/testsuite/tests/driver/T20604/T20604.stdout b/testsuite/tests/driver/T20604/T20604.stdout index 45b3c357c37..00a3b5a0773 100644 --- a/testsuite/tests/driver/T20604/T20604.stdout +++ b/testsuite/tests/driver/T20604/T20604.stdout @@ -1,3 +1,4 @@ A1 A -addDependentFile "/home/hsyl20/projects/ghc/merge-ghc-prim/_build/stage1/lib/../lib/x86_64-linux-ghc-9.13.20241220/libHSghc-internal-9.1300.0-inplace-ghc9.13.20241220.so" b035bf4e19d2537a0af5c8861760eaf1 +HSrts-fs- +HSghc-internal- diff --git a/testsuite/tests/driver/T21097b/Makefile b/testsuite/tests/driver/T21097b/Makefile index 6455817a300..bba4b552848 100644 --- a/testsuite/tests/driver/T21097b/Makefile +++ b/testsuite/tests/driver/T21097b/Makefile @@ -4,4 +4,4 @@ include $(TOP)/mk/test.mk T21097b: '$(GHC_PKG)' recache --package-db pkgdb - '$(TEST_HC)' -no-global-package-db -no-user-package-db -package-db pkgdb -v0 Test.hs -ddump-mod-map + '$(TEST_HC)' -no-global-package-db -no-user-package-db -package-db pkgdb -v0 Test.hs -no-rts -ddump-mod-map diff --git a/testsuite/tests/driver/all.T b/testsuite/tests/driver/all.T index 611b2379770..70ed1257ced 100644 --- a/testsuite/tests/driver/all.T +++ b/testsuite/tests/driver/all.T @@ -277,7 +277,7 @@ test('T12971', [when(opsys('mingw32'), fragile(17945)), ignore_stdout], makefile test('json_dump', normal, compile_fail, ['-ddump-json']) test('json', normalise_version('ghc'), compile_fail, ['-fdiagnostics-as-json']) test('json_warn', normalise_version('ghc'), compile, ['-fdiagnostics-as-json -Wunused-matches -Wx-partial']) -test('json2', normalise_version('ghc-internal', 'base','ghc-prim'), compile, ['-ddump-types -ddump-json -Wno-unsupported-llvm-version']) +test('json2', normalise_version('ghc-internal', 'base','ghc-prim'), compile, ['-ddump-types -ddump-json']) test('T16167', [normalise_version('ghc'),req_interp,exit_code(1)], run_command, ['{compiler} -x hs -e ":set prog T16167.hs" -ddump-json T16167.hs']) test('T13604', [], makefile_test, []) @@ -330,5 +330,5 @@ test('T23944', [unless(have_dynamic(), skip), extra_files(['T23944A.hs'])], mult test('T24286', [cxx_src, unless(have_profiling(), skip), extra_files(['T24286.cpp'])], compile, ['-prof -no-hs-main']) test('T24839', [unless(arch('x86_64') or arch('aarch64'), skip), extra_files(["t24839_sub.S"])], compile_and_run, ['t24839_sub.S']) test('t25150', [extra_files(["t25150"])], multimod_compile, ['Main.hs', '-v0 -working-dir t25150/dir a.c']) -test('T25382', normal, makefile_test, []) +test('T25382', expect_broken(28), makefile_test, []) test('T26018', req_c, makefile_test, []) diff --git a/testsuite/tests/ffi/should_run/T1288_c.c b/testsuite/tests/ffi/should_run/T1288_c.c index 2fe90a989b5..ac5f41314b9 100644 --- a/testsuite/tests/ffi/should_run/T1288_c.c +++ b/testsuite/tests/ffi/should_run/T1288_c.c @@ -3,4 +3,5 @@ void test(int arg) { printf("The argument passed was %i\n", arg ); + fflush(NULL); } diff --git a/testsuite/tests/ffi/should_run/T1288_ghci_c.c b/testsuite/tests/ffi/should_run/T1288_ghci_c.c index 2fe90a989b5..ac5f41314b9 100644 --- a/testsuite/tests/ffi/should_run/T1288_ghci_c.c +++ b/testsuite/tests/ffi/should_run/T1288_ghci_c.c @@ -3,4 +3,5 @@ void test(int arg) { printf("The argument passed was %i\n", arg ); + fflush(NULL); } diff --git a/testsuite/tests/ffi/should_run/T2276_c.c b/testsuite/tests/ffi/should_run/T2276_c.c index 2fe90a989b5..ac5f41314b9 100644 --- a/testsuite/tests/ffi/should_run/T2276_c.c +++ b/testsuite/tests/ffi/should_run/T2276_c.c @@ -3,4 +3,5 @@ void test(int arg) { printf("The argument passed was %i\n", arg ); + fflush(NULL); } diff --git a/testsuite/tests/ffi/should_run/T2276_ghci_c.c b/testsuite/tests/ffi/should_run/T2276_ghci_c.c index 2fe90a989b5..ac5f41314b9 100644 --- a/testsuite/tests/ffi/should_run/T2276_ghci_c.c +++ b/testsuite/tests/ffi/should_run/T2276_ghci_c.c @@ -3,4 +3,5 @@ void test(int arg) { printf("The argument passed was %i\n", arg ); + fflush(NULL); } diff --git a/testsuite/tests/ghci/linking/all.T b/testsuite/tests/ghci/linking/all.T index a2b45e0e09f..df46765d9af 100644 --- a/testsuite/tests/ghci/linking/all.T +++ b/testsuite/tests/ghci/linking/all.T @@ -32,8 +32,7 @@ test('ghcilink005', when(unregisterised(), fragile(16085)), unless(doing_ghci, skip), req_dynamic_lib_support, - req_interp, - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + req_interp], makefile_test, ['ghcilink005']) test('ghcilink006', diff --git a/testsuite/tests/ghci/linking/dyn/all.T b/testsuite/tests/ghci/linking/dyn/all.T index b215f6b7202..5d834099deb 100644 --- a/testsuite/tests/ghci/linking/dyn/all.T +++ b/testsuite/tests/ghci/linking/dyn/all.T @@ -3,7 +3,6 @@ setTestOpts(req_dynamic_lib_support) test('load_short_name', [ extra_files(['A.c']) , unless(doing_ghci, skip) , req_c - , when(opsys('linux') and not ghc_dynamic(), expect_broken(20706)) ], makefile_test, ['load_short_name']) @@ -12,8 +11,7 @@ test('T1407', unless(doing_ghci, skip), pre_cmd('$MAKE -s --no-print-directory compile_libT1407'), extra_hc_opts('-L"$PWD/T1407dir"'), - js_broken(22359), - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + js_broken(22359)], makefile_test, []) test('T3242', diff --git a/testsuite/tests/ghci/prog001/prog001.T b/testsuite/tests/ghci/prog001/prog001.T index f00b0b6a986..519ee2e3821 100644 --- a/testsuite/tests/ghci/prog001/prog001.T +++ b/testsuite/tests/ghci/prog001/prog001.T @@ -3,6 +3,5 @@ test('prog001', when(arch('arm'), fragile(17555)), cmd_prefix('ghciWayFlags=' + config.ghci_way_flags), req_interp, - unless(opsys('mingw32') or not config.have_RTS_linker, extra_ways(['ghci-ext'])), - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + unless(opsys('mingw32') or not config.have_RTS_linker, extra_ways(['ghci-ext']))], ghci_script, ['prog001.script']) diff --git a/testsuite/tests/ghci/prog002/prog002.T b/testsuite/tests/ghci/prog002/prog002.T index 83f8d0d92e6..3e25bb455b0 100644 --- a/testsuite/tests/ghci/prog002/prog002.T +++ b/testsuite/tests/ghci/prog002/prog002.T @@ -1,4 +1,3 @@ test('prog002', [extra_files(['../shell.hs', 'A1.hs', 'A2.hs', 'B.hs', 'C.hs', 'D.hs']), - cmd_prefix('ghciWayFlags=' + config.ghci_way_flags), - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + cmd_prefix('ghciWayFlags=' + config.ghci_way_flags)], ghci_script, ['prog002.script']) diff --git a/testsuite/tests/ghci/prog010/all.T b/testsuite/tests/ghci/prog010/all.T index 103ff833819..d30de29400a 100644 --- a/testsuite/tests/ghci/prog010/all.T +++ b/testsuite/tests/ghci/prog010/all.T @@ -1,5 +1,4 @@ test('ghci.prog010', [cmd_prefix('ghciWayFlags=' + config.ghci_way_flags), - extra_files(['../shell.hs', 'A.hs', 'B.hs']), - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + extra_files(['../shell.hs', 'A.hs', 'B.hs'])], ghci_script, ['ghci.prog010.script']) diff --git a/testsuite/tests/ghci/scripts/T7388.hs b/testsuite/tests/ghci/scripts/T7388.hs index 91ca1c7268f..348f2c446fc 100644 --- a/testsuite/tests/ghci/scripts/T7388.hs +++ b/testsuite/tests/ghci/scripts/T7388.hs @@ -2,5 +2,7 @@ module T7388 where import Foreign.C +import Foreign.Ptr foreign import capi "stdio.h printf" printfb :: CString -> CInt -> IO () +foreign import capi "stdio.h fflush" fflushb :: Ptr () -> IO () diff --git a/testsuite/tests/ghci/scripts/T7388.script b/testsuite/tests/ghci/scripts/T7388.script index 7f02d864539..c9477ab761d 100644 --- a/testsuite/tests/ghci/scripts/T7388.script +++ b/testsuite/tests/ghci/scripts/T7388.script @@ -1,2 +1,5 @@ :l T7388 withCString "I am a working CApi FFI call\n" $ \str -> printfb str 0 +-- don't forget to flush, otherwise when ghc is statically linked, the C stdout +-- buffer is never flushed. +fflushb nullPtr diff --git a/testsuite/tests/ghci/scripts/all.T b/testsuite/tests/ghci/scripts/all.T index da1451a29f1..af17d9c6a62 100755 --- a/testsuite/tests/ghci/scripts/all.T +++ b/testsuite/tests/ghci/scripts/all.T @@ -163,8 +163,7 @@ test('T6106', [extra_files(['../shell.hs']), test('T6105', normal, ghci_script, ['T6105.script']) test('T7117', normal, ghci_script, ['T7117.script']) test('ghci058', [extra_files(['../shell.hs']), - cmd_prefix('ghciWayFlags=' + config.ghci_way_flags), - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + cmd_prefix('ghciWayFlags=' + config.ghci_way_flags)], ghci_script, ['ghci058.script']) test('T7587', normal, ghci_script, ['T7587.script']) test('T7688', normal, ghci_script, ['T7688.script']) diff --git a/testsuite/tests/plugins/all.T b/testsuite/tests/plugins/all.T index a7bad499350..40d6439828d 100644 --- a/testsuite/tests/plugins/all.T +++ b/testsuite/tests/plugins/all.T @@ -131,7 +131,7 @@ test('T10294a', pre_cmd('$MAKE -s --no-print-directory -C annotation-plugin package.T10294a TOP={top}')], makefile_test, []) -test('frontend01', [extra_files(['FrontendPlugin.hs']), when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], +test('frontend01', [extra_files(['FrontendPlugin.hs'])], makefile_test, []) test('T11244', @@ -360,9 +360,7 @@ test('plugins-external', test('test-phase-hooks-plugin', [extra_files(['hooks-plugin/']), - pre_cmd('$MAKE -s --no-print-directory -C hooks-plugin package.test-phase-hooks-plugin TOP={top}'), - - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + pre_cmd('$MAKE -s --no-print-directory -C hooks-plugin package.test-phase-hooks-plugin TOP={top}')], compile, ['-package-db hooks-plugin/pkg.test-phase-hooks-plugin/local.package.conf -fplugin Hooks.PhasePlugin -package hooks-plugin ' + config.plugin_way_flags]) diff --git a/testsuite/tests/plugins/plugins02.stderr b/testsuite/tests/plugins/plugins02.stderr index 2ea9331d3ec..3d035ef35ee 100644 --- a/testsuite/tests/plugins/plugins02.stderr +++ b/testsuite/tests/plugins/plugins02.stderr @@ -1 +1 @@ -: The value Simple.BadlyTypedPlugin.plugin with type GHC.Internal.Types.Int did not have the type GHC.Plugins.Plugin as required +: The value Simple.BadlyTypedPlugin.plugin with type GHC.Internal.Types.Int did not have the type GHC.Driver.Plugins.Plugin as required diff --git a/testsuite/tests/rts/T8308/all.T b/testsuite/tests/rts/T8308/all.T index 74eeec3ebcb..080f09743f3 100644 --- a/testsuite/tests/rts/T8308/all.T +++ b/testsuite/tests/rts/T8308/all.T @@ -1 +1 @@ -test('T8308', js_broken(22261), makefile_test, ['T8308']) +test('T8308', req_target_debug_rts, makefile_test, ['T8308']) diff --git a/testsuite/tests/rts/all.T b/testsuite/tests/rts/all.T index 69fa8c5bdcb..6c4388b8a04 100644 --- a/testsuite/tests/rts/all.T +++ b/testsuite/tests/rts/all.T @@ -241,6 +241,7 @@ test('return_mem_to_os', normal, compile_and_run, ['']) test('T4850', [ when(opsys('mingw32'), expect_broken(4850)) , js_broken(22261) # FFI "dynamic" convention unsupported + , req_target_debug_rts ], makefile_test, ['T4850']) def config_T5250(name, opts): @@ -413,7 +414,7 @@ test('T10904', [ extra_run_opts('20000'), req_c ], test('T10728', [extra_run_opts('+RTS -maxN3 -RTS'), only_ways(['threaded2'])], compile_and_run, ['']) -test('T9405', [when(opsys('mingw32'), fragile(21361)), js_broken(22261)], makefile_test, ['T9405']) +test('T9405', [when(opsys('mingw32'), fragile(21361)), req_target_debug_rts], makefile_test, ['T9405']) test('T11788', [ when(ghc_dynamic(), skip) , req_interp @@ -469,6 +470,8 @@ test('T14900', test('InternalCounters', [ js_skip # JS backend doesn't support internal counters + # Require threaded RTS + , req_target_smp # The ways which build against the debug RTS are built with PROF_SPIN and # therefore differ in output , omit_ways(['nonmoving_thr_sanity', 'threaded2_sanity', 'sanity']) @@ -503,6 +506,7 @@ test('keep-cafs-fail', filter_stdout_lines('Evaluated a CAF|exit.*'), ignore_stderr, # on OS X the shell emits an "Abort trap" message to stderr req_rts_linker, + req_target_debug_rts ], makefile_test, ['KeepCafsFail']) @@ -512,7 +516,8 @@ test('keep-cafs', 'KeepCafs2.hs', 'KeepCafsMain.hs']), when(opsys('mingw32'), expect_broken (5987)), when(opsys('freebsd') or opsys('openbsd'), expect_broken(16035)), - req_rts_linker + req_rts_linker, + req_target_debug_rts ], makefile_test, ['KeepCafs']) @@ -522,12 +527,11 @@ test('T11829', [ req_c, check_errmsg("This is a test"), when(arch('wasm32'), fra ['T11829_c.cpp -package system-cxx-std-lib']) test('T16514', [req_c, omit_ghci], compile_and_run, ['T16514_c.c']) -test('test-zeroongc', extra_run_opts('-DZ'), compile_and_run, ['-debug']) +test('test-zeroongc', [extra_run_opts('-DZ'), req_target_debug_rts], compile_and_run, ['-debug']) test('T13676', [when(opsys('mingw32'), expect_broken(17447)), - extra_files(['T13676.hs']), - when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], + extra_files(['T13676.hs'])], ghci_script, ['T13676.script']) test('InitEventLogging', [ only_ways(['normal']) @@ -605,7 +609,7 @@ test('decodeMyStack_emptyListForMissingFlag', test('T20201a', [js_skip, exit_code(1)], compile_and_run, ['-with-rtsopts -AturtlesM']) test('T20201b', [js_skip, exit_code(1)], compile_and_run, ['-with-rtsopts -A64z']) -test('T22012', [js_skip, extra_ways(['ghci'])], compile_and_run, ['T22012_c.c']) +test('T22012', [js_skip, fragile(23043), extra_ways(['ghci'])], compile_and_run, ['T22012_c.c']) # Skip for JS platform as the JS RTS is always single threaded test('T22795a', [only_ways(['normal']), js_skip, req_ghc_with_threaded_rts], compile_and_run, ['-threaded']) @@ -625,7 +629,7 @@ test('T23221', compile_and_run, ['-O -with-rtsopts -T']) -test('T23142', [unless(debug_rts(), skip), req_interp], makefile_test, ['T23142']) +test('T23142', [req_target_debug_rts, req_interp], makefile_test, ['T23142']) test('T23400', [], compile_and_run, ['-with-rtsopts -A8k']) diff --git a/testsuite/tests/rts/linker/T20494-obj.c b/testsuite/tests/rts/linker/T20494-obj.c index ed073d6cfaf..501238028ba 100644 --- a/testsuite/tests/rts/linker/T20494-obj.c +++ b/testsuite/tests/rts/linker/T20494-obj.c @@ -1,8 +1,11 @@ #include +#include #define CONSTRUCTOR(prio) __attribute__((constructor(prio))) #define DESTRUCTOR(prio) __attribute__((destructor(prio))) -#define PRINT(str) printf(str); fflush(stdout) +// don't use "stdout" variable here as it is not properly defined when loading +// this object in a statically linked GHC. +#define PRINT(str) dprintf(1,str); fsync(1) CONSTRUCTOR(1000) void constr_a(void) { PRINT("constr a\n"); } CONSTRUCTOR(2000) void constr_b(void) { PRINT("constr b\n"); } diff --git a/testsuite/tests/rts/linker/all.T b/testsuite/tests/rts/linker/all.T index e88594b1025..db593c1b006 100644 --- a/testsuite/tests/rts/linker/all.T +++ b/testsuite/tests/rts/linker/all.T @@ -123,14 +123,17 @@ test('linker_unload_native', ###################################### test('linker_error1', [extra_files(['linker_error.c']), js_skip, # dynamic linking not supported by the JS backend + req_target_debug_rts, ignore_stderr], makefile_test, ['linker_error1']) test('linker_error2', [extra_files(['linker_error.c']), js_skip, # dynamic linking not supported by the JS backend + req_target_debug_rts, ignore_stderr], makefile_test, ['linker_error2']) test('linker_error3', [extra_files(['linker_error.c']), js_skip, # dynamic linking not supported by the JS backend + req_target_debug_rts, ignore_stderr], makefile_test, ['linker_error3']) ###################################### @@ -149,11 +152,12 @@ test('rdynamic', [ unless(opsys('linux') or opsys('mingw32'), skip) test('T7072', [extra_files(['load-object.c', 'T7072.c']), unless(opsys('linux'), skip), - req_rts_linker], + req_rts_linker, + req_target_debug_rts + ], makefile_test, ['T7072']) -test('T20494', [req_rts_linker, when(opsys('linux') and not ghc_dynamic(), expect_broken(20706))], - makefile_test, ['T20494']) +test('T20494', [req_rts_linker], makefile_test, ['T20494']) test('T20918', [extra_files(['T20918_v.cc']), diff --git a/testsuite/tests/th/T10279.hs b/testsuite/tests/th/T10279.hs index b8dbf9d9bcb..bbcb42b0d3b 100644 --- a/testsuite/tests/th/T10279.hs +++ b/testsuite/tests/th/T10279.hs @@ -1,10 +1,11 @@ module T10279 where import Language.Haskell.TH import Language.Haskell.TH.Syntax +import T10279h -- NB: rts-1.0.2 is used here because it doesn't change. -- You do need to pick the right version number, otherwise the -- error message doesn't recognize it as a source package ID, -- (This is OK, since it will look obviously wrong when they -- try to find the package in their package database.) -blah = $(conE (Name (mkOccName "Foo") (NameG VarName (mkPkgName "rts-1.0.3") (mkModName "A")))) +blah = $(conE (Name (mkOccName "Foo") (NameG VarName (mkPkgName ("ghc-internal-" <> pkg_version)) (mkModName "A")))) diff --git a/testsuite/tests/th/T10279.stderr b/testsuite/tests/th/T10279.stderr index 6ac34bc0951..e6f4f8d3d05 100644 --- a/testsuite/tests/th/T10279.stderr +++ b/testsuite/tests/th/T10279.stderr @@ -1,11 +1,13 @@ - -T10279.hs:10:9: error: [GHC-51294] +T10279.hs:11:9: error: [GHC-51294] • Failed to load interface for ‘A’. - no unit id matching ‘rts-1.0.3’ was found - (This unit ID looks like the source package ID; - the real unit ID is ‘rts’) + no unit id matching ‘ghc-internal-9.1300.0’ was found + (This unit-id looks like a source package name-version; candidates real unit-ids are: + ‘ghc-internal’) • In the untyped splice: $(conE (Name (mkOccName "Foo") - (NameG VarName (mkPkgName "rts-1.0.3") (mkModName "A")))) + (NameG + VarName (mkPkgName ("ghc-internal-" <> pkg_version)) + (mkModName "A")))) + diff --git a/testsuite/tests/th/T10279h.hs b/testsuite/tests/th/T10279h.hs new file mode 100644 index 00000000000..856a8052b20 --- /dev/null +++ b/testsuite/tests/th/T10279h.hs @@ -0,0 +1,4 @@ +{-# LANGUAGE CPP #-} +module T10279h where + +pkg_version = VERSION_ghc_internal diff --git a/testsuite/tests/th/T16180.hs b/testsuite/tests/th/T16180.hs index 88859285384..e4232b41fac 100644 --- a/testsuite/tests/th/T16180.hs +++ b/testsuite/tests/th/T16180.hs @@ -22,11 +22,13 @@ $(do [ ".global \"_mydata\"" , "_mydata:" , ".ascii \"Hello world\\0\"" + , ".section .note.GNU-stack,\"\",@progbits" ] #else [ ".global \"mydata\"" , "mydata:" , ".ascii \"Hello world\\0\"" + , ".section .note.GNU-stack,\"\",@progbits" ] #endif return []) diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T index b1015cb7266..ee7b5b93fa6 100644 --- a/testsuite/tests/th/all.T +++ b/testsuite/tests/th/all.T @@ -325,7 +325,7 @@ test('T10047', only_ways(['ghci']), ghci_script, ['T10047.script']) test('T10019', only_ways(['ghci']), ghci_script, ['T10019.script']) test('T10267', [], multimod_compile_fail, ['T10267', '-fno-max-valid-hole-fits -dsuppress-uniques -v0 ' + config.ghc_th_way_flags]) -test('T10279', normal, compile_fail, ['-v0']) +test('T10279', [normalise_version('ghc-internal'), extra_files(['T10279h.hs'])], multimod_compile_fail, ['T10279', '-v0']) test('T10306', normal, compile, ['-v0']) test('T10596', normal, compile, ['-v0']) test('T10598_TH', normal, compile, ['-v0 -dsuppress-uniques -ddump-splices']) diff --git a/utils/deriveConstants/Main.hs b/utils/deriveConstants/Main.hs index 68acf8ec815..044ba9339b4 100644 --- a/utils/deriveConstants/Main.hs +++ b/utils/deriveConstants/Main.hs @@ -841,6 +841,7 @@ getWanted verbose os tmpdir gccProgram gccFlags nmProgram mobjdumpProgram = case words line of ('_' : n) : "C" : s : _ -> mkP n s n : "C" : s : _ -> mkP n s + n : "B" : _ : s : _ -> mkP n s [n, "D", _, s] -> mkP n s [s, "O", "*COM*", _, n] -> mkP n s _ -> Nothing diff --git a/utils/fs/README b/utils/fs/README deleted file mode 100644 index 5011939a381..00000000000 --- a/utils/fs/README +++ /dev/null @@ -1,4 +0,0 @@ -This "fs" library, used by various ghc utilities is used to share some common -I/O filesystem functions with different packages. - -This file is copied across the build-system by configure. diff --git a/utils/fs/fs.c b/utils/fs/fs.c deleted file mode 100644 index d64094cae15..00000000000 --- a/utils/fs/fs.c +++ /dev/null @@ -1,590 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) Tamar Christina 2018-2019 - * - * Windows I/O routines for file opening. - * - * NOTE: Only modify this file in utils/fs/ and rerun configure. Do not edit - * this file in any other directory as it will be overwritten. - * - * ---------------------------------------------------------------------------*/ -#include "fs.h" -#include - -#if defined(_WIN32) - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* Duplicate a string, but in wide form. The caller is responsible for freeing - the result. */ -static wchar_t* FS(to_wide) (const char *path) { - size_t len = mbstowcs (NULL, path, 0); - wchar_t *w_path = malloc (sizeof (wchar_t) * (len + 1)); - mbstowcs (w_path, path, len); - w_path[len] = L'\0'; - return w_path; -} - -/* This function converts Windows paths between namespaces. More specifically - It converts an explorer style path into a NT or Win32 namespace. - This has several caveats but they are caveats that are native to Windows and - not POSIX. See - https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx. - Anything else such as raw device paths we leave untouched. The main benefit - of doing any of this is that we can break the MAX_PATH restriction and also - access raw handles that we couldn't before. - - The resulting string is dynamically allocated and so callers are expected to - free this string. */ -wchar_t* FS(create_device_name) (const wchar_t* filename) { - const wchar_t* win32_dev_namespace = L"\\\\.\\"; - const wchar_t* win32_file_namespace = L"\\\\?\\"; - const wchar_t* nt_device_namespace = L"\\Device\\"; - const wchar_t* unc_prefix = L"UNC\\"; - const wchar_t* network_share = L"\\\\"; - - wchar_t* result = _wcsdup (filename); - wchar_t ns[10] = {0}; - - /* If the file is already in a native namespace don't change it. */ - if ( wcsncmp (win32_dev_namespace , filename, 4) == 0 - || wcsncmp (win32_file_namespace, filename, 4) == 0 - || wcsncmp (nt_device_namespace , filename, 8) == 0) - return result; - - /* Since we're using the lower level APIs we must normalize slashes now. The - Win32 API layer will no longer convert '/' into '\\' for us. */ - for (size_t i = 0; i < wcslen (result); i++) - { - if (result[i] == L'/') - result[i] = L'\\'; - } - - /* We need to expand dos short paths as well. */ - DWORD nResult = GetLongPathNameW (result, NULL, 0) + 1; - wchar_t* temp = NULL; - if (nResult > 1) - { - temp = _wcsdup (result); - free (result); - result = malloc (nResult * sizeof (wchar_t)); - if (GetLongPathNameW (temp, result, nResult) == 0) - { - result = memcpy (result, temp, wcslen (temp)); - goto cleanup; - } - free (temp); - } - - /* Now resolve any . and .. in the path or subsequent API calls may fail since - Win32 will no longer resolve them. */ - nResult = GetFullPathNameW (result, 0, NULL, NULL) + 1; - temp = _wcsdup (result); - free (result); - result = malloc (nResult * sizeof (wchar_t)); - if (GetFullPathNameW (temp, nResult, result, NULL) == 0) - { - result = memcpy (result, temp, wcslen (temp)); - goto cleanup; - } - - free (temp); - - int startOffset = 0; - /* When remapping a network share, \\foo needs to become - \\?\UNC\foo and not \\?\\UNC\\foo which is an invalid path. */ - if (wcsncmp (network_share, result, 2) == 0) - { - if (swprintf (ns, 10, L"%ls%ls", win32_file_namespace, unc_prefix) <= 0) - { - goto cleanup; - } - startOffset = 2; - } - else if (swprintf (ns, 10, L"%ls", win32_file_namespace) <= 0) - { - goto cleanup; - } - - /* Create new string. */ - int bLen = wcslen (result) + wcslen (ns) + 1 - startOffset; - temp = _wcsdup (result + startOffset); - free (result); - result = malloc (bLen * sizeof (wchar_t)); - if (swprintf (result, bLen, L"%ls%ls", ns, temp) <= 0) - { - goto cleanup; - } - - free (temp); - - return result; - -cleanup: - free (temp); - free (result); - return NULL; -} - -static int setErrNoFromWin32Error (void); -/* Sets errno to the right error value and returns -1 to indicate the failure. - This function should only be called when the creation of the fd actually - failed and you want to return -1 for the fd. */ -static -int setErrNoFromWin32Error (void) { - switch (GetLastError()) { - case ERROR_SUCCESS: - errno = 0; - break; - case ERROR_ACCESS_DENIED: - case ERROR_FILE_READ_ONLY: - errno = EACCES; - break; - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - errno = ENOENT; - break; - case ERROR_FILE_EXISTS: - errno = EEXIST; - break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_OUTOFMEMORY: - errno = ENOMEM; - break; - case ERROR_INVALID_HANDLE: - errno = EBADF; - break; - case ERROR_INVALID_FUNCTION: - errno = EFAULT; - break; - default: - errno = EINVAL; - break; - } - return -1; -} - - -#define HAS_FLAG(a,b) (((a) & (b)) == (b)) - -int FS(swopen) (const wchar_t* filename, int oflag, int shflag, int pmode) -{ - /* Construct access mode. */ - /* https://docs.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants */ - DWORD dwDesiredAccess = 0; - if (HAS_FLAG (oflag, _O_RDONLY)) - dwDesiredAccess |= GENERIC_READ; - if (HAS_FLAG (oflag, _O_RDWR)) - dwDesiredAccess |= GENERIC_WRITE | GENERIC_READ; - if (HAS_FLAG (oflag, _O_WRONLY)) - dwDesiredAccess |= GENERIC_WRITE; - if (HAS_FLAG (oflag, _O_APPEND)) - dwDesiredAccess |= FILE_APPEND_DATA; - - /* Construct shared mode. */ - /* https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants */ - DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - if (HAS_FLAG (shflag, _SH_DENYRW)) - dwShareMode &= ~(FILE_SHARE_READ | FILE_SHARE_WRITE); - if (HAS_FLAG (shflag, _SH_DENYWR)) - dwShareMode &= ~FILE_SHARE_WRITE; - if (HAS_FLAG (shflag, _SH_DENYRD)) - dwShareMode &= ~FILE_SHARE_READ; - if (HAS_FLAG (pmode, _S_IWRITE)) - dwShareMode |= FILE_SHARE_READ | FILE_SHARE_WRITE; - if (HAS_FLAG (pmode, _S_IREAD)) - dwShareMode |= FILE_SHARE_READ; - - /* Override access mode with pmode if creating file. */ - if (HAS_FLAG (oflag, _O_CREAT)) - { - if (HAS_FLAG (pmode, _S_IWRITE)) - dwDesiredAccess |= FILE_GENERIC_WRITE; - if (HAS_FLAG (pmode, _S_IREAD)) - dwDesiredAccess |= FILE_GENERIC_READ; - } - - /* Create file disposition. */ - /* https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea */ - DWORD dwCreationDisposition = 0; - if (HAS_FLAG (oflag, (_O_CREAT | _O_EXCL))) - dwCreationDisposition |= CREATE_NEW; - else if (HAS_FLAG (oflag, _O_TRUNC | _O_CREAT)) - dwCreationDisposition |= CREATE_ALWAYS; - else if (HAS_FLAG (oflag, _O_TRUNC) && !HAS_FLAG (oflag, O_RDONLY)) - dwCreationDisposition |= TRUNCATE_EXISTING; - else if (HAS_FLAG (oflag, _O_APPEND | _O_CREAT)) - dwCreationDisposition |= OPEN_ALWAYS; - else if (HAS_FLAG (oflag, _O_APPEND)) - dwCreationDisposition |= OPEN_EXISTING; - else if (HAS_FLAG (oflag, _O_CREAT)) - dwCreationDisposition |= OPEN_ALWAYS; - else - dwCreationDisposition |= OPEN_EXISTING; - - /* Set file access attributes. */ - DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; - if (HAS_FLAG (oflag, _O_RDONLY)) - dwFlagsAndAttributes |= 0; /* No special attribute. */ - if (HAS_FLAG (oflag, _O_TEMPORARY)) - { - dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - dwShareMode |= FILE_SHARE_DELETE; - } - if (HAS_FLAG (oflag, _O_SHORT_LIVED)) - dwFlagsAndAttributes |= FILE_ATTRIBUTE_TEMPORARY; - if (HAS_FLAG (oflag, _O_RANDOM)) - dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; - if (HAS_FLAG (oflag, _O_SEQUENTIAL)) - dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - /* Flag is only valid on it's own. */ - if (dwFlagsAndAttributes != FILE_ATTRIBUTE_NORMAL) - dwFlagsAndAttributes &= ~FILE_ATTRIBUTE_NORMAL; - - /* Ensure we have shared read for files which are opened read-only. */ - if (HAS_FLAG (dwCreationDisposition, OPEN_EXISTING) - && ((dwDesiredAccess & (GENERIC_WRITE|GENERIC_READ)) == GENERIC_READ)) - dwShareMode |= FILE_SHARE_READ; - - /* Set security attributes. */ - SECURITY_ATTRIBUTES securityAttributes; - ZeroMemory (&securityAttributes, sizeof(SECURITY_ATTRIBUTES)); - securityAttributes.bInheritHandle = !(oflag & _O_NOINHERIT); - securityAttributes.lpSecurityDescriptor = NULL; - securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - - wchar_t* _filename = FS(create_device_name) (filename); - if (!_filename) - return -1; - - HANDLE hResult - = CreateFileW (_filename, dwDesiredAccess, dwShareMode, &securityAttributes, - dwCreationDisposition, dwFlagsAndAttributes, NULL); - - free (_filename); - if (INVALID_HANDLE_VALUE == hResult) - return setErrNoFromWin32Error (); - - /* Now we have a Windows handle, we have to convert it to an FD and apply - the remaining flags. */ - const int flag_mask = _O_APPEND | _O_RDONLY | _O_TEXT | _O_WTEXT; - int fd = _open_osfhandle ((intptr_t)hResult, oflag & flag_mask); - if (-1 == fd) - return setErrNoFromWin32Error (); - - /* Finally we can change the mode to the requested one. */ - const int mode_mask = _O_TEXT | _O_BINARY | _O_U16TEXT | _O_U8TEXT | _O_WTEXT; - if ((oflag & mode_mask) && (-1 == _setmode (fd, oflag & mode_mask))) - return setErrNoFromWin32Error (); - - return fd; -} - -int FS(translate_mode) (const wchar_t* mode) -{ - int oflag = 0; - int len = wcslen (mode); - int i; - #define IS_EXT(X) ((i < (len - 1)) && mode[i+1] == X) - - for (i = 0; i < len; i++) - { - switch (mode[i]) - { - case L'a': - if (IS_EXT (L'+')) - oflag |= _O_RDWR | _O_CREAT | _O_APPEND; - else - oflag |= _O_WRONLY | _O_CREAT | _O_APPEND; - break; - case L'r': - if (IS_EXT (L'+')) - oflag |= _O_RDWR; - else - oflag |= _O_RDONLY; - break; - case L'w': - if (IS_EXT (L'+')) - oflag |= _O_RDWR | _O_CREAT | _O_TRUNC; - else - oflag |= _O_WRONLY | _O_CREAT | _O_TRUNC; - break; - case L'b': - oflag |= _O_BINARY; - break; - case L't': - oflag |= _O_TEXT; - break; - case L'c': - case L'n': - oflag |= 0; - break; - case L'S': - oflag |= _O_SEQUENTIAL; - break; - case L'R': - oflag |= _O_RANDOM; - break; - case L'T': - oflag |= _O_SHORT_LIVED; - break; - case L'D': - oflag |= _O_TEMPORARY; - break; - default: - if (wcsncmp (mode, L"ccs=UNICODE", 11) == 0) - oflag |= _O_WTEXT; - else if (wcsncmp (mode, L"ccs=UTF-8", 9) == 0) - oflag |= _O_U8TEXT; - else if (wcsncmp (mode, L"ccs=UTF-16LE", 12) == 0) - oflag |= _O_U16TEXT; - else continue; - } - } - #undef IS_EXT - - return oflag; -} - -FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode) -{ - int shflag = 0; - int pmode = 0; - int oflag = FS(translate_mode) (mode); - - int fd = FS(swopen) (filename, oflag, shflag, pmode); - if (fd < 0) - return NULL; - - FILE* file = _wfdopen (fd, mode); - return file; -} - -FILE *FS(fopen) (const char* filename, const char* mode) -{ - wchar_t * const w_filename = FS(to_wide) (filename); - wchar_t * const w_mode = FS(to_wide) (mode); - - FILE *result = FS(fwopen) (w_filename, w_mode); - free (w_filename); - free (w_mode); - - return result; -} - -int FS(sopen) (const char* filename, int oflag, int shflag, int pmode) -{ - wchar_t * const w_filename = FS(to_wide) (filename); - int result = FS(swopen) (w_filename, oflag, shflag, pmode); - free (w_filename); - - return result; -} - -int FS(_stat) (const char *path, struct _stat *buffer) -{ - wchar_t * const w_path = FS(to_wide) (path); - int result = FS(_wstat) (w_path, buffer); - free (w_path); - - return result; -} - -int FS(_stat64) (const char *path, struct __stat64 *buffer) -{ - wchar_t * const w_path = FS(to_wide) (path); - int result = FS(_wstat64) (w_path, buffer); - free (w_path); - - return result; -} - -static __time64_t ftToPosix(FILETIME ft) -{ - /* takes the last modified date. */ - LARGE_INTEGER date, adjust; - date.HighPart = ft.dwHighDateTime; - date.LowPart = ft.dwLowDateTime; - - /* 100-nanoseconds = milliseconds * 10000. */ - /* A UNIX timestamp contains the number of seconds from Jan 1, 1970, while the - FILETIME documentation says: Contains a 64-bit value representing the - number of 100-nanosecond intervals since January 1, 1601 (UTC). - - Between Jan 1, 1601 and Jan 1, 1970 there are 11644473600 seconds */ - adjust.QuadPart = 11644473600000 * 10000; - - /* removes the diff between 1970 and 1601. */ - date.QuadPart -= adjust.QuadPart; - - /* converts back from 100-nanoseconds to seconds. */ - return (__time64_t)date.QuadPart / 10000000; -} - -int FS(_wstat) (const wchar_t *path, struct _stat *buffer) -{ - ZeroMemory (buffer, sizeof (struct _stat)); - wchar_t* _path = FS(create_device_name) (path); - if (!_path) - return -1; - - /* Construct shared mode. */ - DWORD dwShareMode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE; - DWORD dwDesiredAccess = FILE_READ_ATTRIBUTES; - DWORD dwFlagsAndAttributes = FILE_FLAG_BACKUP_SEMANTICS; - DWORD dwCreationDisposition = OPEN_EXISTING; - - SECURITY_ATTRIBUTES securityAttributes; - ZeroMemory (&securityAttributes, sizeof(SECURITY_ATTRIBUTES)); - securityAttributes.bInheritHandle = false; - securityAttributes.lpSecurityDescriptor = NULL; - securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); - - HANDLE hResult - = CreateFileW (_path, dwDesiredAccess, dwShareMode, &securityAttributes, - dwCreationDisposition, dwFlagsAndAttributes, NULL); - - if (INVALID_HANDLE_VALUE == hResult) - { - free (_path); - return setErrNoFromWin32Error (); - } - - WIN32_FILE_ATTRIBUTE_DATA finfo; - ZeroMemory (&finfo, sizeof (WIN32_FILE_ATTRIBUTE_DATA)); - if(!GetFileAttributesExW (_path, GetFileExInfoStandard, &finfo)) - { - free (_path); - CloseHandle (hResult); - return setErrNoFromWin32Error (); - } - - unsigned short mode = _S_IREAD; - - if (finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - mode |= (_S_IFDIR | _S_IEXEC); - else - { - mode |= _S_IFREG; - DWORD type; - if (GetBinaryTypeW (_path, &type)) - mode |= _S_IEXEC; - } - - if (!(finfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - mode |= _S_IWRITE; - - buffer->st_mode = mode; - buffer->st_nlink = 1; - buffer->st_size = ((uint64_t)finfo.nFileSizeHigh << 32) + finfo.nFileSizeLow; - buffer->st_atime = ftToPosix (finfo.ftLastAccessTime); - buffer->st_mtime = buffer->st_ctime = ftToPosix (finfo.ftLastWriteTime); - free (_path); - CloseHandle (hResult); - return 0; -} - -int FS(_wstat64) (const wchar_t *path, struct __stat64 *buffer) -{ - struct _stat buf; - ZeroMemory (buffer, sizeof (struct __stat64)); - - int result = FS(_wstat) (path, &buf); - - buffer->st_mode = buf.st_mode; - buffer->st_nlink = 1; - buffer->st_size = buf.st_size; - buffer->st_atime = buf.st_atime; - buffer->st_mtime = buf.st_mtime; - - return result; -} - -int FS(_wrename) (const wchar_t *from, const wchar_t *to) -{ - wchar_t* const _from = FS(create_device_name) (from); - if (!_from) - return -1; - - wchar_t* const _to = FS(create_device_name) (to); - if (!_to) - { - free (_from); - return -1; - } - - if (MoveFileW(_from, _to) == 0) { - free (_from); - free (_to); - return setErrNoFromWin32Error (); - } - - - free (_from); - free (_to); - return 0; -} - -int FS(rename) (const char *from, const char *to) -{ - wchar_t * const w_from = FS(to_wide) (from); - wchar_t * const w_to = FS(to_wide) (to); - int result = FS(_wrename) (w_from, w_to); - free(w_from); - free(w_to); - - return result; -} - -int FS(unlink) (const char *filename) -{ - return FS(_unlink) (filename); -} - -int FS(_unlink) (const char *filename) -{ - wchar_t * const w_filename = FS(to_wide) (filename); - int result = FS(_wunlink) (w_filename); - free(w_filename); - - return result; -} - -int FS(_wunlink) (const wchar_t *filename) -{ - wchar_t* const _filename = FS(create_device_name) (filename); - if (!_filename) - return -1; - - if (DeleteFileW(_filename) == 0) { - free (_filename); - return setErrNoFromWin32Error (); - } - - - free (_filename); - return 0; -} -int FS(remove) (const char *path) -{ - return FS(_unlink) (path); -} -int FS(_wremove) (const wchar_t *path) -{ - return FS(_wunlink) (path); -} -#else -FILE *FS(fopen) (const char* filename, const char* mode) -{ - return fopen (filename, mode); -} -#endif diff --git a/utils/fs/fs.h b/utils/fs/fs.h deleted file mode 100644 index 6c5f56ccdd7..00000000000 --- a/utils/fs/fs.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * (c) Tamar Christina 2018-2019 - * - * Windows I/O routines for file opening. - * - * NOTE: Only modify this file in utils/fs/ and rerun configure. Do not edit - * this file in any other directory as it will be overwritten. - * - * ---------------------------------------------------------------------------*/ - -#pragma once - -#include - -#if !defined(FS_NAMESPACE) -#define FS_NAMESPACE hs -#endif - -/* Play some dirty tricks to get CPP to expand correctly. */ -#define FS_FULL(ns, name) __##ns##_##name -#define prefix FS_NAMESPACE -#define FS_L(p, n) FS_FULL(p, n) -#define FS(name) FS_L(prefix, name) - -#if defined(_WIN32) -#include -// N.B. defines some macro rewrites to, e.g., turn _wstat into -// _wstat64i32. We must include it here to ensure tat this rewrite applies to -// both the definition and use sites. -#include -#include - -wchar_t* FS(create_device_name) (const wchar_t*); -int FS(translate_mode) (const wchar_t*); -int FS(swopen) (const wchar_t* filename, int oflag, - int shflag, int pmode); -int FS(sopen) (const char* filename, int oflag, - int shflag, int pmode); -FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode); -FILE *FS(fopen) (const char* filename, const char* mode); -int FS(_stat) (const char *path, struct _stat *buffer); -int FS(_stat64) (const char *path, struct __stat64 *buffer); -int FS(_wstat) (const wchar_t *path, struct _stat *buffer); -int FS(_wstat64) (const wchar_t *path, struct __stat64 *buffer); -int FS(_wrename) (const wchar_t *from, const wchar_t *to); -int FS(rename) (const char *from, const char *to); -int FS(unlink) (const char *filename); -int FS(_unlink) (const char *filename); -int FS(_wunlink) (const wchar_t *filename); -int FS(remove) (const char *path); -int FS(_wremove) (const wchar_t *path); -#else -FILE *FS(fopen) (const char* filename, const char* mode); -#endif diff --git a/utils/genprimopcode/Main.hs b/utils/genprimopcode/Main.hs index ac39e81abb3..dc24828b078 100644 --- a/utils/genprimopcode/Main.hs +++ b/utils/genprimopcode/Main.hs @@ -209,6 +209,12 @@ main = getArgs >>= \args -> "--foundation-tests" -> putStr (gen_foundation_tests p_o_specs) + "--wrappers-module" + -> putStr (gen_wrappers_module p_o_specs) + + "--prim-module" + -> putStr (gen_hs_source_module p_o_specs) + _ -> error "Should not happen, known_args out of sync?" ) @@ -235,13 +241,18 @@ known_args "--make-latex-doc", "--wired-in-docs", "--wired-in-deprecations", - "--foundation-tests" + "--foundation-tests", + "--wrappers-module", + "--prim-module" ] ------------------------------------------------------------------ -- Code generators ----------------------------------------------- ------------------------------------------------------------------ +gen_hs_source_module :: Info -> String +gen_hs_source_module info = "primOpPrimModule = " ++ show (gen_hs_source info) + gen_hs_source :: Info -> String gen_hs_source (Info defaults entries) = "{-\n" @@ -467,6 +478,9 @@ In PrimopWrappers we set some crucial GHC options a very simple module and there is no optimisation to be done -} +gen_wrappers_module :: Info -> String +gen_wrappers_module info = "primOpWrappersModule = " ++ show (gen_wrappers info) + gen_wrappers :: Info -> String gen_wrappers (Info _ entries) = "-- | Users should not import this module. It is GHC internal only.\n" diff --git a/utils/genprimopcode/genprimopcode.cabal b/utils/genprimopcode/genprimopcode.cabal index 8db8827e159..946c5e576ae 100644 --- a/utils/genprimopcode/genprimopcode.cabal +++ b/utils/genprimopcode/genprimopcode.cabal @@ -31,5 +31,7 @@ Executable genprimopcode AccessOps Build-Depends: base >= 4 && < 5, array + default-extensions: + UnboxedSums if flag(build-tool-depends) build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0 diff --git a/utils/ghc-pkg/Main.hs b/utils/ghc-pkg/Main.hs index 14684dc9649..a262b711e0c 100644 --- a/utils/ghc-pkg/Main.hs +++ b/utils/ghc-pkg/Main.hs @@ -5,6 +5,7 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE KindSignatures #-} +{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -151,6 +152,7 @@ data Flag | FlagVerbosity (Maybe String) | FlagUnitId | FlagShowUnitIds + | FlagTarget String deriving Eq flags :: [OptDescr Flag] @@ -198,7 +200,9 @@ flags = [ Option [] ["ipid", "unit-id"] (NoArg FlagUnitId) "interpret package arguments as unit IDs (e.g. installed package IDs)", Option ['v'] ["verbose"] (OptArg FlagVerbosity "Verbosity") - "verbosity level (0-2, default 1)" + "verbosity level (0-2, default 1)", + Option [] ["target"] (ReqArg FlagTarget "TARGET") + "run against the specified target (this has no effect if --global-package-db is specified)" ] data Verbosity = Silent | Normal | Verbose @@ -268,6 +272,10 @@ usageHeader prog = substProg prog $ " for input for the graphviz tools. For example, to generate a PDF\n" ++ " of the dependency graph: ghc-pkg dot | tred | dot -Tpdf >pkgs.pdf\n" ++ "\n" ++ + " $p mermaid\n" ++ + " Generate a graph of the package dependencies in Mermaid format\n" ++ + " suitable for embedding in Markdown files.\n" ++ + "\n" ++ " $p find-module {module}\n" ++ " List registered packages exposing module {module} in the global\n" ++ " database, and also the user database if --user is given.\n" ++ @@ -464,6 +472,8 @@ runit verbosity cli nonopts = do (Just (Substring pkgarg_str m)) Nothing ["dot"] -> do showPackageDot verbosity cli + ["mermaid"] -> do + showPackageMermaid verbosity cli ["find-module", mod_name] -> do let match = maybe (==mod_name) id (substringCheck mod_name) listPackages verbosity cli Nothing (Just match) @@ -587,6 +597,29 @@ readFromSettingsFile settingsFile f = do Right archOS -> Right archOS Left e -> Left e +-- | Get the cross target. +-- +-- This is either extracted from the '--target' flag or inferred +-- from the current program name. +getTarget :: [Flag] -> IO (Maybe String) +getTarget my_flags = do + case [ t | FlagTarget t <- my_flags ] of + [] -> do + -- when no target is specified on the command line, infer it from the program name. + -- e.g. x86_64-unknown-linux-ghc-pkg + progN <- getProgName + if | "-ghc-pkg" `isSuffixOf` progN + , parts <- split '-' progN + , length parts > 3 -> pure (Just (take (length progN - 8) progN)) + | otherwise -> pure Nothing + ts -> pure (Just (last ts)) + where + split :: Char -> String -> [String] + split c s = case rest of + [] -> [chunk] + _:rest -> chunk : split c rest + where (chunk, rest) = break (==c) s + getPkgDatabases :: Verbosity -> GhcPkg.DbOpenMode mode DbModifySelector -> Bool -- use the user db @@ -616,7 +649,12 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do [] -> do mb_dir <- getBaseDir case mb_dir of Nothing -> die err_msg - Just dir -> do + Just dir' -> do + mt <- getTarget my_flags + dir <- case mt of + Nothing -> pure dir' + Just target -> pure (dir' "targets" target "lib") + -- Look for where it is given in the settings file, if marked there. let settingsFile = dir "settings" exists_settings_file <- doesFileExist settingsFile @@ -1643,6 +1681,27 @@ showPackageDot verbosity myflags = do ] putStrLn "}" +showPackageMermaid :: Verbosity -> [Flag] -> IO () +showPackageMermaid verbosity myflags = do + (_, GhcPkg.DbOpenReadOnly, flag_db_stack) <- + getPkgDatabases verbosity GhcPkg.DbOpenReadOnly + False{-use user-} True{-use cache-} False{-expand vars-} myflags + + let all_pkgs = allPackagesInStack flag_db_stack + ipix = PackageIndex.fromList all_pkgs + + putStrLn "```mermaid" + putStrLn "graph TD" + mapM_ putStrLn [ " " ++ from ++ " --> " ++ to + | p <- all_pkgs, + let from = display (mungedId p), + key <- depends p, + Just dep <- [PackageIndex.lookupUnitId ipix key], + let to = display (mungedId dep) + ] + putStrLn "```" + + -- ----------------------------------------------------------------------------- -- Prints the highest (hidden or exposed) version of a package diff --git a/utils/ghc-toolchain/exe/Main.hs b/utils/ghc-toolchain/exe/Main.hs index 9b1e9b3d32f..c508f2e5dea 100644 --- a/utils/ghc-toolchain/exe/Main.hs +++ b/utils/ghc-toolchain/exe/Main.hs @@ -1,12 +1,14 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE RecordWildCards #-} module Main where import Control.Monad -import Data.Char (toUpper) +import Data.Char (toUpper,isSpace) import Data.Maybe (isNothing,fromMaybe) +import qualified Data.List as List import System.Exit import System.Console.GetOpt import System.Environment @@ -53,6 +55,8 @@ data Opts = Opts , optReadelf :: ProgOpt , optMergeObjs :: ProgOpt , optWindres :: ProgOpt + , optOtool :: ProgOpt + , optInstallNameTool :: ProgOpt -- Note we don't actually configure LD into anything but -- see #23857 and #22550 for the very unfortunate story. , optLd :: ProgOpt @@ -62,6 +66,7 @@ data Opts = Opts , optLdOverride :: Maybe Bool , optVerbosity :: Int , optKeepTemp :: Bool + , optOutputSettings :: Bool -- ^ Output settings file, not Target } data FormatOpts = FormatOpts @@ -100,6 +105,8 @@ emptyOpts = Opts , optReadelf = po0 , optMergeObjs = po0 , optWindres = po0 + , optOtool = po0 + , optInstallNameTool = po0 , optLd = po0 , optUnregisterised = Nothing , optTablesNextToCode = Nothing @@ -107,6 +114,7 @@ emptyOpts = Opts , optLdOverride = Nothing , optVerbosity = 1 , optKeepTemp = False + , optOutputSettings = False } where po0 = emptyProgOpt @@ -127,6 +135,8 @@ _optNm = Lens optNm (\x o -> o {optNm=x}) _optReadelf = Lens optReadelf (\x o -> o {optReadelf=x}) _optMergeObjs = Lens optMergeObjs (\x o -> o {optMergeObjs=x}) _optWindres = Lens optWindres (\x o -> o {optWindres=x}) +_optOtool = Lens optOtool (\x o -> o {optOtool =x}) +_optInstallNameTool = Lens optInstallNameTool (\x o -> o {optInstallNameTool=x}) _optLd = Lens optLd (\x o -> o {optLd= x}) _optTriple :: Lens Opts (Maybe String) @@ -148,6 +158,9 @@ _optTablesNextToCode = Lens optTablesNextToCode (\x o -> o {optTablesNextToCode= _optUseLibFFIForAdjustors = Lens optUseLibFFIForAdjustors (\x o -> o {optUseLibFFIForAdjustors=x}) _optLdOvveride = Lens optLdOverride (\x o -> o {optLdOverride=x}) +_optOutputSettings :: Lens Opts Bool +_optOutputSettings = Lens optOutputSettings (\x o -> o {optOutputSettings=x}) + _optVerbosity :: Lens Opts Int _optVerbosity = Lens optVerbosity (\x o -> o {optVerbosity=x}) @@ -161,6 +174,7 @@ options = , llvmTripleOpt , verbosityOpt , keepTempOpt + , outputSettingsOpt , outputOpt ] ++ concat @@ -184,6 +198,8 @@ options = , progOpts "readelf" "readelf utility" _optReadelf , progOpts "merge-objs" "linker for merging objects" _optMergeObjs , progOpts "windres" "windres utility" _optWindres + , progOpts "otool" "otool utility" _optOtool + , progOpts "install-name-tool" "install_name_tool utility" _optInstallNameTool , progOpts "ld" "linker" _optLd ] where @@ -233,6 +249,9 @@ options = keepTempOpt = Option [] ["keep-temp"] (NoArg (set _optKeepTemp True)) "do not remove temporary files" + outputSettingsOpt = Option [] ["output-settings"] (NoArg (set _optOutputSettings True)) + "output settings instead of Target" + outputOpt = Option ['o'] ["output"] (ReqArg (set _optOutput . Just) "OUTPUT") "The output path for the generated target toolchain configuration" @@ -309,7 +328,10 @@ run opts = do tgt <- mkTarget opts logDebug $ "Final Target: " ++ show tgt let file = fromMaybe (error "undefined --output") (optOutput opts) - writeFile file (show tgt) + let output = case optOutputSettings opts of + False -> show tgt + True -> show (targetToSettings tgt) + writeFile file output optional :: M a -> M (Maybe a) optional k = fmap Just k <|> pure Nothing @@ -444,6 +466,20 @@ mkTarget opts = do return (Just windres) _ -> return Nothing + otool <- + case archOS_OS archOs of + OSDarwin -> do + otool <- findProgram "otool" (optOtool opts) ["otool"] + return (Just otool) + _ -> return Nothing + + install_name_tool <- + case archOS_OS archOs of + OSDarwin -> do + install_name_tool <- findProgram "install_name_tool" (optInstallNameTool opts) ["install_name_tool"] + return (Just install_name_tool) + _ -> return Nothing + -- various other properties of the platform tgtWordSize <- checkWordSize cc tgtEndianness <- checkEndianness cc @@ -481,6 +517,8 @@ mkTarget opts = do , tgtNm = nm , tgtMergeObjs = mergeObjs , tgtWindres = windres + , tgtOtool = otool + , tgtInstallNameTool = install_name_tool , tgtWordSize , tgtEndianness , tgtUnregisterised @@ -495,3 +533,188 @@ mkTarget opts = do return t --- ROMES:TODO: fp_settings.m4 in general which I don't think was ported completely (e.g. the basenames and windows llvm-XX and such) + + +targetToSettings :: Target -> [(String,String)] +targetToSettings tgt@Target{..} = + [ ("C compiler command", ccPath) + , ("C compiler flags", ccFlags) + , ("C++ compiler command", cxxPath) + , ("C++ compiler flags", cxxFlags) + , ("C compiler link flags", clinkFlags) + , ("C compiler supports -no-pie", linkSupportsNoPie) + , ("CPP command", cppPath) + , ("CPP flags", cppFlags) + , ("Haskell CPP command", hsCppPath) + , ("Haskell CPP flags", hsCppFlags) + , ("JavaScript CPP command", jsCppPath) + , ("JavaScript CPP flags", jsCppFlags) + , ("C-- CPP command", cmmCppPath) + , ("C-- CPP flags", cmmCppFlags) + , ("C-- CPP supports -g0", cmmCppSupportsG0') + , ("ld supports compact unwind", linkSupportsCompactUnwind) + , ("ld supports filelist", linkSupportsFilelist) + , ("ld supports single module", linkSupportsSingleModule) + , ("ld is GNU ld", linkIsGnu) + , ("Merge objects command", mergeObjsPath) + , ("Merge objects flags", mergeObjsFlags) + , ("Merge objects supports response files", mergeObjsSupportsResponseFiles') + , ("ar command", arPath) + , ("ar flags", arFlags) + , ("ar supports at file", arSupportsAtFile') + , ("ar supports -L", arSupportsDashL') + , ("ranlib command", ranlibPath) + , ("otool command", maybe "otool" prgPath tgtOtool) + , ("install_name_tool command", maybe "install_name_tool" prgPath tgtInstallNameTool) + , ("windres command", maybe "/bin/false" prgPath tgtWindres) -- TODO: /bin/false is not available on many distributions by default, but we keep it as it were before the ghc-toolchain patch. Fix-me. + , ("unlit command", "$topdir/../bin/unlit") -- FIXME + , ("cross compiling", yesNo False) -- FIXME: why do we need this settings at all? + , ("target platform string", targetPlatformTriple tgt) + , ("target os", (show $ archOS_OS tgtArchOs)) + , ("target arch", (show $ archOS_arch tgtArchOs)) + , ("target word size", wordSize) + , ("target word big endian", isBigEndian) + , ("target has GNU nonexec stack", (yesNo tgtSupportsGnuNonexecStack)) + , ("target has .ident directive", (yesNo tgtSupportsIdentDirective)) + , ("target has subsections via symbols", (yesNo tgtSupportsSubsectionsViaSymbols)) + , ("target has libm", has_libm) + , ("Unregisterised", (yesNo tgtUnregisterised)) + , ("LLVM target", tgtLlvmTarget) + , ("LLVM llc command", llc_cmd) + , ("LLVM opt command", llvm_opt_cmd) + , ("LLVM llvm-as command", llvm_as_cmd) + , ("LLVM llvm-as flags", "") -- see ec826009b3a9d5f8e975ca2c8002832276043c18, #25793 + , ("Use inplace MinGW toolchain", use_inplace_mingw) + , ("target RTS linker only supports shared libraries", yesNo (targetRTSLinkerOnlySupportsSharedLibs tgt)) + , ("Use interpreter", yesNo (targetSupportsInterpreter tgt)) + , ("Support SMP", yesNo (targetSupportsSMP tgt)) + , ("RTS ways", "v") -- FIXME: should be a property of the RTS, not of the target + , ("Tables next to code", (yesNo tgtTablesNextToCode)) + , ("Leading underscore", (yesNo tgtSymbolsHaveLeadingUnderscore)) + , ("Use LibFFI", yesNo tgtUseLibffiForAdjustors) + , ("RTS expects libdw", yesNo False) -- FIXME + , ("Relative Global Package DB", "package.conf.d") -- FIXME + , ("base unit-id", "") + ] + where + yesNo True = "YES" + yesNo False = "NO" + + wordSize = show (wordSize2Bytes tgtWordSize) + isBigEndian = yesNo $ (\case BigEndian -> True; LittleEndian -> False) tgtEndianness + + has_libm = "NO" -- FIXME + llc_cmd = "llc" -- FIXME + llvm_opt_cmd = "opt" -- FIXME + llvm_as_cmd = "llvm-as" -- FIXME + use_inplace_mingw = "NO" -- FIXME + + ccPath = prgPath $ ccProgram tgtCCompiler + ccFlags = escapeArgs $ prgFlags $ ccProgram tgtCCompiler + cxxPath = prgPath $ cxxProgram tgtCxxCompiler + cxxFlags = escapeArgs $ prgFlags $ cxxProgram tgtCxxCompiler + clinkFlags = escapeArgs $ prgFlags $ ccLinkProgram tgtCCompilerLink + linkSupportsNoPie = yesNo $ ccLinkSupportsNoPie tgtCCompilerLink + cppPath = prgPath $ cppProgram tgtCPreprocessor + cppFlags = escapeArgs $ prgFlags $ cppProgram tgtCPreprocessor + hsCppPath = prgPath $ hsCppProgram tgtHsCPreprocessor + hsCppFlags = escapeArgs $ prgFlags $ hsCppProgram tgtHsCPreprocessor + jsCppPath = maybe "" (prgPath . jsCppProgram) tgtJsCPreprocessor + jsCppFlags = maybe "" (escapeArgs . prgFlags . jsCppProgram) tgtJsCPreprocessor + cmmCppPath = prgPath $ cmmCppProgram tgtCmmCPreprocessor + cmmCppFlags = escapeArgs $ prgFlags $ cmmCppProgram tgtCmmCPreprocessor + cmmCppSupportsG0' = yesNo $ cmmCppSupportsG0 tgtCmmCPreprocessor + mergeObjsPath = maybe "" (prgPath . mergeObjsProgram) tgtMergeObjs + mergeObjsFlags = maybe "" (escapeArgs . prgFlags . mergeObjsProgram) tgtMergeObjs + linkSupportsSingleModule = yesNo $ ccLinkSupportsSingleModule tgtCCompilerLink + linkSupportsFilelist = yesNo $ ccLinkSupportsFilelist tgtCCompilerLink + linkSupportsCompactUnwind = yesNo $ ccLinkSupportsCompactUnwind tgtCCompilerLink + linkIsGnu = yesNo $ ccLinkIsGnu tgtCCompilerLink + arPath = prgPath $ arMkArchive tgtAr + arFlags = escapeArgs $ prgFlags (arMkArchive tgtAr) + arSupportsAtFile' = yesNo (arSupportsAtFile tgtAr) + arSupportsDashL' = yesNo (arSupportsDashL tgtAr) + ranlibPath = maybe "" (prgPath . ranlibProgram) tgtRanlib + mergeObjsSupportsResponseFiles' = maybe "NO" (yesNo . mergeObjsSupportsResponseFiles) tgtMergeObjs + +-- | Just like 'GHC.ResponseFile.escapeArgs', but use spaces instead of newlines +-- for splitting elements. +escapeArgs :: [String] -> String +escapeArgs = unwords . map escapeArg + +escapeArg :: String -> String +escapeArg = reverse . List.foldl' escape [] + +escape :: String -> Char -> String +escape cs c + | isSpace c + || '\\' == c + || '\'' == c + || '"' == c = c:'\\':cs -- n.b., our caller must reverse the result + | otherwise = c:cs + +-- | Does the target support the -N RTS flag? +-- +-- Adapated from hadrian: Oracles.Flag.targetSupportsSMP +targetSupportsSMP :: Target -> Bool +targetSupportsSMP Target{..} = case archOS_arch tgtArchOs of + -- The THREADED_RTS requires `BaseReg` to be in a register and the + -- Unregisterised mode doesn't allow that. + _ | tgtUnregisterised -> False + ArchARM isa _ _ + -- We don't support load/store barriers pre-ARMv7. See #10433. + | isa < ARMv7 -> False + | otherwise -> True + ArchX86 -> True + ArchX86_64 -> True + ArchPPC -> True + ArchPPC_64 ELF_V1 -> True + ArchPPC_64 ELF_V2 -> True + ArchAArch64 -> True + ArchS390X -> True + ArchRISCV64 -> True + ArchLoongArch64 -> True + ArchAArch64 -> True + _ -> False + + + +-- | Check whether the target supports GHCi. +-- +-- Adapted from hadrian:Oracles.Settings.ghcWithInterpreter +targetSupportsInterpreter :: Target -> Bool +targetSupportsInterpreter Target{..} = goodOs && goodArch + where + goodOs = case archOS_OS tgtArchOs of + OSMinGW32 -> True + OSLinux -> True + OSSolaris2 -> True + OSFreeBSD -> True + OSDragonFly -> True + OSNetBSD -> True + OSOpenBSD -> True + OSDarwin -> True + OSKFreeBSD -> True + OSWasi -> True + _ -> False + -- TODO "cygwin32"? + + goodArch = case archOS_arch tgtArchOs of + ArchX86 -> True + ArchX86_64 -> True + ArchPPC -> True + ArchAArch64 -> True + ArchS390X -> True + ArchPPC_64 ELF_V1 -> True + ArchPPC_64 ELF_V2 -> True + ArchRISCV64 -> True + ArchWasm32 -> True + ArchAArch64 -> True + ArchARM {} -> True + _ -> False + + +targetRTSLinkerOnlySupportsSharedLibs :: Target -> Bool +targetRTSLinkerOnlySupportsSharedLibs tgt = case archOS_arch (tgtArchOs tgt) of + ArchWasm32 -> True + _ -> False diff --git a/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs b/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs index ec95db46f9d..e1ffd71c7b5 100644 --- a/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs +++ b/utils/ghc-toolchain/src/GHC/Toolchain/Target.hs @@ -74,6 +74,10 @@ data Target = Target -- Windows-specific tools , tgtWindres :: Maybe Program + + -- Mac specific + , tgtOtool:: Maybe Program + , tgtInstallNameTool :: Maybe Program } deriving (Read, Eq, Ord) @@ -122,5 +126,7 @@ instance Show Target where , ", tgtNm = " ++ show tgtNm , ", tgtMergeObjs = " ++ show tgtMergeObjs , ", tgtWindres = " ++ show tgtWindres + , ", tgtOtool = " ++ show tgtOtool + , ", tgtInstallNameTool = " ++ show tgtInstallNameTool , "}" ] diff --git a/utils/hsc2hs b/utils/hsc2hs index 2fab2f4cdff..c3b21800a67 160000 --- a/utils/hsc2hs +++ b/utils/hsc2hs @@ -1 +1 @@ -Subproject commit 2fab2f4cdffef12afe561ef03f5ebdace7dbae67 +Subproject commit c3b21800a67366c9591dc85a471d1dfdb1efcf29 diff --git a/utils/unlit/unlit.c b/utils/unlit/unlit.c index 2ec2af60582..71c45d4b923 100644 --- a/utils/unlit/unlit.c +++ b/utils/unlit/unlit.c @@ -363,7 +363,7 @@ int main(int argc,char **argv) file = "stdin"; } else - if ((istream=__hs_fopen(argv[0], "r")) == NULL) { + if ((istream=__rts_fopen(argv[0], "r")) == NULL) { fprintf(stderr, CANNOTOPEN, argv[0]); exit(1); } @@ -372,7 +372,7 @@ int main(int argc,char **argv) if (strcmp(argv[1], "-")==0) ostream = stdout; else - if ((ostream=__hs_fopen(argv[1], "w")) == NULL) { + if ((ostream=__rts_fopen(argv[1], "w")) == NULL) { fprintf(stderr, CANNOTOPEN, argv[1]); exit(1); } diff --git a/utils/unlit/unlit.cabal b/utils/unlit/unlit.cabal index 0707d5d95ae..770567be3a8 100644 --- a/utils/unlit/unlit.cabal +++ b/utils/unlit/unlit.cabal @@ -1,18 +1,14 @@ -cabal-version: 2.4 +cabal-version: 3.0 Name: unlit Version: 0.1 -Copyright: XXX License: BSD-3-Clause -Author: XXX -Maintainer: XXX Synopsis: Literate program filter -Description: XXX Category: Development build-type: Simple -extra-source-files: fs.h Executable unlit + cc-options: -DFS_NAMESPACE=rts Default-Language: Haskell2010 Main-Is: unlit.c - C-Sources: fs.c - Includes: fs.h + build-depends: + rts-fs