diff --git a/pkgs/build-support/go/module.nix b/pkgs/build-support/go/module.nix index 30542b1d16c6..ce699c213454 100644 --- a/pkgs/build-support/go/module.nix +++ b/pkgs/build-support/go/module.nix @@ -253,6 +253,9 @@ lib.extendMkDerivation { if [ -f "$NIX_CC_FOR_TARGET/nix-support/dynamic-linker" ]; then export GO_LDSO=$(cat $NIX_CC_FOR_TARGET/nix-support/dynamic-linker) fi + if [ "$CGO_ENABLED" = "0" ]; then + export GOFLAGS="-buildmode=exe $GOFLAGS" + fi cd "$modRoot" '' + lib.optionalString (finalAttrs.vendorHash != null) '' diff --git a/pkgs/development/compilers/go/1.24.nix b/pkgs/development/compilers/go/1.24.nix index 17be8a607ec0..da57d07f7205 100644 --- a/pkgs/development/compilers/go/1.24.nix +++ b/pkgs/development/compilers/go/1.24.nix @@ -9,16 +9,13 @@ buildPackages, pkgsBuildTarget, targetPackages, - testers, - skopeo, buildGo124Module, + callPackage, }: let goBootstrap = buildPackages.callPackage ./bootstrap122.nix { }; - skopeoTest = skopeo.override { buildGoModule = buildGo124Module; }; - # We need a target compiler which is still runnable at build time, # to handle the cross-building case where build != host == target targetCC = pkgsBuildTarget.targetPackages.stdenv.cc; @@ -195,14 +192,10 @@ stdenv.mkDerivation (finalAttrs: { disallowedReferences = [ goBootstrap ]; passthru = { - inherit goBootstrap skopeoTest; - tests = { - skopeo = testers.testVersion { package = skopeoTest; }; - version = testers.testVersion { - package = finalAttrs.finalPackage; - command = "go version"; - version = "go${finalAttrs.version}"; - }; + inherit goBootstrap; + tests = callPackage ./tests.nix { + go = finalAttrs.finalPackage; + buildGoModule = buildGo124Module; }; }; diff --git a/pkgs/development/compilers/go/1.25.nix b/pkgs/development/compilers/go/1.25.nix index fcf12a2d82be..fc472c987040 100644 --- a/pkgs/development/compilers/go/1.25.nix +++ b/pkgs/development/compilers/go/1.25.nix @@ -10,20 +10,13 @@ pkgsBuildTarget, targetPackages, # for testing - testers, - runCommand, - bintools, - skopeo, - clickhouse-backup, buildGo125Module, + callPackage, }: let goBootstrap = buildPackages.callPackage ./bootstrap122.nix { }; - skopeoTest = skopeo.override { buildGoModule = buildGo125Module; }; - clickhouse-backupTest = clickhouse-backup.override { buildGoModule = buildGo125Module; }; - # We need a target compiler which is still runnable at build time, # to handle the cross-building case where build != host == target targetCC = pkgsBuildTarget.targetPackages.stdenv.cc; @@ -200,31 +193,10 @@ stdenv.mkDerivation (finalAttrs: { disallowedReferences = [ goBootstrap ]; passthru = { - inherit goBootstrap skopeoTest; - tests = { - skopeo = testers.testVersion { package = skopeoTest; }; - version = testers.testVersion { - package = finalAttrs.finalPackage; - command = "go version"; - version = "go${finalAttrs.version}"; - }; - # Picked clickhouse-backup as a package that sets CGO_ENABLED=0 - # Running and outputting the right version proves a working ELF interpreter was picked - clickhouse-backup = testers.testVersion { package = clickhouse-backupTest; }; - clickhouse-backup-is-pie = runCommand "has-pie" { meta.broken = stdenv.hostPlatform.isStatic; } '' - ${lib.optionalString (!isCross) '' - if ${lib.getExe' bintools "readelf"} -p .comment ${lib.getExe clickhouse-backup} | grep -Fq "GCC: (GNU)"; then - echo "${lib.getExe clickhouse-backup} has a GCC .comment, but it should have used the internal go linker" - exit 1 - fi - ''} - if ${lib.getExe' bintools "readelf"} -h ${lib.getExe clickhouse-backup} | grep -q "Type:.*DYN"; then - touch $out - else - echo "ERROR: clickhouse-backup is NOT PIE" - exit 1 - fi - ''; + inherit goBootstrap; + tests = callPackage ./tests.nix { + go = finalAttrs.finalPackage; + buildGoModule = buildGo125Module; }; }; diff --git a/pkgs/development/compilers/go/tests.nix b/pkgs/development/compilers/go/tests.nix new file mode 100644 index 000000000000..3eeaa8b53262 --- /dev/null +++ b/pkgs/development/compilers/go/tests.nix @@ -0,0 +1,61 @@ +{ + lib, + stdenv, + go, + buildGoModule, + # A package that relies on CGO + skopeo, + testers, + runCommand, + bintools, + # A package with CGO_ENABLED=0 + athens, +}: +let + skopeo' = skopeo.override { buildGoModule = buildGoModule; }; + athens' = athens.override { buildGoModule = buildGoModule; }; + expectedCgoEnabledType = "DYN"; + expectedCgoDisabledType = "EXE"; +in +{ + skopeo = testers.testVersion { package = skopeo'; }; + version = testers.testVersion { + package = go; + command = "go version"; + version = "go${go.version}"; + }; + athens = testers.testVersion { package = athens'; }; +} +# bin type tests assume ELF file + linux-specific exe types +// lib.optionalAttrs stdenv.hostPlatform.isLinux { + skopeo-bin-type = runCommand "skopeo-bin-type" { meta.broken = stdenv.hostPlatform.isStatic; } '' + bin="${lib.getExe' skopeo' ".skopeo-wrapped"}" + if ! ${lib.getExe' bintools "readelf"} -p .comment $bin | grep -Fq "GCC: (GNU)"; then + echo "${lib.getExe skopeo} should have been externally linked, but no GNU .comment section found" + exit 1 + fi + if ${lib.getExe' bintools "readelf"} -h $bin | grep -q "Type:.*${expectedCgoEnabledType}"; then + touch $out + else + echo "ERROR: $bin is NOT ${expectedCgoEnabledType}" + exit 1 + fi + ''; + athens-bin-type = runCommand "athens-bin-type" { meta.broken = stdenv.hostPlatform.isStatic; } '' + bin="${lib.getExe athens'}" + ${lib.optionalString (stdenv.buildPlatform == stdenv.targetPlatform) '' + # For CGO_ENABLED=0 the internal linker should be used, except + # for cross where we rely on external linking by default + if ${lib.getExe' bintools "readelf"} -p .comment ${lib.getExe athens'} | grep -Fq "GCC: (GNU)"; then + echo "${lib.getExe athens'} has a GCC .comment, but it should have used the internal go linker" + exit 1 + fi + ''} + if ${lib.getExe' bintools "readelf"} -h "$bin" | grep -q "Type:.*${expectedCgoDisabledType}"; then + touch $out + else + echo "ERROR: $bin is NOT ${expectedCgoDisabledType}" + exit 1 + fi + ''; +}