Skip to content

[ Linux ] (--build-system swiftbuild) : Unable to link test binary '/lib/aarch64-linux-gnu/Scrt1.o:function _start: error: undefined reference to 'main' #8439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 task done
kcieplak opened this issue Apr 1, 2025 · 4 comments
Labels
bug swift build Changes impacting `swift build`

Comments

@kcieplak
Copy link
Contributor

kcieplak commented Apr 1, 2025

Is it reproducible with SwiftPM command-line tools: swift build, swift test, swift package etc?

  • Confirmed reproduction steps with SwiftPM CLI. The description text must include reproduction steps with either of command-line SwiftPM commands, swift build, swift test, swift package etc.

Description

The test case 'packageInitLibrary' on Linux exposes a failure to link a test binary for execution.

info: Link fooTests.xctest (aarch64) cd /tmp/TemporaryDirectory.lVbW4O/foo /usr/bin/clang -target aarch64-unknown-linux-gnu --sysroot / -O0 -L/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/EagerLinkingTBDs/Debug-linux -L/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Products/Debug-linux -L/usr/lib @/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/foo.build/Debug-linux/fooTests.build/Objects-normal/aarch64/fooTests.LinkFileList -Xlinker -rpath -Xlinker @loader_path/Frameworks -Xlinker -rpath -Xlinker @loader_path/../Frameworks -rdynamic -lswiftCore -lswiftSwiftOnoneSupport -L/usr/lib/swift/linux -L/usr/lib/swift @/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/foo.build/Debug-linux/fooTests.build/Objects-normal/aarch64/fooTests.autolink -v -o /tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Products/Debug-linux/fooTests.xctest error: unknown Linker command failed with exit code 1 (use -v to see invocation) [] info: clang version 17.0.0 (https://github.com/swiftlang/llvm-project.git 22f70408f415ca696fb3e82936e8cc7c2e1d1de6) Target: aarch64-unknown-linux-gnu Thread model: posix InstalledDir: /usr/bin Build config: +assertions Found candidate GCC installation: //lib/gcc/aarch64-linux-gnu/11 Found candidate GCC installation: /lib/gcc/aarch64-linux-gnu/11 Selected GCC installation: /lib/gcc/aarch64-linux-gnu/11 Candidate multilib: .;@m64 Selected multilib: .;@m64 "/usr/bin/ld.gold" --sysroot=/ -EL -z relro --hash-style=gnu --eh-frame-hdr -m aarch64linux -export-dynamic -pie -dynamic-linker /lib/ld-linux-aarch64.so.1 -o /tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Products/Debug-linux/fooTests.xctest /lib/aarch64-linux-gnu/Scrt1.o /lib/aarch64-linux-gnu/crti.o /lib/gcc/aarch64-linux-gnu/11/crtbeginS.o -L/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/EagerLinkingTBDs/Debug-linux -L/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Products/Debug-linux -L/usr/lib -L/usr/lib/swift/linux -L/usr/lib/swift -L/lib/gcc/aarch64-linux-gnu/11 -L/lib/aarch64-linux-gnu -L/usr/lib/aarch64-linux-gnu -L/lib -L/usr/lib /tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/foo.build/Debug-linux/fooTests.build/Objects-normal/aarch64/Modules/fooTests.o /tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/foo.build/Debug-linux/fooTests.build/Objects-normal/aarch64/fooTests.o /tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Products/Debug-linux/foo_Module.o -rpath @loader_path/Frameworks -rpath @loader_path/../Frameworks -lswiftCore -lswiftSwiftOnoneSupport -lswiftSwiftOnoneSupport -lswiftCore -lswift_Concurrency -lswift_StringProcessing -lswift_RegexParser -lTesting -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /lib/gcc/aarch64-linux-gnu/11/crtendS.o /lib/aarch64-linux-gnu/crtn.o /lib/aarch64-linux-gnu/Scrt1.o:function _start: error: undefined reference to 'main' /lib/aarch64-linux-gnu/Scrt1.o:function _start: error: undefined reference to 'main' clang: error: linker command failed with exit code 1 (use -v to see invocation) error: Build failed error: fatalError

Expected behavior

Test binary links and is executable

Actual behavior

Fails to link with missing 'main'

Steps to reproduce

mkdir foo
cd foo
swift package init -- type library
swift test --build-system swift build --vv

Swift Package Manager version/commit hash

No response

Swift & OS version (output of swift --version ; uname -a)

No response

@kcieplak kcieplak added the bug label Apr 1, 2025
@kcieplak
Copy link
Contributor Author

kcieplak commented Apr 1, 2025

Looking at the native build system, a series of objects are directly linked in the call to the linker...

/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/foo.build/foo.swift.o
/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/foo.build/foo.swiftmodule.o
/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/fooPackageDiscoveredTests.build/all-discovered-tests.swift.o
/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/fooPackageDiscoveredTests.build/fooPackageDiscoveredTests.swiftmodule.o
/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/fooPackageDiscoveredTests.build/fooTests.swift.o
/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/fooPackageTests.build/fooPackageTests.swiftmodule.o
/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/fooPackageTests.build/runner.swift.o
/tmp/foo/.build/aarch64-unknown-linux-gnu/debug/fooTests.build/fooTests.swift.o

The runner.swift.o object contains the 'main' symbol.

nm /tmp/foo/.build/aarch64-unknown-linux-gnu/debug/fooPackageTests.build/runner.swift.o | grep main
0000000000000000 T $s15fooPackageTests6RunnerV4mainyyFZ
000000000000bfa8 t $s15fooPackageTests6RunnerV4mainyyFZyyYaYbcfU_
000000000000c098 t $s15fooPackageTests6RunnerV4mainyyFZyyYaYbcfU_TQ1_
000000000000c004 t $s15fooPackageTests6RunnerV4mainyyFZyyYaYbcfU_TY0_
0000000000000240 d $s15fooPackageTests6RunnerV4mainyyFZyyYaYbcfU_Tu
0000000000000000 T $s15fooPackageTests6RunnerV5$mainyyFZ
0000000000000000 T main

In the case for swiftbuild none of the directly linked objects have the 'main' symbol.

/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/foo.build/Debug-linux/fooTests.build/Objects-normal/aarch64/Modules/fooTests.o
/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Intermediates.noindex/foo.build/Debug-linux/fooTests.build/Objects-normal/aarch64/fooTests.o
/tmp/TemporaryDirectory.lVbW4O/foo/.build/aarch64-unknown-linux-gnu/Products/Debug-linux/foo_Module.o

The native build system builds a directly runnable binary, but swiftbuild is not. On macOS a test library is created that is executed using the swiftpm-testing-helper.

/Users/kcieplak/repos/swift-package-manager/.build/arm64-apple-macosx/debug/swiftpm-testing-helper --test-bundle-path /private/tmp/.build/arm64-apple-macosx/Products/Debug/tmpTests.xctest/Contents/MacOS/tmpTests --build-system swiftbuild --vv /private/tmp/.build/arm64-apple-macosx/Products/Debug/tmpTests.xctest/Contents/MacOS/tmpTests --testing-library swift-testing

@kcieplak
Copy link
Contributor Author

kcieplak commented Apr 1, 2025

Looking at the generated PIF a "com.apple.product-type.bundle.unit-test" target is being asked to be created.
Linux does not support "bundles". This is a macOS specific behaviour.

      },
      "name" : "fooTests_24A218193B660A5F_PackageProduct",
      "productReference" : {
        "guid" : "PRODUCTREF-PACKAGE-PRODUCT:fooTests",
        "name" : "fooTests",
        "type" : "file"
      },
      "productTypeIdentifier" : "com.apple.product-type.bundle.unit-test",
      "type" : "standard"
    },
    "signature" : "cb021b9bbc34175e5ccfe9377f3a7a9a03f9971fb8152860ac47f249f5840833",
    "type" : "target"

