[Git][ghc/ghc][wip/supersven/hadrian-cross-stage3] 3 commits: Hack
Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC Commits: 7456b7c7 by Sven Tennie at 2026-02-07T08:10:14+01:00 Hack - - - - - 37a1598a by Sven Tennie at 2026-02-07T08:23:33+01:00 WIP: Validate script - - - - - 2fdd2d9a by Sven Tennie at 2026-02-07T12:18:43+01:00 Fix stage3 bindist creation - - - - - 3 changed files: - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/Generate.hs - + validate-riscv-bindist.sh Changes: ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -122,8 +122,8 @@ installTo relocatable prefix = do runBuilderWithCmdOptions env (Make bindistFilesDir) ["install"] [] [] -buildBinDistDir :: FilePath -> BindistConfig -> Action () -buildBinDistDir root conf@BindistConfig{..} = do +buildBinDistDir :: FilePath -> FilePath -> BindistConfig -> Action () +buildBinDistDir dirPrefix root conf@BindistConfig{..} = do verbosity <- getVerbosity -- We 'need' all binaries and libraries @@ -153,7 +153,7 @@ buildBinDistDir root conf@BindistConfig{..} = do distDir <- Context.distDir (vanillaContext library_stage rts) let ghcBuildDir = root -/- stageString library_stage - bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty + bindistFilesDir = root -/- "bindist" -/- dirPrefix <> ghcVersionPretty ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform rtsIncludeDir = distDir -/- "include" @@ -223,8 +223,7 @@ buildBinDistDir root conf@BindistConfig{..} = do -- N.B. the ghc-pkg executable may be prefixed with a target triple -- (c.f. #20267). - -- Not going to work for cross - ghcPkgName <- programName (vanillaContext Stage1 ghcPkg) + ghcPkgName <- programName (vanillaContext executable_stage ghcPkg) cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ] @@ -316,27 +315,27 @@ bindistRules = do phony "binary-dist-dir" $ do cfg <- implicitBindistConfig - buildBinDistDir root cfg + buildBinDistDir "" root cfg - phony "binary-dist-dir-cross" $ buildBinDistDir root crossBindist + phony "binary-dist-dir-cross" $ buildBinDistDir "" root crossBindist - phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist + phony "binary-dist-dir-stage3" $ buildBinDistDir "stage3-" root targetBindist let buildBinDist compressor = do win_host <- isWinHost win_target <- isWinTarget Stage2 when (win_target && win_host) (error "normal binary-dist does not work for windows targets, use `reloc-binary-dist-*` target instead.") - buildBinDistX "binary-dist-dir" "bindist" compressor - buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" + buildBinDistX "binary-dist-dir" "bindist" "" compressor + buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" "" - buildBinDistX :: String -> FilePath -> Compressor -> Action () - buildBinDistX target bindist_folder compressor = do + buildBinDistX :: String -> FilePath -> FilePath -> Compressor -> Action () + buildBinDistX target bindist_folder dirPrefix compressor = do need [target] version <- setting ProjectVersion targetPlatform <- setting TargetPlatformFull - let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform + let ghcVersionPretty = dirPrefix <> "ghc-" ++ version ++ "-" ++ targetPlatform -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz tarPath <- builderPath (Tar Create) @@ -352,12 +351,12 @@ bindistRules = do phony (name <> "-dist-xz") $ mk_bindist Xz -- TODO: Generate these targets as well - phony ("binary-dist-cross") $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz - phony ("binary-dist-stage3") $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz + phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" "" Xz + phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" "stage3-" Xz -- Prepare binary distribution configure script -- (generated under <ghc root>/distrib/configure by 'autoreconf') - root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do + root -/- "bindist" -/- "*ghc-*" -/- "configure" %> \configurePath -> do need ["distrib" -/- "configure.ac"] ghcRoot <- topDirectory copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4") @@ -372,7 +371,7 @@ bindistRules = do moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath -- Generate the Makefile that enables the "make install" part - root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do + root -/- "bindist" -/- "*ghc-*" -/- "Makefile" %> \makefilePath -> do top <- topDirectory copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath @@ -381,7 +380,7 @@ bindistRules = do -- (see the list of files needed in the 'binary-dist' rule above, before -- creating the archive). forM_ bindistInstallFiles $ \file -> - root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do + root -/- "bindist" -/- "*ghc-*" -/- file %> \dest -> do copyFile (fixup file) dest where @@ -466,7 +465,7 @@ pkgToWrappers stage pkg = do -- These are the packages which we want to expose to the user and hence -- there are wrappers installed in the bindist. | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg] - -> (:[]) <$> (programName =<< programContext Stage1 pkg) + -> (:[]) <$> (programName =<< programContext stage pkg) | otherwise -> pure [] wrapper :: Stage -> FilePath -> Action String ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -417,9 +417,15 @@ bindistRules = do templateRule ("distrib" -/- "configure.ac") $ mconcat [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion , interpolateVar "CrossCompilePrefix" $ do - crossCompiling <- interp $ getFlag CrossCompiling - tpf <- setting TargetPlatformFull - pure $ if crossCompiling then tpf <> "-" else "" + -- For a bindist, the prefix is needed only if the distributed compiler + -- is a cross-compiler (i.e., host != target in the bindist). + -- For Stage3 bindist (isStage3Cross=True), both host and target are the + -- target platform, so no prefix. For cross-compiler bindist (Stage1), + -- host != target, so we add the prefix. + -- Note: This template is shared by all bindist types, evaluated in Stage2 context. + host <- ifM isStage3Cross (setting TargetPlatformFull) (setting HostPlatformFull) + target <- setting TargetPlatformFull + pure $ if host /= target then target <> "-" else "" , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget tgtSymbolsHaveLeadingUnderscore , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion , interpolateSetting "LlvmMinVersion" LlvmMinVersion @@ -429,8 +435,8 @@ bindistRules = do , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode , interpolateVar "TargetHasLibm" $ yesNo <$> interp (staged (buildFlag TargetHasLibm)) , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple - , interpolateVar "BuildPlatform" $ interp $ queryBuild targetPlatformTriple - , interpolateVar "HostPlatform" $ interp $ queryHost targetPlatformTriple + , interpolateVar "BuildPlatform" $ ifM isStage3Cross (getTarget targetPlatformTriple) (interp $ queryBuild targetPlatformTriple) + , interpolateVar "HostPlatform" $ ifM isStage3Cross (getTarget targetPlatformTriple) (interp $ queryHost targetPlatformTriple) , interpolateVar "TargetWordBigEndian" $ getTarget isBigEndian , interpolateVar "TargetWordSize" $ getTarget wordSize , interpolateVar "Unregisterised" $ yesNo <$> getTarget tgtUnregisterised @@ -439,13 +445,19 @@ bindistRules = do , interpolateVar "BaseUnitId" $ pkgUnitId Stage1 base , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP Stage2 , interpolateVar "TargetPlatformFull" (setting TargetPlatformFull) - , interpolateVar "BuildPlatformFull" (setting BuildPlatformFull) - , interpolateVar "HostPlatformFull" (setting HostPlatformFull) + , interpolateVar "BuildPlatformFull" $ ifM isStage3Cross (setting TargetPlatformFull) (setting BuildPlatformFull) + , interpolateVar "HostPlatformFull" $ ifM isStage3Cross (setting TargetPlatformFull) (setting HostPlatformFull) ] where interp = interpretInContext (semiEmptyTarget Stage2) getTarget = interp . queryTarget Stage2 + -- TODO: This is a hack. It should be covered by config files + isStage3Cross = do + crossCompiling <- interp $ getFlag CrossCompiling + stage <- interp getStage + pure $ if crossCompiling && stage >= Stage2 then True else False + -- | Given a 'String' replace characters '.' and '-' by underscores ('_') so that -- the resulting 'String' is a valid C preprocessor identifier. cppify :: String -> String ===================================== validate-riscv-bindist.sh ===================================== @@ -0,0 +1,184 @@ +#!/usr/bin/env bash +# Script to validate that only RISC-V binaries, libraries, and target strings +# are present in _build/bindist/stage3-* directories + +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +ERRORS=0 +WARNINGS=0 + +echo "=== RISC-V Bindist Validation Script ===" +echo "" + +# Find all stage3-* directories +STAGE3_DIRS=$(find _build/bindist -maxdepth 1 -name "stage3-*" -type d 2>/dev/null || true) + +if [ -z "$STAGE3_DIRS" ]; then + echo -e "${YELLOW}Warning: No stage3-* directories found in _build/bindist/${NC}" + exit 1 +fi + +echo "Found stage3 directories:" +echo "$STAGE3_DIRS" +echo "" + +# Function to check if a file is a RISC-V binary/library +check_binary_arch() { + local file="$1" + + # Skip non-binary files + if ! file "$file" | grep -qE "ELF|archive"; then + return 0 + fi + + # Check architecture + local arch_info=$(file "$file") + + if echo "$arch_info" | grep -qE "RISC-V|riscv"; then + return 0 + else + echo -e "${RED}ERROR: Non-RISC-V binary/library found:${NC}" + echo " File: $file" + echo " Arch: $arch_info" + echo "" + return 1 + fi +} + +# Function to check target strings in text files +check_target_strings() { + local file="$1" + + # Skip if file is not readable or is a directory + if [ ! -f "$file" ] || [ ! -r "$file" ]; then + return 0 + fi + + # Skip binary files (ELF binaries and archives) + if file "$file" | grep -qE "ELF|archive"; then + return 0 + fi + + # Look for common non-RISC-V target patterns (case insensitive) + # Common architectures to check for: x86_64, aarch64, arm, i386, i686, powerpc, etc. + # Also check for build/host alias variables + local bad_patterns=( + "build_alias=.*x86_64" + "build_alias=.*aarch64" + "build_alias=.*i386" + "build_alias=.*i686" + "host_alias=.*x86_64" + "host_alias=.*aarch64" + "host_alias=.*i386" + "host_alias=.*i686" + "bootstrap_build=.*x86_64" + "bootstrap_build=.*aarch64" + "bootstrap_build=.*i386" + "bootstrap_build=.*i686" + "bootstrap_host=.*x86_64" + "bootstrap_host=.*aarch64" + "bootstrap_host=.*i386" + "bootstrap_host=.*i686" + ) + + local found_bad=0 + for pattern in "${bad_patterns[@]}"; do + if grep -qiE "$pattern" "$file" 2>/dev/null; then + if [ $found_bad -eq 0 ]; then + echo -e "${RED}ERROR: Non-RISC-V target string found in:${NC}" + echo " File: $file" + found_bad=1 + fi + echo " Pattern: $pattern" + # Show context (up to 3 lines) + grep -niE "$pattern" "$file" | head -3 | sed 's/^/ /' + fi + done + + if [ $found_bad -eq 1 ]; then + echo "" + return 1 + fi + + return 0 +} + +# Function to check for RISC-V references (informational) +check_riscv_presence() { + local file="$1" + + # Skip binary files for this check + if file "$file" | grep -qE "ELF|archive|executable"; then + return 0 + fi + + if [ ! -f "$file" ] || [ ! -r "$file" ]; then + return 0 + fi + + # Check if it's a text file + if ! file "$file" | grep -qE "text|ASCII|UTF-8|script"; then + return 0 + fi + + # Look for RISC-V patterns + if grep -qiE "riscv|risc-v" "$file" 2>/dev/null; then + return 0 + fi + + return 1 +} + +echo "=== Checking binaries and libraries for architecture ===" +echo "" + +for dir in $STAGE3_DIRS; do + echo "Scanning: $dir" + + # Find all ELF binaries and archives + while IFS= read -r -d '' file; do + if ! check_binary_arch "$file"; then + ((ERRORS++)) + fi + done < <(find "$dir" -type f -executable -print0 2>/dev/null) + + # Also check .a and .so files + while IFS= read -r -d '' file; do + if ! check_binary_arch "$file"; then + ((ERRORS++)) + fi + done < <(find "$dir" -type f \( -name "*.a" -o -name "*.so" -o -name "*.so.*" \) -print0 2>/dev/null) +done + +echo "" +echo "=== Checking text files for non-RISC-V target strings ===" +echo "" + +for dir in $STAGE3_DIRS; do + echo "Scanning: $dir" + + # Check common configuration and script files + while IFS= read -r -d '' file; do + if ! check_target_strings "$file"; then + ((ERRORS++)) + fi + done < <(find "$dir" -type f \( -name "*.conf" -o -name "*.config" -o -name "*.sh" -o -name "*.txt" -o -name "*.cabal" -o -name "*.mk" -o -name "Makefile" -o -name "configure" \) -print0 2>/dev/null) +done + +echo "" +echo "=== Summary ===" +echo "" + +if [ $ERRORS -eq 0 ]; then + echo -e "${GREEN}✓ All checks passed! Only RISC-V binaries/libraries and target strings found.${NC}" + exit 0 +else + echo -e "${RED}✗ Found $ERRORS error(s)${NC}" + echo -e "${RED}Non-RISC-V content detected in stage3 bindist directories!${NC}" + exit 1 +fi View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/251862dcf6e7ad8ace5a7626bd0d3cd... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/251862dcf6e7ad8ace5a7626bd0d3cd... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Sven Tennie (@supersven)