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

EASTL doesn't detect non-apple clang on MacOS properly - thinks modern clang versions are pre-C++11 #68

Closed
xaxxon opened this issue Nov 7, 2016 · 11 comments

Comments

@xaxxon
Copy link

xaxxon commented Nov 7, 2016

on clang 3.9 (and probably others), I have to make sure to have

#define EA_HAVE_CPP11_INITIALIZER_LIST

before I include any eastl headers or I get redefinition of initializer_list. Is this normal?

Searching the eastl source on github for that string, I don't see anywhere it would be set automatically...

Thank you.

@rparolin
Copy link
Contributor

rparolin commented Nov 7, 2016

The included EABase package is EASTL's only dependency. It handles defining the necessary compiler and platform defines EASTL uses to configure itself. The necessary EABase header files should be included implicitly by EASTL headers.

EA_HAVE_CPP11_INITIALIZER_LIST defined here:

#if !defined(EA_HAVE_CPP11_INITIALIZER_LIST) && !defined(EA_NO_HAVE_CPP11_INITIALIZER_LIST)

FAQ entry on this:

EASTL has only one dependency: EABase. And EASTL auto-configures itself for most compiler environments and for the most typical configuration choices. Since it is fairly highly warning-free, you won't likely need to modify your compiler warning settings, even if they're pretty stict. EASTL has a few .cpp files which need to be compiled if you want to use the modules associated with those files. You can just compile those files with your regular compiler settings. Alternatively, you can use one of the EASTL project files.<br>

Example of an EASTL header including EABase headers:

#include <EABase/eabase.h>

@xaxxon
Copy link
Author

xaxxon commented Nov 7, 2016

in eacompilers.h

            #elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__APPLE__) // Clang 3.1+, not including Apple's Clang.                           

is what's killing me. I'm running 3.9 (real clang version, not stupid apple clang version number) downloaded directly from clang's download site: http://llvm.org/releases/download.html

Any thoughts on a workaround? Either for my code or for eacompilers.h directly?

@rparolin
Copy link
Contributor

rparolin commented Nov 7, 2016

Is your compiler not in at least C++11 mode?

    #if (__cplusplus >= 201103L)    // Clang and GCC defines this like so in C++11 mode.
        #define EA_COMPILER_CPP11_ENABLED 1

@xaxxon
Copy link
Author

xaxxon commented Nov 7, 2016

I am using c++14 and heavily use c++14 features, so it must be set correct or I'd get all sorts of errors.

but if I'm reading this correctly,

Because this isn't true (because of the compiler version and APPLE being set) :

    #elif defined(EA_COMPILER_CPP11_ENABLED) && defined(__clang__) && (EA_COMPILER_VERSION >= 301) && !defined(__APPLE__) // Clang 3.1+, not including Apple's Clang.

it sets:

        #define EA_COMPILER_NO_INITIALIZER_LISTS 1

which then causes this:

#elif defined(EA_HAVE_LIBCPP_LIBRARY) && (_LIBCPP_VERSION >= 1) && !defined(EA_COMPILER_NO_INITIALIZER_LISTS)

to set EA_NO_HAVE_CPP11_INITIALIZER_LIST instead of EA_HAVE_CPP11_INITIALIZER_LIST

which then causes this to be false:

#if defined(EA_HAVE_CPP11_INITIALIZER_LIST) // If the compiler can generate calls to std::initializer_list...

.. causing std::initializer_list to be redefined here:

namespace std
{
    // See the C++11 Standard, section 18.9.
    template<class E> 
    class initializer_list
    {
    public:

@xaxxon
Copy link
Author

xaxxon commented Nov 7, 2016

More to the point, I comment out the APPLE test in eacompiler.h and things work as expected.

#elif defined(EA_COMPILER_CPP11_ENABLED) && defined(clang) && (EA_COMPILER_VERSION >= 301) // && !defined(APPLE) // Clang 3.1+, not including Apple's Clang.

@xaxxon
Copy link
Author

xaxxon commented Nov 7, 2016

I have reason to believe there is a apple_build_version but am double checking.

@xaxxon
Copy link
Author

xaxxon commented Nov 7, 2016

zacs-MacBook-Pro:apb xaxxon$ cat >deleteme22.cpp
__apple_build_version__     <<<=======
zacs-MacBook-Pro:apb xaxxon$ /usr/bin/clang -E deleteme22.cpp      <<<=======
# 1 "deleteme22.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 336 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "deleteme22.cpp" 2
8000038     <<<=======
zacs-MacBook-Pro:apb xaxxon$ /usr/bin/clang -v
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin



zacs-MacBook-Pro:apb xaxxon$ which clang
/Users/xaxxon/Downloads/clang+llvm-3.9.0-x86_64-apple-darwin/bin/clang     <<<=======
zacs-MacBook-Pro:apb xaxxon$ clang -E deleteme22.cpp
# 1 "deleteme22.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 335 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "deleteme22.cpp" 2
__apple_build_version__     <<<=======

A little more documentation is here: https://sourceforge.net/p/predef/wiki/Compilers/

I've been told this is how cmake determine

@rparolin
Copy link
Contributor

rparolin commented Nov 7, 2016

Ah, yes this makes sense.

EABase figures you are on an Apple platform so you must be using an Apple version of clang. Since you are using clang 3.9 on MacOS it figures you are on an older version of the Apple Clang compiler which doesn't have initializer_lists. Preventing CMake from defining APPLE would force EABase into the non-Apple Clang version checks and everything should work correctly. Not sure if this easily done but internally and on the open source repo we only build/test with Apple's version of Clang on MacOS.

This is the best document I've found for mapping between the version numbers:
https://trac.macports.org/wiki/XcodeVersionInfo

@xaxxon
Copy link
Author

xaxxon commented Nov 7, 2016

I think you could literally to do a text replace of __APPLE__ to __apple_build_version__ and be done.

@rparolin
Copy link
Contributor

rparolin commented Nov 8, 2016

Potentially, I'm briefly looked at the Apple docs and they refer to APPLE but not to apple_build_version. We actually don't test this use case internally so if its a popular enough feature we could support it. However we would have to setup the Travis CI infrastructure to validate this use case and ensure we don't regress as future development occurs. If anyone is interested in doing the work I'd be interested in reviewing the PR.

@xaxxon xaxxon changed the title Am I supposed to have to define EA_HAVE_CPP11_INITIALIZER_LIST in order to not get errors on modern compilers? EASTL doesn't detect non-apple clang on MacOS properly - thinks modern clang versions are pre-C++11 Nov 17, 2016
@DragoonX6
Copy link
Contributor

Potentially look at https://github.com/electronicarts/EASTL/blob/master/scripts/CMake/CommonCppFlags.cmake I might have screwed up the apple flags for clang as I don't have an apple machine.

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

No branches or pull requests

3 participants