Skip to content

Wrong condition for deciding when to add -latomic #30093

Closed
@ryandesign

Description

@ryandesign
  • Version: 12.12.0, 13.0.1
  • Platform: macOS 10.13
  • Subsystem:

node.gyp uses this code to decide whether to add the -latomic flag:

      ['OS in ("linux", "mac") and llvm_version != "0.0"', {
         'libraries': ['-latomic'],
       }],

This is exactly wrong. You want to add -latomic when not using llvm/clang. llvm_version is supposed to be 0.0 when not using llvm/clang. Therefore what I think you meant to write was 'OS in ("linux", "mac") and llvm_version == "0.0".

However, in fact, llvm_version ended up being 0.0 even when using llvm/clang on recent macOS versions because you're setting llvm_version wrong, or rather, it's wrong to assume that you can get the llvm version. It's set this way in configure.py:

  o['variables']['llvm_version'] = get_llvm_version(CC) if is_clang else '0.0'
def get_llvm_version(cc):
  return get_version_helper(
    cc, r"(^(?:FreeBSD )?clang version|based on LLVM) ([0-9]+\.[0-9]+)")

This will only work with open-source versions of clang, and versions of Apple's Xcode clang prior to Xcode 7. As of Xcode 7, Apple no longer advertises its compiler as being "based on" a particular open source llvm version; Apple's llvm/clang has diverged too much from open source llvm/clang for any such association to be meaningful.

The consequence of the combination of these two errors is that it correctly omits -latomic with Xcode 7 and later, but incorrectly adds -latomic with any open source clang version and probably also with Xcode 6 and earlier.

You can try to get the clang version using the __clang_major__, __clang_minor__ and __clang_patchlevel__ preprocessor defines, which you do in try_check_compiler in configure.py, and you make decisions based on that number elsewhere, but note that Apple's clang uses a different version numbering scheme than open source clang. If there's a particular clang feature you need that you can't check for using the feature-checking macros, you can check if __apple_build_version__ is defined and if so you can compare that number with a known-good Apple build version; if it's not defined, you can compare __clang_major__.__clang_minor__.__clang_patchlevel__ with a known-good open source clang version.

For this situation, where you merely want to add -latomic when not using clang, it seems like you just need a variable based on the __clang__ preprocessor define that indicates whether you're using clang. It doesn't matter here what the specific llvm version is; it just matters whether or not clang is being used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions