Skip to content
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

Dub build fails to build project on macOS with M1 chip #2954

Open
Vladiwostok opened this issue Jul 23, 2024 · 10 comments
Open

Dub build fails to build project on macOS with M1 chip #2954

Vladiwostok opened this issue Jul 23, 2024 · 10 comments

Comments

@Vladiwostok
Copy link

Vladiwostok commented Jul 23, 2024

System information

  • dub version: 1.38.0
  • OS Platform and distribution: macOS 14.5 (M1 chip)
  • compiler version LDC 1.39.0

Bug Description

Repo: https://github.com/Dlang-UPB/D-scanner

When trying to build the project's DMD dependency with dub build, the build fails with 'exit code 1' when running the following pregenerate command: https://github.com/dlang/dmd/blob/master/dub.sdl#L53-L61

When running the command manually, the linker reports that the 'phobos2-ldc' lib is not found. When specifying the library path via 'LIBRARY_PATH' or 'DFLAGS' env vars, the manual command works, but dub build still won't build the project.

How to reproduce?

  1. Get an M-chip macOS machine running (macOS 14.5) with the LDC compiler
  2. Clone the following repo: https://github.com/Dlang-UPB/D-scanner
  3. Run dub and watch the build fail:
dub build
  1. Run the pregen command manually (used dir paths specific to my macOS machine) and observe the linker error:
dub --arch=aarch64 --compiler=ldc2 --single /Users/runner/.dub/packages/dmd/~master/dmd/config.d -- /Users/runner/.dub/packages/dmd/~master/dmd/generated/dub /Users/runner/.dub/packages/dmd/~master/dmd/VERSION /etc
  1. Set either one env var:
export LIBRARY_PATH=/Users/runner/hostedtoolcache/dc/ldc2-1.39.0/arm64/ldc2-1.39.0-osx-universal/lib-arm64
export DFLAGS=-L-L/Users/runner/hostedtoolcache/dc/ldc2-1.39.0/arm64/ldc2-1.39.0-osx-universal/lib-arm64
  1. Run the pregen command manually (step 5) and watch the command execute successfully, run dub build (step 3) and watch the build fail.

Expected Behavior

The program should build successfully when using dub, and without having to set any additional library paths.

Logs

$ dub build
Error Expected one or zero arguments.
      Run "dub run -h" for more information about the "run" command.
Error Command failed with exit code 1: 
    "${DUB_EXE}" \
    --arch=${DUB_ARCH} \
    --compiler=${DC} \
    --single "${DUB_PACKAGE_DIR}config.d" \
    -- "${DUB_PACKAGE_DIR}generated/dub" \
    "${DUB_PACKAGE_DIR}VERSION" \
    /etc
$ dub build -vverbose
...
Running 
    "${DUB_EXE}" \
    --arch=${DUB_ARCH} \
    --compiler=${DC} \
    --single "${DUB_PACKAGE_DIR}config.d" \
    -- "${DUB_PACKAGE_DIR}generated/dub" \
    "${DUB_PACKAGE_DIR}VERSION" \
    /etc
   
Error Expected one or zero arguments.
      Run "dub run -h" for more information about the "run" command.
Error Command failed with exit code 1: 
    "${DUB_EXE}" \
    --arch=${DUB_ARCH} \
    --compiler=${DC} \
    --single "${DUB_PACKAGE_DIR}config.d" \
    -- "${DUB_PACKAGE_DIR}generated/dub" \
    "${DUB_PACKAGE_DIR}VERSION" \
    /etc
   
Full exception: object.Exception@source/dub/internal/utils.d(189): Command failed with exit code 1: 
    "${DUB_EXE}" \
    --arch=${DUB_ARCH} \
    --compiler=${DC} \
    --single "${DUB_PACKAGE_DIR}config.d" \
    -- "${DUB_PACKAGE_DIR}generated/dub" \
    "${DUB_PACKAGE_DIR}VERSION" \
    /etc
   
----------------
??:? object.Throwable.TraceInfo core.runtime.defaultTraceHandler(void*) [0x10233c2f3]
??:? _d_run_main [0x102344cf7]
??:? start [0x181c7e0df]
??:? 0x0 [0xe8177fffffffffff]
$ dub --arch=aarch64 --compiler=ldc2 --single /Users/runner/.dub/packages/dmd/~master/dmd/config.d -- /Users/runner/.dub/packages/dmd/~master/dmd/generated/dub /Users/runner/.dub/packages/dmd/~master/dmd/VERSION /etc
    Starting Performing "debug" build using ldc2 for aarch64, arm_hardfloat.
    Building config ~master: building configuration [application]
     Linking config
ld: library 'phobos2-ldc' not found
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: /usr/bin/cc failed with status: 1
Error ldc2 failed with exit code 1.

Additional information

The same project built using makefile on the same OS and with the same compiler builds successfully, without having to set any additional library paths.

If needed, we can provide access to the target macOS machine via our Github actions flow.

@Geod24
Copy link
Member

Geod24 commented Jul 24, 2024

@kinke : Any idea ?

@kinke
Copy link
Contributor

kinke commented Jul 24, 2024

So the immediate problem is this?

