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

macOS: LD version detection is unable to detect linker for compiler gfortran with Xcode CLT 15.0 #12282

Closed
wmutschl opened this issue Sep 22, 2023 · 24 comments

Comments

@wmutschl
Copy link

wmutschl commented Sep 22, 2023

Describe the bug
We have recently switched to meson for building dynare, an industry-leading software used by many central banks, economic policy and research institutions as well as universities.

All was good with Xcode Command Line Tools (CLT) 14.3.1, but recently I updated to Xcode CLT 15.0 and now I get an error ld: unknown options: --version when detecting linker for compiler gfortran -Wl,--version`:

The Meson build system
Version: 1.2.1
Source dir: /Users/wmutschl/dynare/irf-matching/irf-matching
Build dir: /Users/wmutschl/dynare/irf-matching/irf-matching/build-matlab
Build type: native build
Project name: dynare
Project version: 6-unstable

meson.build:12:0: ERROR: Unable to detect linker for compiler `gfortran -Wl,--version -L/var/folders/b0/t0gqszsj5qg8mvpk7fqy0f7h0000gn/T/tmp.cH3j0LwS`
stdout: 
stderr: collect2 version 13.2.0
/usr/bin/ld -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/ -dynamic -arch x86_64 -platform_version macos 13.0.0 0.0 -o a.out -L/var/folders/b0/t0gqszsj5qg8mvpk7fqy0f7h0000gn/T/tmp.cH3j0LwS -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc/x86_64-apple-darwin22/13 -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc/x86_64-apple-darwin22/13/../../.. --version -lemutls_w -lgcc -lSystem -no_compact_unwind -rpath @loader_path -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc/x86_64-apple-darwin22/13 -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current
ld: unknown options: --version 
collect2: error: ld returned 1 exit status

Here is the output of meson-log.txt:

# cat /Users/wmutschl/dynare/unstable/build-matlab/meson-logs/meson-log.txt 

Build started at 2023-09-21T08:24:25.638781
Main binary: /usr/local/opt/python@3.11/bin/python3.11
Build Options: -Dmatlab_path=/Applications/MATLAB/x86_64/MATLAB_R2023a.app -Dbuildtype=debugoptimized '-Dfortran_args=['"'"'-B'"'"','"'"'/Users/wmutschl/dynare/slicot/lib'"'"']' --native-file=scripts/homebrew-native.ini
Python system: Darwin
The Meson build system
Version: 1.2.1
Source dir: /Users/wmutschl/dynare/unstable
Build dir: /Users/wmutschl/dynare/unstable/build-matlab
Build type: native build
Project name: dynare
Project version: 6-unstable
-----------
Detecting compiler via: `gfortran --version` -> 0
stdout:
GNU Fortran (Homebrew GCC 13.2.0) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-----------
Running command: gfortran -E -dM -
-----
-----------
Detecting linker via: `gfortran -Wl,--version` -> 1
stderr:
collect2 version 13.2.0
/usr/bin/ld -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/ -dynamic -arch x86_64 -platform_version macos 13.0.0 0.0 -o a.out -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc/x86_64-apple-darwin22/13 -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc/x86_64-apple-darwin22/13/../../.. --version -lemutls_w -lgcc -lSystem -no_compact_unwind -rpath @loader_path -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc/x86_64-apple-darwin22/13 -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current
ld: unknown options: --version 
collect2: error: ld returned 1 exit status
-----------

meson.build:12:0: ERROR: Unable to detect linker for compiler `gfortran -Wl,--version`
stdout: 
stderr: collect2 version 13.2.0
/usr/bin/ld -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/ -dynamic -arch x86_64 -platform_version macos 13.0.0 0.0 -o a.out -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc/x86_64-apple-darwin22/13 -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc -L/usr/local/Cellar/gcc/13.2.0/bin/../lib/gcc/current/gcc/x86_64-apple-darwin22/13/../../.. --version -lemutls_w -lgcc -lSystem -no_compact_unwind -rpath @loader_path -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc/x86_64-apple-darwin22/13 -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current/gcc -rpath /usr/local/Cellar/gcc/13.2.0/lib/gcc/current
ld: unknown options: --version 
collect2: error: ld returned 1 exit status

To Reproduce
Update to Xcode Command Line Tools 15.0 and follow the instructions to build for macos, you will get the error. Downgrade to Xcode Command Line Tools 14.3.1 and there is no error.
Here is a minimal version of the build process to replicate:

# brew packages
brew install meson bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc docutils wget pkg-config git-lfs
# compile Dynare from source
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git $HOME/dynare/unstable
cd $HOME/dynare/unstable
meson setup --native-file scripts/homebrew-native.ini -Dbuild_for=octave -Dbuildtype=debugoptimized -Dfortran_args="['-B']" build-octave

homebrew-native.ini looks like this:

[binaries]
cpp = 'g++-13'
flex = '/usr/local/opt/flex/bin/flex'
bison = '/usr/local/opt/bison/bin/bison'

Expected behavior
No error.

system parameters

  • MacOS Ventura 13.5.2 or 13.6
  • Python 3.11.5
  • meson 1.2.1
  • ninja 1.11.1
@eli-schwartz
Copy link
Member

Hmm, weird.

What options does /usr/bin/ld accept? Is there a different spelling for this particular linker to emit its version number?

(I thought we try both -v and --version, but I'd need to double check.)

@wmutschl
Copy link
Author

Many thanks for the quick reply! I just updated to Xcode CLT 15.0 again:

# /usr/bin/ld -v
@(#)PROGRAM:ld  PROJECT:dyld-1015.7
BUILD 18:48:48 Aug 22 2023
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
will use ld-classic for: armv6 armv7 armv7s arm64_32 i386 armv6m armv7k armv7m armv7em
LTO support using: LLVM version 15.0.0 (static support for 29, runtime is 29)
TAPI support using: Apple TAPI version 15.0.0 (tapi-1500.0.12.3)
Library search paths:
Framework search paths:

and

#/usr/bin/ld --version
ld: unknown option: --version

@wmutschl
Copy link
Author

However, the same with Xcode CLT 14.3.1:

# /usr/bin/ld -v
@(#)PROGRAM:ld  PROJECT:ld64-857.1
BUILD 23:13:29 May  7 2023
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 14.0.3, (clang-1403.0.22.14.1) (static support for 29, runtime is 29)
TAPI support using: Apple TAPI version 14.0.3 (tapi-1403.0.5.1)

and

# /usr/bin/ld --version
ld: unknown option: --version

@eli-schwartz
Copy link
Member

This looks like the difference between "PROJECT:ld64" and "PROJECT:dyld" is tripping up the detection. I think there was a recent discussion about this, hold on...

@wmutschl
Copy link
Author

wmutschl commented Sep 22, 2023

Yes, but I checked, I have the fix #11958 in my /usr/local/opt/meson/lib/python3.11/site-packages/mesonbuild/linkers/detection.py.
Line 189 and following:

    elif e.endswith('(use -v to see invocation)\n') or 'macosx_version' in e or 'ld: unknown option:' in e:
        if isinstance(comp_class.LINKER_PREFIX, str):
            cmd = compiler + [comp_class.LINKER_PREFIX + '-v,-r'] + extra_args
        else:
            cmd = compiler + comp_class.LINKER_PREFIX + ['-v'] + extra_args
        _, newo, newerr = Popen_safe_logged(cmd, msg='Detecting Apple linker via')

        for line in newerr.split('\n'):
            if 'PROJECT:ld' in line or 'PROJECT:dyld' in line:
                v = line.split('-')[1]
                break
        else:
            __failed_to_detect_linker(compiler, check_args, o, e)
        linker = linkers.AppleDynamicLinker(compiler, for_machine, comp_class.LINKER_PREFIX, override, version=v)

@eli-schwartz
Copy link
Member

Okay then, I'm out of ideas that I can think of and suggest from my phone while I'm on the go. I'll try to investigate in greater depth later today or perhaps on Sunday.

@wmutschl
Copy link
Author

I am very grateful for any idea, thank you so much for taking the time!

@wmutschl
Copy link
Author

I have also updated the first post which has minimal instructions to reproduce the error.

@jpakkane
Copy link
Member

Does it fail if you use Meson from Git trunk?

@wmutschl
Copy link
Author

I am sorry, but I don't know how to install the most recent git version. I tried:

git clone https://github.com/mesonbuild/meson.git $HOME/meson
brew uninstall meson
brew install bison flex boost gcc gsl libmatio veclibfort octave sphinx-doc docutils wget pkg-config git-lfs
git clone --recurse-submodules https://git.dynare.org/Dynare/dynare.git $HOME/dynare/unstable
cd $HOME/dynare/unstable
$HOME/meson/meson.py setup --native-file scripts/homebrew-native.ini -Dbuild_for=octave -Dbuildtype=debugoptimized -Dfortran_args="['-B']" build-octave

But now I get:

meson.build:15:0: ERROR: Compiler gfortran cannot compile programs.

Is there a guide how I install it properly from git?

@eli-schwartz
Copy link
Member

git clone https://github.com/mesonbuild/meson.git $HOME/meson
[...]
$HOME/meson/meson.py setup [...]

This is a correct implementation of running meson from git. To be sure, you should see that it's reporting a version number of 1.2.99 rather than reporting a version of 1.2.1

My conclusion is that the answer to @jpakkane's question is "no, using the most recent git version still fails, and does not solve the problem -- it is not fixed yet".

@mkoeppe
Copy link

mkoeppe commented Sep 26, 2023

Has this failure been reproduced with gfortran that is not coming from Homebrew?
This homebrew-specific configuration Homebrew/homebrew-core@57c7726 by @fxcoudert may be relevant.

@fxcoudert
Copy link

fxcoudert commented Sep 26, 2023

On macOS Ventura, Homebrew's gcc is unaffected by the changed linked above (we still build it on CI with Xcode 14).

But even when called as ld-classic, the linker output should be matched by the code shown above:

$ /Library/Developer/CommandLineTools/usr/bin/ld-classic -v
@(#)PROGRAM:ld-classic  PROJECT:ld64-907
BUILD 19:12:38 Aug 11 2023
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
LTO support using: LLVM version 15.0.0 (static support for 29, runtime is 29)
TAPI support using: Apple TAPI version 15.0.0 (tapi-1500.0.12.3)

meson.build:15:0: ERROR: Compiler gfortran cannot compile programs.

Do you have the output from that test?

@dimpase
Copy link

dimpase commented Sep 28, 2023

macport seems to have the same issue with the new ld, see https://trac.macports.org/ticket/68225

@wmutschl
Copy link
Author

Thanks for the updates, I did some more digging and it seems like the linker issue is a known bug, already reported to Apple, and also in the release notes for XCode 15 (and for me the issue is still there in 15.1. Beta):

  • Binaries using symbols with a weak definition crash at runtime on iOS 14/macOS 12 or older. This impacts primarily C++ projects due to their extensive use of weak symbols. (114813650) (FB13097713)
    Workaround: Bump the minimum deployment target to iOS 15, macOS 12, watchOS 8 or tvOS 15, or add -Wl,-ld_classic to the OTHER_LDFLAGS build setting.
  • Weak symbol imports are linked as non-weak imports, when used from LTO object files. (115521975) (FB13171424)
    Workaround: Add -Wl,-weak_reference_mismatches,weak or -Wl,-ld_classic options to the OTHER_LDFLAGS build setting.

Other resources also confirm that the current workaround is to add -ld_classic to linker flags, which forces the older linker to be used.

See:

However, how do I do this to my project? Do I set environmental variables or do I change the meson build script? Sorry, I am very new to this and not very experiences in compilations...
I found this Libreoffice snippet, so would it be correct to add:

 export LDFLAGS="$LDFLAGS -Wl,-ld_classic"

before my meson setup command?

@eli-schwartz
Copy link
Member

Yes, setting LDFLAGS should work.

@wmutschl
Copy link
Author

wmutschl commented Oct 10, 2023

Okay an update that it works, but I am not sure what exactly did it for me.

  1. Installed XCode Command Line Tools 15.1 Beta, issue still persisted.
  2. Did a export LDFLAGS="$LDFLAGS -Wl,-ld_classic" prior to the meson command, and issue was gone (still on 15.1 Beta).

Interestingly, from now on (even after reboot) I don't have to use export LDFLAGS="$LDFLAGS -Wl,-ld_classic" anymore, but it keeps using the ld_classic linker; this is strange isn't it?

@wmutschl
Copy link
Author

export LDFLAGS="$LDFLAGS -Wl,-ld_classic" with XCode Command Line Tools 15.0 also works. And same weird thing: I only need to run the export LDFLAGS="$LDFLAGS -Wl,-ld_classic" command once before the meson setup. Closing the terminal, restarting the computer, re-opening Terminal, cloning the repo, the meson setup command runs fine (without the export command anymore).

@wmutschl
Copy link
Author

wmutschl commented Oct 10, 2023

@svillemot proposed to simply use the native file in our case:

[binaries]
cpp = 'g++-13'
c = 'gcc-13'
flex = '/usr/local/opt/flex/bin/flex'
bison = '/usr/local/opt/bison/bin/bison'

[built-in options]
cpp_args = [ '-I/usr/local/include', '-B', '/usr/local/lib' ]
cpp_link_args = [ '-Wl,-ld_classic' ]
c_link_args = [ '-Wl,-ld_classic' ]
fortran_link_args = [ '-Wl,-ld_classic' ]

I replicated the issue in a clean installed macOS. Using the above native file solves the issue.

@dimpase
Copy link

dimpase commented Oct 10, 2023

So in a new shell LDFLAGS is not set, yet meson works?

@wmutschl
Copy link
Author

Yes, very weird... I have this on two macs... Anyways, the native file is the better solution.

@wmutschl
Copy link
Author

wmutschl commented Oct 11, 2023

I have done another install in a virtual machine and both the native file solution as well as the export command work and solve the issue. Also the persistence of the export command is not there anymore, so all is good, seems to be something specific to my settings.

@dimpase
Copy link

dimpase commented Oct 11, 2023

Yes, very weird... I have this on two macs... Anyways, the native file is the better solution.

could it be "restore apps and windows" macOS feature playing here? (or perhaps a side effect of it)

vbraun pushed a commit to vbraun/sage that referenced this issue Oct 28, 2023
    
<!-- ^^^^^
Please provide a concise, informative and self-explanatory title.
Don't put issue numbers in there, do this in the PR body below.
For example, instead of "Fixes sagemath#1234" use "Introduce new method to
calculate 1+1"
-->
<!-- Describe your changes here in detail -->


<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
- Fixes sagemath#36342
- using the fix discussed at
mesonbuild/meson#12282
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->
<!-- If your change requires a documentation PR, please link it
appropriately -->
<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
<!-- Feel free to remove irrelevant items. -->

- [x] The title is concise, informative, and self-explanatory.
- [ ] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: sagemath#36523
Reported by: Matthias Köppe
Reviewer(s): John H. Palmieri
vbraun pushed a commit to vbraun/sage that referenced this issue Oct 29, 2023
    
<!-- ^^^^^
Please provide a concise, informative and self-explanatory title.
Don't put issue numbers in there, do this in the PR body below.
For example, instead of "Fixes sagemath#1234" use "Introduce new method to
calculate 1+1"
-->
<!-- Describe your changes here in detail -->


<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
- Fixes sagemath#36342
- using the fix discussed at
mesonbuild/meson#12282
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. -->
<!-- If your change requires a documentation PR, please link it
appropriately -->
<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
<!-- Feel free to remove irrelevant items. -->

- [x] The title is concise, informative, and self-explanatory.
- [ ] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [ ] I have created tests covering the changes.
- [ ] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: sagemath#36523
Reported by: Matthias Köppe
Reviewer(s): John H. Palmieri
@wmutschl
Copy link
Author

wmutschl commented Dec 20, 2023

Xcode CLT 15.1 fixed this issue, the ld_classic workaround in the native file is not necessary anymore, even though the workaround still continues to work.
Nope, 15.1 did not fix this.

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

6 participants