Sven Tennie pushed to branch wip/supersven/hadrian-cross-stage3 at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • hadrian/src/Rules/BinaryDist.hs
    ... ... @@ -122,8 +122,8 @@ installTo relocatable prefix = do
    122 122
         runBuilderWithCmdOptions env (Make bindistFilesDir) ["install"] [] []
    
    123 123
     
    
    124 124
     
    
    125
    -buildBinDistDir :: FilePath -> BindistConfig -> Action ()
    
    126
    -buildBinDistDir root conf@BindistConfig{..} = do
    
    125
    +buildBinDistDir :: FilePath -> FilePath -> BindistConfig -> Action ()
    
    126
    +buildBinDistDir dirPrefix root conf@BindistConfig{..} = do
    
    127 127
     
    
    128 128
         verbosity <- getVerbosity
    
    129 129
         -- We 'need' all binaries and libraries
    
    ... ... @@ -153,7 +153,7 @@ buildBinDistDir root conf@BindistConfig{..} = do
    153 153
         distDir        <- Context.distDir (vanillaContext library_stage rts)
    
    154 154
     
    
    155 155
         let ghcBuildDir      = root -/- stageString library_stage
    
    156
    -        bindistFilesDir  = root -/- "bindist" -/- ghcVersionPretty
    
    156
    +        bindistFilesDir  = root -/- "bindist" -/- dirPrefix <> ghcVersionPretty
    
    157 157
             ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    158 158
             rtsIncludeDir    = distDir -/- "include"
    
    159 159
     
    
    ... ... @@ -223,8 +223,7 @@ buildBinDistDir root conf@BindistConfig{..} = do
    223 223
         -- N.B. the ghc-pkg executable may be prefixed with a target triple
    
    224 224
         -- (c.f. #20267).
    
    225 225
     
    
    226
    -    -- Not going to work for cross
    
    227
    -    ghcPkgName <- programName (vanillaContext Stage1 ghcPkg)
    
    226
    +    ghcPkgName <- programName (vanillaContext executable_stage ghcPkg)
    
    228 227
         cmd_ (bindistFilesDir -/- "bin" -/- ghcPkgName) ["recache", "--package-db", bindistFilesDir -/- "lib" -/- "package.conf.d" ]
    
    229 228
     
    
    230 229
     
    
    ... ... @@ -316,27 +315,27 @@ bindistRules = do
    316 315
     
    
    317 316
         phony "binary-dist-dir" $ do
    
    318 317
           cfg <- implicitBindistConfig
    
    319
    -      buildBinDistDir root cfg
    
    318
    +      buildBinDistDir "" root cfg
    
    320 319
     
    
    321
    -    phony "binary-dist-dir-cross" $ buildBinDistDir root crossBindist
    
    320
    +    phony "binary-dist-dir-cross" $ buildBinDistDir "" root crossBindist
    
    322 321
     
    
    323
    -    phony "binary-dist-dir-stage3" $ buildBinDistDir root targetBindist
    
    322
    +    phony "binary-dist-dir-stage3" $ buildBinDistDir "stage3-" root targetBindist
    
    324 323
     
    
    325 324
         let buildBinDist compressor = do
    
    326 325
               win_host <- isWinHost
    
    327 326
               win_target <- isWinTarget Stage2
    
    328 327
               when (win_target && win_host) (error "normal binary-dist does not work for windows targets, use `reloc-binary-dist-*` target instead.")
    
    329
    -          buildBinDistX "binary-dist-dir" "bindist" compressor
    
    330
    -        buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist"
    
    328
    +          buildBinDistX "binary-dist-dir" "bindist" "" compressor
    
    329
    +        buildBinDistReloc = buildBinDistX "reloc-binary-dist-dir" "reloc-bindist" ""
    
    331 330
     
    
    332
    -        buildBinDistX :: String -> FilePath -> Compressor -> Action ()
    
    333
    -        buildBinDistX target bindist_folder compressor = do
    
    331
    +        buildBinDistX :: String -> FilePath -> FilePath -> Compressor -> Action ()
    
    332
    +        buildBinDistX target bindist_folder dirPrefix compressor = do
    
    334 333
                 need [target]
    
    335 334
     
    
    336 335
                 version        <- setting ProjectVersion
    
    337 336
                 targetPlatform <- setting TargetPlatformFull
    
    338 337
     
    
    339
    -            let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform
    
    338
    +            let ghcVersionPretty = dirPrefix <> "ghc-" ++ version ++ "-" ++ targetPlatform
    
    340 339
     
    
    341 340
                 -- Finally, we create the archive <root>/bindist/ghc-X.Y.Z-platform.tar.xz
    
    342 341
                 tarPath <- builderPath (Tar Create)
    
    ... ... @@ -352,12 +351,12 @@ bindistRules = do
    352 351
           phony (name <> "-dist-xz") $ mk_bindist Xz
    
    353 352
     
    
    354 353
         -- TODO: Generate these targets as well
    
    355
    -    phony ("binary-dist-cross") $ buildBinDistX "binary-dist-dir-cross" "bindist" Xz
    
    356
    -    phony ("binary-dist-stage3") $ buildBinDistX "binary-dist-dir-stage3" "bindist" Xz
    
    354
    +    phony "binary-dist-cross" $ buildBinDistX "binary-dist-dir-cross" "bindist" "" Xz
    
    355
    +    phony "binary-dist-stage3" $ buildBinDistX "binary-dist-dir-stage3" "bindist" "stage3-" Xz
    
    357 356
     
    
    358 357
         -- Prepare binary distribution configure script
    
    359 358
         -- (generated under <ghc root>/distrib/configure by 'autoreconf')
    
    360
    -    root -/- "bindist" -/- "ghc-*" -/- "configure" %> \configurePath -> do
    
    359
    +    root -/- "bindist" -/- "*ghc-*" -/- "configure" %> \configurePath -> do
    
    361 360
             need ["distrib" -/- "configure.ac"]
    
    362 361
             ghcRoot <- topDirectory
    
    363 362
             copyFile (ghcRoot -/- "aclocal.m4") (ghcRoot -/- "distrib" -/- "aclocal.m4")
    
    ... ... @@ -372,7 +371,7 @@ bindistRules = do
    372 371
             moveFile (ghcRoot -/- "distrib" -/- "configure") configurePath
    
    373 372
     
    
    374 373
         -- Generate the Makefile that enables the "make install" part
    
    375
    -    root -/- "bindist" -/- "ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    374
    +    root -/- "bindist" -/- "*ghc-*" -/- "Makefile" %> \makefilePath -> do
    
    376 375
             top <- topDirectory
    
    377 376
             copyFile (top -/- "hadrian" -/- "bindist" -/- "Makefile") makefilePath
    
    378 377
     
    
    ... ... @@ -381,7 +380,7 @@ bindistRules = do
    381 380
         -- (see the list of files needed in the 'binary-dist' rule above, before
    
    382 381
         -- creating the archive).
    
    383 382
         forM_ bindistInstallFiles $ \file ->
    
    384
    -        root -/- "bindist" -/- "ghc-*" -/- file %> \dest -> do
    
    383
    +        root -/- "bindist" -/- "*ghc-*" -/- file %> \dest -> do
    
    385 384
                 copyFile (fixup file) dest
    
    386 385
     
    
    387 386
       where
    
    ... ... @@ -466,7 +465,7 @@ pkgToWrappers stage pkg = do
    466 465
             -- These are the packages which we want to expose to the user and hence
    
    467 466
             -- there are wrappers installed in the bindist.
    
    468 467
           | pkg `elem` [hpcBin, haddock, hp2ps, hsc2hs, ghc, ghcPkg]
    
    469
    -                      -> (:[]) <$> (programName =<< programContext Stage1 pkg)
    
    468
    +                      -> (:[]) <$> (programName =<< programContext stage pkg)
    
    470 469
           | otherwise     -> pure []
    
    471 470
     
    
    472 471
     wrapper :: Stage -> FilePath -> Action String
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -417,9 +417,15 @@ bindistRules = do
    417 417
       templateRule ("distrib" -/- "configure.ac") $ mconcat
    
    418 418
         [ interpolateSetting "ConfiguredEmsdkVersion" EmsdkVersion
    
    419 419
         , interpolateVar "CrossCompilePrefix" $ do
    
    420
    -        crossCompiling <- interp $ getFlag CrossCompiling
    
    421
    -        tpf <- setting TargetPlatformFull
    
    422
    -        pure $ if crossCompiling then tpf <> "-" else ""
    
    420
    +        -- For a bindist, the prefix is needed only if the distributed compiler
    
    421
    +        -- is a cross-compiler (i.e., host != target in the bindist).
    
    422
    +        -- For Stage3 bindist (isStage3Cross=True), both host and target are the
    
    423
    +        -- target platform, so no prefix. For cross-compiler bindist (Stage1),
    
    424
    +        -- host != target, so we add the prefix.
    
    425
    +        -- Note: This template is shared by all bindist types, evaluated in Stage2 context.
    
    426
    +        host <- ifM isStage3Cross (setting TargetPlatformFull) (setting HostPlatformFull)
    
    427
    +        target <- setting TargetPlatformFull
    
    428
    +        pure $ if host /= target then target <> "-" else ""
    
    423 429
         , interpolateVar "LeadingUnderscore" $ yesNo <$> getTarget tgtSymbolsHaveLeadingUnderscore
    
    424 430
         , interpolateSetting "LlvmMaxVersion" LlvmMaxVersion
    
    425 431
         , interpolateSetting "LlvmMinVersion" LlvmMinVersion
    
    ... ... @@ -429,8 +435,8 @@ bindistRules = do
    429 435
         , interpolateVar "TablesNextToCode" $ yesNo <$> getTarget tgtTablesNextToCode
    
    430 436
         , interpolateVar "TargetHasLibm" $ yesNo <$> interp (staged (buildFlag TargetHasLibm))
    
    431 437
         , interpolateVar "TargetPlatform" $ getTarget targetPlatformTriple
    
    432
    -    , interpolateVar "BuildPlatform"  $ interp $ queryBuild targetPlatformTriple
    
    433
    -    , interpolateVar "HostPlatform"   $ interp $ queryHost targetPlatformTriple
    
    438
    +    , interpolateVar "BuildPlatform"  $ ifM isStage3Cross (getTarget targetPlatformTriple) (interp $ queryBuild targetPlatformTriple)
    
    439
    +    , interpolateVar "HostPlatform"   $ ifM isStage3Cross (getTarget targetPlatformTriple) (interp $ queryHost targetPlatformTriple)
    
    434 440
         , interpolateVar "TargetWordBigEndian" $ getTarget isBigEndian
    
    435 441
         , interpolateVar "TargetWordSize" $ getTarget wordSize
    
    436 442
         , interpolateVar "Unregisterised" $ yesNo <$> getTarget tgtUnregisterised
    
    ... ... @@ -439,13 +445,19 @@ bindistRules = do
    439 445
         , interpolateVar "BaseUnitId" $ pkgUnitId Stage1 base
    
    440 446
         , interpolateVar "GhcWithSMP" $ yesNo <$> targetSupportsSMP Stage2
    
    441 447
         , interpolateVar "TargetPlatformFull" (setting TargetPlatformFull)
    
    442
    -    , interpolateVar "BuildPlatformFull" (setting BuildPlatformFull)
    
    443
    -    , interpolateVar "HostPlatformFull"  (setting HostPlatformFull)
    
    448
    +    , interpolateVar "BuildPlatformFull" $ ifM isStage3Cross (setting TargetPlatformFull) (setting BuildPlatformFull)
    
    449
    +    , interpolateVar "HostPlatformFull" $ ifM isStage3Cross (setting TargetPlatformFull) (setting HostPlatformFull)
    
    444 450
         ]
    
    445 451
       where
    
    446 452
         interp = interpretInContext (semiEmptyTarget Stage2)
    
    447 453
         getTarget = interp . queryTarget Stage2
    
    448 454
     
    
    455
    +    -- TODO: This is a hack. It should be covered by config files
    
    456
    +    isStage3Cross = do
    
    457
    +        crossCompiling <- interp $ getFlag CrossCompiling
    
    458
    +        stage <- interp getStage
    
    459
    +        pure $ if crossCompiling && stage >= Stage2 then True else False
    
    460
    +
    
    449 461
     -- | Given a 'String' replace characters '.' and '-' by underscores ('_') so that
    
    450 462
     -- the resulting 'String' is a valid C preprocessor identifier.
    
    451 463
     cppify :: String -> String
    

  • validate-riscv-bindist.sh
    1
    +#!/usr/bin/env bash
    
    2
    +# Script to validate that only RISC-V binaries, libraries, and target strings
    
    3
    +# are present in _build/bindist/stage3-* directories
    
    4
    +
    
    5
    +set -e
    
    6
    +
    
    7
    +RED='\033[0;31m'
    
    8
    +GREEN='\033[0;32m'
    
    9
    +YELLOW='\033[1;33m'
    
    10
    +NC='\033[0m' # No Color
    
    11
    +
    
    12
    +ERRORS=0
    
    13
    +WARNINGS=0
    
    14
    +
    
    15
    +echo "=== RISC-V Bindist Validation Script ==="
    
    16
    +echo ""
    
    17
    +
    
    18
    +# Find all stage3-* directories
    
    19
    +STAGE3_DIRS=$(find _build/bindist -maxdepth 1 -name "stage3-*" -type d 2>/dev/null || true)
    
    20
    +
    
    21
    +if [ -z "$STAGE3_DIRS" ]; then
    
    22
    +    echo -e "${YELLOW}Warning: No stage3-* directories found in _build/bindist/${NC}"
    
    23
    +    exit 1
    
    24
    +fi
    
    25
    +
    
    26
    +echo "Found stage3 directories:"
    
    27
    +echo "$STAGE3_DIRS"
    
    28
    +echo ""
    
    29
    +
    
    30
    +# Function to check if a file is a RISC-V binary/library
    
    31
    +check_binary_arch() {
    
    32
    +    local file="$1"
    
    33
    +    
    
    34
    +    # Skip non-binary files
    
    35
    +    if ! file "$file" | grep -qE "ELF|archive"; then
    
    36
    +        return 0
    
    37
    +    fi
    
    38
    +    
    
    39
    +    # Check architecture
    
    40
    +    local arch_info=$(file "$file")
    
    41
    +    
    
    42
    +    if echo "$arch_info" | grep -qE "RISC-V|riscv"; then
    
    43
    +        return 0
    
    44
    +    else
    
    45
    +        echo -e "${RED}ERROR: Non-RISC-V binary/library found:${NC}"
    
    46
    +        echo "  File: $file"
    
    47
    +        echo "  Arch: $arch_info"
    
    48
    +        echo ""
    
    49
    +        return 1
    
    50
    +    fi
    
    51
    +}
    
    52
    +
    
    53
    +# Function to check target strings in text files
    
    54
    +check_target_strings() {
    
    55
    +    local file="$1"
    
    56
    +    
    
    57
    +    # Skip if file is not readable or is a directory
    
    58
    +    if [ ! -f "$file" ] || [ ! -r "$file" ]; then
    
    59
    +        return 0
    
    60
    +    fi
    
    61
    +    
    
    62
    +    # Skip binary files (ELF binaries and archives)
    
    63
    +    if file "$file" | grep -qE "ELF|archive"; then
    
    64
    +        return 0
    
    65
    +    fi
    
    66
    +    
    
    67
    +    # Look for common non-RISC-V target patterns (case insensitive)
    
    68
    +    # Common architectures to check for: x86_64, aarch64, arm, i386, i686, powerpc, etc.
    
    69
    +    # Also check for build/host alias variables
    
    70
    +    local bad_patterns=(
    
    71
    +        "build_alias=.*x86_64"
    
    72
    +        "build_alias=.*aarch64"
    
    73
    +        "build_alias=.*i386"
    
    74
    +        "build_alias=.*i686"
    
    75
    +        "host_alias=.*x86_64"
    
    76
    +        "host_alias=.*aarch64"
    
    77
    +        "host_alias=.*i386"
    
    78
    +        "host_alias=.*i686"
    
    79
    +        "bootstrap_build=.*x86_64"
    
    80
    +        "bootstrap_build=.*aarch64"
    
    81
    +        "bootstrap_build=.*i386"
    
    82
    +        "bootstrap_build=.*i686"
    
    83
    +        "bootstrap_host=.*x86_64"
    
    84
    +        "bootstrap_host=.*aarch64"
    
    85
    +        "bootstrap_host=.*i386"
    
    86
    +        "bootstrap_host=.*i686"
    
    87
    +    )
    
    88
    +    
    
    89
    +    local found_bad=0
    
    90
    +    for pattern in "${bad_patterns[@]}"; do
    
    91
    +        if grep -qiE "$pattern" "$file" 2>/dev/null; then
    
    92
    +            if [ $found_bad -eq 0 ]; then
    
    93
    +                echo -e "${RED}ERROR: Non-RISC-V target string found in:${NC}"
    
    94
    +                echo "  File: $file"
    
    95
    +                found_bad=1
    
    96
    +            fi
    
    97
    +            echo "  Pattern: $pattern"
    
    98
    +            # Show context (up to 3 lines)
    
    99
    +            grep -niE "$pattern" "$file" | head -3 | sed 's/^/    /'
    
    100
    +        fi
    
    101
    +    done
    
    102
    +    
    
    103
    +    if [ $found_bad -eq 1 ]; then
    
    104
    +        echo ""
    
    105
    +        return 1
    
    106
    +    fi
    
    107
    +    
    
    108
    +    return 0
    
    109
    +}
    
    110
    +
    
    111
    +# Function to check for RISC-V references (informational)
    
    112
    +check_riscv_presence() {
    
    113
    +    local file="$1"
    
    114
    +    
    
    115
    +    # Skip binary files for this check
    
    116
    +    if file "$file" | grep -qE "ELF|archive|executable"; then
    
    117
    +        return 0
    
    118
    +    fi
    
    119
    +    
    
    120
    +    if [ ! -f "$file" ] || [ ! -r "$file" ]; then
    
    121
    +        return 0
    
    122
    +    fi
    
    123
    +    
    
    124
    +    # Check if it's a text file
    
    125
    +    if ! file "$file" | grep -qE "text|ASCII|UTF-8|script"; then
    
    126
    +        return 0
    
    127
    +    fi
    
    128
    +    
    
    129
    +    # Look for RISC-V patterns
    
    130
    +    if grep -qiE "riscv|risc-v" "$file" 2>/dev/null; then
    
    131
    +        return 0
    
    132
    +    fi
    
    133
    +    
    
    134
    +    return 1
    
    135
    +}
    
    136
    +
    
    137
    +echo "=== Checking binaries and libraries for architecture ==="
    
    138
    +echo ""
    
    139
    +
    
    140
    +for dir in $STAGE3_DIRS; do
    
    141
    +    echo "Scanning: $dir"
    
    142
    +    
    
    143
    +    # Find all ELF binaries and archives
    
    144
    +    while IFS= read -r -d '' file; do
    
    145
    +        if ! check_binary_arch "$file"; then
    
    146
    +            ((ERRORS++))
    
    147
    +        fi
    
    148
    +    done < <(find "$dir" -type f -executable -print0 2>/dev/null)
    
    149
    +    
    
    150
    +    # Also check .a and .so files
    
    151
    +    while IFS= read -r -d '' file; do
    
    152
    +        if ! check_binary_arch "$file"; then
    
    153
    +            ((ERRORS++))
    
    154
    +        fi
    
    155
    +    done < <(find "$dir" -type f \( -name "*.a" -o -name "*.so" -o -name "*.so.*" \) -print0 2>/dev/null)
    
    156
    +done
    
    157
    +
    
    158
    +echo ""
    
    159
    +echo "=== Checking text files for non-RISC-V target strings ==="
    
    160
    +echo ""
    
    161
    +
    
    162
    +for dir in $STAGE3_DIRS; do
    
    163
    +    echo "Scanning: $dir"
    
    164
    +    
    
    165
    +    # Check common configuration and script files
    
    166
    +    while IFS= read -r -d '' file; do
    
    167
    +        if ! check_target_strings "$file"; then
    
    168
    +            ((ERRORS++))
    
    169
    +        fi
    
    170
    +    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)
    
    171
    +done
    
    172
    +
    
    173
    +echo ""
    
    174
    +echo "=== Summary ==="
    
    175
    +echo ""
    
    176
    +
    
    177
    +if [ $ERRORS -eq 0 ]; then
    
    178
    +    echo -e "${GREEN}โœ“ All checks passed! Only RISC-V binaries/libraries and target strings found.${NC}"
    
    179
    +    exit 0
    
    180
    +else
    
    181
    +    echo -e "${RED}โœ— Found $ERRORS error(s)${NC}"
    
    182
    +    echo -e "${RED}Non-RISC-V content detected in stage3 bindist directories!${NC}"
    
    183
    +    exit 1
    
    184
    +fi