Skip to content

configure script misidentifies non-Apple clang as Apple clang on macOS #14

@ryandesign

Description

@ryandesign

I noticed this while configuring polymake:

checking C++ compiler ... ok (/opt/local/bin/clang++-mp-11 is Apple CLANG (roughly 8.0) from Xcode 11.1.0)

This is wrong. /opt/local/bin/clang++-mp-11 is not Apple clang 8; it's llvm.org clang 11.

I see the problem is at least partly here:

#if defined(__APPLE__)
std::cout << "apple";
#endif
#if defined(__clang__)
std::cout << "clang " << __clang_major__ << '.' << __clang_minor__ << '.' << __clang_patchlevel__ << std::endl;
return 0;

You assume we are using Apple clang if the __APPLE__ preprocessor macro is defined but in fact__APPLE__ is defined by all compilers on macOS. If you want to know if Apple clang is being used, check if __apple_build_version__ is defined.

As a result of this decision you later do this:

if (/^(apple)?clang /) {
if ($1 eq "apple") {
$XcodeVersion=$';
$CLANGversion=xcode2clang_version();
} else {

which sets up the $XcodeVersion variable, and then later you do this:

if (defined($GCCversion) or defined($CLANGversion)) {
print "ok ($CXX is ",
defined($GCCversion)
? "GCC $GCCversion" :
defined($XcodeVersion)
? "Apple CLANG (roughly $CLANGversion) from Xcode $XcodeVersion"
: "CLANG $CLANGversion",
")\n";
}

which prints that the compiler is Apple clang if the $XcodeVersion variable is defined.

I see that you also want to know whether Apple's version of gcc is being used:

} elsif (/(apple)?gcc /) {
$GCCversion=$';
# decide whether we use the gcc provided by apple, in that case we need the -arch flags, otherwise we probably don't
$NeedsArchFlag=defined($1);
if (v_cmp($GCCversion, "5.1") < 0) {
die "C++ compiler $CXX says its version is $GCCversion, while the minimal required version is 5.1\n";
}

__apple_build_version__ is only defined by Apple clang, not by Apple gcc. If you want to identify Apple gcc, check if __APPLE_CC__ is defined. However, I see that you use this to decide whether to set $NeedsArchFlag which determines whether you add an -arch flag which doesn't seem quite right. Yes, Apple's versions of gcc supported -arch flags while FSF gcc did not. However, FSF gcc added support for -arch flags in gcc 4.7. And you also already require gcc 5.1 or later, which excludes all versions of Apple gcc (of which 4.2.1 was the last version). So it looks like here you really are asking whether we are building for macOS, and for that __APPLE__ is ok.

Later you use $NeedsArchFlag to decide whether to add an -arch flag:

if ( !defined($FinkBase) && !defined($BrewBase) ) {
$Arch //= `uname -m`;
chomp $Arch;
if ($Arch ne "arm64" && $Arch ne "i386" && $Arch ne "x86_64") {
die "Invalid architecture $Arch for Mac OS: allowed values are i386, x86_64 and arm64.\n";
}
}
$ARCHFLAGS= $NeedsArchFlag ? "-arch $Arch" : "";
$Arch="darwin.$Arch";

But this is weird in several ways. First, you conflate the output of uname -m (which tells you the architecture of the kernel) with the desired user-space architecture (which could be different: the original 64-bit Intel Macs used 32-bit kernels and 64-bit user-space software). Second, there's no point in adding an -arch flag unless your goal is to cross-compile. The default arch is not to cross-compile. So my recommendation is to rip out everything related to setting the -arch flag. The user can specify an -arch flag manually using the usual compiler environment variables if they want something other than the default.

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