dub --arch=aarch64 --compiler=ldc2 --single /Users/runner/.dub/packages/dmd/~master/dmd/config.d -- /Users/runner/.dub/packages/dmd/~master/dmd/generated/dub /Users/runner/.dub/packages/dmd/~master/dmd/VERSION /etc

The most suspicious thing IMO is the --arch=aarch64, so I'd try removing it, and adding -v for more dub output. And probably having the compiler emit the invoked clang cmdline via DFLAGS=-v or so.

@Vladiwostok
Copy link
Author

So the immediate problem is this?

dub --arch=aarch64 --compiler=ldc2 --single /Users/runner/.dub/packages/dmd/~master/dmd/config.d -- /Users/runner/.dub/packages/dmd/~master/dmd/generated/dub /Users/runner/.dub/packages/dmd/~master/dmd/VERSION /etc

The most suspicious thing IMO is the --arch=aarch64, so I'd try removing it, and adding -v for more dub output. And probably having the compiler emit the invoked clang cmdline via DFLAGS=-v or so.

I've run the command without the arch specification and the build executed successfully.

Running the command with verbose compiler logging, I noticed the following diff:

  1. When running with --arch=aarch64
config    /Users/runner/hostedtoolcache/dc/ldc2-1.39.0/arm64/ldc2-1.39.0-osx-universal/etc/ldc2.conf (aarch64-apple-darwin23.5.0)
  1. When running without --arch=aarch64
config    /Users/runner/hostedtoolcache/dc/ldc2-1.39.0/arm64/ldc2-1.39.0-osx-universal/etc/ldc2.conf (arm64-apple-darwin23.5.0)

Looking back in DMD's dub file, I can see the arch being propagated using dub's arch env var (which I presume to be aarch64:

--arch=$${DUB_ARCH}

Does this still look like a dub issue?

@kinke
Copy link
Contributor

kinke commented Jul 24, 2024

Okay thx, now I think I know what happens - the ldc2.conf file expects arm64-apple-… triples, not aarch64-…. Apple went with this scheme for clang, so we/LDC adopted it.

Now I'm definitely no fan of recursive dub calls in pregenerate/build commands, as used by the DMD dub recipe here. I've seen weird issues due to the extra environment variables.

Not sure what the best way forward is - either killing the --arch specification in DMD's dub.sdl, or creating an ugly special case for dub's DUB_ARCH (arm64 for Apple AArch64 targets), or even supporting aarch64-apple-… triples in LDC's ldc2.conf.

@kinke
Copy link
Contributor

kinke commented Jul 24, 2024

Okay, after looking at DMD's dub.sdl, I think that should be fixed - it builds & runs a little config.d tool, so it must be runnable on the compiling machine. One might be cross-compiling, so DUB_ARCH does NOT guarantee the config.d executable can be run.

@kinke
Copy link
Contributor

kinke commented Jul 24, 2024

Looks as if dlang/dmd#9275 actually broke working cross-compilation before, despite its name. ;)

@Geod24
Copy link
Member

Geod24 commented Jul 26, 2024

Now I'm definitely no fan of recursive dub calls in pregenerate/build commands, as used by the DMD dub recipe here. I've seen weird issues due to the extra environment variables.

I've had issues as well. Recursive dub calls are quite popular from my experience, so we probably need to harden the testsuite around it, because they are quite convenient.

@Vladiwostok
Copy link
Author

I'm thinking about drafting a PR in dmd repo and removing the --arch=$${DUB_ARCH} argument from the dub file. Not sure what the implication of this would be for other platforms.

I think using a macOS-arm64 triple would be better for the pregen command, but I think that would mean the pregen command for platform="posix" should be changed in individual commands for all POSIX platforms, so that it won't get applied to macOS arm. Adding so many pregen commands would pollute the dub file.

@kinke
Copy link
Contributor

kinke commented Jul 26, 2024

The thing is: that config.d tool doesn't need to be built for the same build target as the main dub build. And it cannot, just imagine some guy cross-compiling some dub project depending on the dmd package on a macOS arm64 box to Windows x64 - have fun running that config.exe on macOS arm64!

So the only robust way of making sure you build a config executable that can be run on the compiling host is to NOT specify any target, letting the compiler pick its default target (the host's native target).

Using .d files for autogenerating little VERSION files derived from git describe --tags etc. is IMO bad practice - when cross-compiling, you require a D compiler that can a) cross-compile, and b) build successfully for the native platform too. Not sure this approach will e.g. ever work with GDC, where you have different toolchains for each host->target combination.

And that platform="posix" is another dub weakness - you can only differentiate between target platforms, not host platforms. So if config.d only supports Posix, we'd ideally run it on every Posix host, regardless of the target platform. But after a quick look at config.d, it doesn't seem as if it wouldn't work on non-Posix - there's just some SYSCONFDIR.imp thingy that is Posix-only, and versioned out appropriately already. Edit: Well, 'appropriately' - that extra thing is done on Posix hosts only, the target is irrelevant. Edit2: In case I'm being unclear - I suggest simply removing the platform="posix", and maybe look into why that SYSCONFDIR.imp thingy is restricted to Posix hosts/targets.

@kinke
Copy link
Contributor

kinke commented Jul 27, 2024

I've had a go at it: dlang/dmd#16756

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants