about summary refs log tree commit diff
path: root/pkgs/build-support/dotnet/build-dotnet-module/hooks/dotnet-configure-hook.sh
blob: 12fa348699865f6aad8db00b110d16b4917e89f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
dotnetConfigureHook() {
    echo "Executing dotnetConfigureHook"

    runHook preConfigure

    if [[ -z ${nugetSource-} ]]; then
        echo
        echo "ERROR: no dependencies were specified"
        echo 'Hint: set `nugetSource` if using these hooks individually. If this is happening with `buildDotnetModule`, please open an issue.'
        echo

        exit 1
    fi

    local nugetSourceSedQuoted="${nugetSource//[\/\\&$'\n']/\\&}"
    local nugetSourceXMLQuoted="$nugetSource"
    nugetSourceXMLQuoted="${nugetSource//&/\&}"
    nugetSourceXMLQuoted="${nugetSourceXMLQuoted//\"/\"}"

    local -r hostRuntimeId=@runtimeId@
    local -r dynamicLinker=@dynamicLinker@
    local -r libPath=@libPath@
    local -r dotnetRuntimeId="${dotnetRuntimeId-$hostRuntimeId}"

    if [[ -n $__structuredAttrs ]]; then
        local dotnetProjectFilesArray=( "${dotnetProjectFiles[@]}" )
        local dotnetTestProjectFilesArray=( "${dotnetTestProjectFiles[@]}" )
        local dotnetFlagsArray=( "${dotnetFlags[@]}" )
        local dotnetRestoreFlagsArray=( "${dotnetRestoreFlags[@]}" )
    else
        local dotnetProjectFilesArray=($dotnetProjectFiles)
        local dotnetTestProjectFilesArray=($dotnetTestProjectFiles)
        local dotnetFlagsArray=($dotnetFlags)
        local dotnetRestoreFlagsArray=($dotnetRestoreFlags)
    fi

    if [[ -z ${enableParallelBuilding-} ]]; then
        local -r parallelFlag="--disable-parallel"
    fi

    dotnetRestore() {
        local -r projectFile="${1-}"
        dotnet restore ${1+"$projectFile"} \
            -p:ContinuousIntegrationBuild=true \
            -p:Deterministic=true \
            --runtime "$dotnetRuntimeId" \
            --source "$nugetSource/lib" \
            ${parallelFlag-} \
            "${dotnetRestoreFlagsArray[@]}" \
            "${dotnetFlagsArray[@]}"
    }

    # Generate a NuGet.config file to make sure everything,
    # including things like <Sdk /> dependencies, is restored from the proper source
    cat >NuGet.config <<EOF
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="nugetSource" value="$nugetSourceXMLQuoted/lib" />
  </packageSources>
</configuration>
EOF

    # Patch paket.dependencies and paket.lock (if found) to use the proper
    # source. This ensures paket restore works correctly. Note that the
    # nugetSourceSedQuoted abomination below safely escapes nugetSource string
    # for use as a sed replacement string to avoid issues with slashes and other
    # special characters ('&', '\\' and '\n').
    find -name paket.dependencies -exec sed -i "s/source .*/source $nugetSourceSedQuoted\/lib/g" {} \;
    find -name paket.lock -exec sed -i "s/remote:.*/remote: $nugetSourceSedQuoted\/lib/g" {} \;

    dotnet tool restore --add-source "$nugetSource/lib"

    # dotnetGlobalTool is set in buildDotnetGlobalTool to patch dependencies but
    # avoid other project-specific logic. This is a hack, but the old behavior
    # is worse as it relied on a bug: setting projectFile to an empty string
    # made the hooks actually skip all project-specific logic. It’s hard to keep
    # backwards compatibility with this odd behavior now since we are using
    # arrays, so instead we just pass a variable to indicate that we don’t have
    # projects.
    if [[ -z ${dotnetGlobalTool-} ]]; then
        if (( ${#dotnetProjectFilesArray[@]} == 0 )); then
            dotnetRestore
        fi

        local projectFile
        for projectFile in "${dotnetProjectFilesArray[@]}" "${dotnetTestProjectFilesArray[@]}"; do
            dotnetRestore "$projectFile"
        done
    fi

    echo "Fixing up native binaries..."
    # Find all native binaries and nuget libraries, and fix them up,
    # by setting the proper interpreter and rpath to some commonly used libraries
    local binary
    for binary in $(find "$HOME/.nuget/packages/" -type f -executable); do
        if patchelf --print-interpreter "$binary" >/dev/null 2>/dev/null; then
            echo "Found binary: $binary, fixing it up..."
            patchelf --set-interpreter "$(cat "$dynamicLinker")" "$binary"

            # This makes sure that if the binary requires some specific runtime dependencies, it can find it.
            # This fixes dotnet-built binaries like crossgen2
            patchelf \
                --add-needed libicui18n.so \
                --add-needed libicuuc.so \
                --add-needed libz.so \
                --add-needed libssl.so \
                "$binary"

            patchelf --set-rpath "$libPath" "$binary"
        fi
    done

    runHook postConfigure

    echo "Finished dotnetConfigureHook"
}

if [[ -z "${dontDotnetConfigure-}" && -z "${configurePhase-}" ]]; then
    configurePhase=dotnetConfigureHook
fi