Feedback on clang change (#53194)

Marcus Calhoun-Lopez mcalhoun at macports.org
Wed Feb 1 19:33:09 UTC 2017


> Something that's not entirely clear to me yet is what's the benefit of
> having clang compile software against gcc's libstdc++ vs. gcc6
> compiling it.

I have attempted to build both Qt and Octave with gcc6, and I have run across a few unpleasant incompatibilities.

Example:
    #include <stdio.h>
    const int N = 5;
    const int j = N;
    int main()
    {
         printf("%d\n",j);
    }

Clang recognizes the above code as valid C, while GCC does not.
Apparently, the C standard allows a little bit of leeway here.
See
    http://stackoverflow.com/questions/21592494/initializer-element-is-not-constant-error-for-no-reason-in-linux-gcc-compilin
    http://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w
At least one system header file (and perhaps others), /System/Library/Frameworks/CoreGraphics.framework/Headers/CGFont.h,
relies on the clang’s interpretation of the standard.


Example:
    #include <Carbon/Carbon.h>
    int main() {}
On recent versions of macOS, GCC can not compile the above code.
I know that Carbon has been deprecated for some time, but it is a convenient example.

/usr/include/AvailabilityInternal.h gets pulled into source code any number of ways.
This can lead to problems since GCC compilers do not understand Clang's __attribute__.
/usr/include/Availability.h protects against this with preprocessor commands
#if defined(__has_feature)
#elif __has_feature(attribute_availability)
#if __has_feature(attribute_availability_with_message)
/usr/include/AvailabilityInternal.h does not always use these safeguards, which means GCC sometimes cannot compile code which has nothing to do with Availability.h.

I filed a bug report with Apple (r29805005), but I have not heard back.

After trying to work around these problems for a time, I gave up.

> And what's the relation of all this to the magic
> -D_GLIBCXX_USE_CXX11_ABI=0 flag.
My point of reference: https://gcc.gnu.org/onlinedocs/libstdc%2B%2B/manual/using_dual_abi.html
The following code is what I wrote to test various combinations.
The -D_GLIBCXX_USE_CXX11_ABI=0 forces the new libstdc++ string and list implementations to be compatible with the old libstdc++ string and list implementations.

main.cxx:
    #include "f1.hxx"
    int main() { f1("Hi There"); }

f1.hxx:
    #include <string>
    void f1(const std::string& string);

f1.cxx
    #include "f1.hxx"
    #include <iostream>
    void f1(const std::string& string) { std::cout << string << "\n"; }

/opt/local/bin/g++-mp-6 -c -D_GLIBCXX_USE_CXX11_ABI=0 f1.cxx
/usr/bin/clang++ -c -stdlib=libstdc++ -std=c++11 main.cxx
/usr/bin/clang++ -stdlib=libstdc++ *.o
./a.out
/opt/local/bin/g++-mp-6 *.o
./a.out

> 
>> I should have made clear that a major downside of choice #2 is that it requires a library dependency on gcc6.
> 
> Thanks, I missed that. And I agree that this is a bit of a downside.
> What kind of dependency is that exactly? Is it only a dependency
> because the port needs to make sure that gcc's libstdc++ is present at
> the time of compilation or are there some other more hardwired
> constraints?
When the patched clang is called, the header files of gcc6 are used and the libraries from libgcc are linked in.
After compilation, the libraries from libgcc have to be there for the resulting binary to run.

> And we should finally address binary builds for libc++. That would
> likely solve 99.9% of our C++11-related problems.

Unfortunately, I do not even know where to begin to solve this problem.

-Marcus


More information about the macports-dev mailing list