SwiftPM should likely create a directly executable test binary.

@bkhouri bkhouri added the swift build Changes impacting `swift build` label Apr 4, 2025
@cmcgee1024
Copy link
Member

The following tests are failing for because of this linker error with Linux.

  • TestCommandSwiftBuildTests.testSwiftTestXMLOutputVerifySingleTestFailureMessageWithFlagDisabledXCTest
  • TestCommandSwiftBuildTests.testSwiftTestXMLOutputVerifyMultipleTestFailureMessageWithFlagEnabledXCTest
  • TestCommandSwiftBuildTests.testSwiftTestXMLOutputVerifySingleTestFailureMessageWithFlagEnabledXCTest
  • TestCommandSwiftBuildTests.testSwiftTestXMLOutputVerifyMultipleTestFailureMessageWithFlagDisabledXCTest

@cmcgee1024
Copy link
Member

There is a swift-build fix that at least partially address this issue: See swiftlang/swift-build#390

cmcgee1024 added a commit that referenced this issue Apr 14, 2025
The TestCommandTests fail on Linux due to a common linker problem with
swift build build system, which is the missing 'main' symbol problem. This
is described further detail in #8439.

Provide the link in the skip messages and remove the TODO tags since the
investigation is complete and the reason for the failures is now known.

Update the common test case logic so that it dumps the command execution
stdout and stderr in the case of failure to help diagnose these result.xml failures
immediately in the logs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug swift build Changes impacting `swift build`
Projects
None yet
Development

No branches or pull requests

3 participants