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

'settings.compiler.libcxx' value not defined #2607

Closed
matlo607 opened this issue Mar 13, 2018 · 4 comments
Closed

'settings.compiler.libcxx' value not defined #2607

matlo607 opened this issue Mar 13, 2018 · 4 comments

Comments

@matlo607
Copy link
Contributor

I use GCC 6.3
My profile is:

[settings]
os=Linux
os_build=Linux
arch=x86_64
compiler=gcc
compiler.version=6.3
build_type=Release

[env]
CC=/opt/rh/devtoolset-6/root/usr/bin/gcc
CXX=/opt/rh/devtoolset-6/root/usr/bin/g++
CFLAGS="-fpic"
CXXFLAGS="-fpic"

I wanted conan to use the default values for GCC 6.3. If I remove the line compiler.libcxx=libstdc++ from my profile, it directly stopped building and threw an error.

# conan create -p gcc-6 . matthieu/testing
ERROR: Conanfile: 'settings.compiler.libcxx' value not defined

GCC documentation about Dual ABI:

The _GLIBCXX_USE_CXX11_ABI macro (see Macros) controls whether the declarations in the library headers use the old or new ABI. So the decision of which ABI to use can be made separately for each source file being compiled. Using the default configuration options for GCC the default value of the macro is 1 which causes the new ABI to be active), so to use the old ABI you must explicitly define the macro to 0 before including any library headers. (Be aware that some GNU/Linux distributions configure GCC 5 differently so that the default value of the macro is 0 and users must define it to 1 to enable the new ABI.)

By default, if this setting is not found, no define is returned.
https://github.com/conan-io/conan/blob/1afadb5cca9e1c688c7b37c69a0ff3c6a6dbe257/conans/client/build/compiler_flags.py

def libcxx_define(compiler, libcxx):

    if not compiler or not libcxx:
        return ""

    if str(compiler) in ['gcc', 'clang', 'apple-clang']:
        if str(libcxx) == 'libstdc++':
            return '_GLIBCXX_USE_CXX11_ABI=0'
        elif str(libcxx) == 'libstdc++11':
            return '_GLIBCXX_USE_CXX11_ABI=1'
    return ""

CMake and Autotools helpers get the value from conanfile.settings and check if the value is not null

self._libcxx = conanfile.settings.get_safe("compiler.libcxx")

If it is null, it does not set neither _GLIBCXX_USE_CXX11_ABI=0 nor _GLIBCXX_USE_CXX11_ABI=1 and the compiler will use its default value, exactly the behavior I want.

What is the reason for throwing an error message ?
Do you prevent this to be able to distinguish the ABI if we are building and publishing an artifact from a distribution embedding a fancy GCC ?

@memsharded
Copy link
Member

Yes, the reason is that we much prefer it to be explicit, rather than the compiler default, because the bad thing is that there is not such compiler default, a modern gcc 5.X might use libstdc++ as default in old distros (which are very common in CIs like travis) and libstdc++11 in modern distros.

I think you might achieve that behavior doing the following:

  • Adding None to your settings.yml file, in the relevant libcxx subsettings
  • (optional) If you want an correct fallback from the explicit setting to the default one you could do something like:
def package_id(self):
      if my_custom_logic_is_default(self.settings.compiler.version, self.settings.libcxx):
          self.info.settings.libcxx = None

This latter step allows managing other libcxx than the default without having a duplicated binary (one for libcxx=default, and other for libcxx=None, which is the default two). The reason we cannot make this the default or built-in in conan, is that it is not true in the general case, the implementation of my_custom_logic_is_default is not a pure function of those settings, but also depends on the system, which is not that easy to check.

@matlo607
Copy link
Contributor Author

I discovered this thread #2340 discussing about which ABI should be set by default according to the compiler's version.
Why not autodetecting with which default ABI the compiler was built ?
On Ubuntu 16.04, GCC 5 is compiler with --with-default-libstdcxx-abi=new which means _GLIBCXX_USE_CXX11_ABI=1

# g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.1-2ubuntu1~16.04' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.1 20160904 (Ubuntu 5.4.1-2ubuntu1~16.04)

On RHEL/CentOS 6/7, GCC 6 and 7 are compiled with --with-default-libstdcxx-abi=gcc4-compatible which means _GLIBCXX_USE_CXX11_ABI=1

# /opt/rh/devtoolset-6/root/usr/bin/g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-6/root/usr/libexec/gcc/x86_64-redhat-linux/6.3.1/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-6/root/usr --mandir=/opt/rh/devtoolset-6/root/usr/share/man --infodir=/opt/rh/devtoolset-6/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-default-libstdcxx-abi=gcc4-compatible --with-isl=/builddir/build/BUILD/gcc-6.3.1-20170216/obj-x86_64-redhat-linux/isl-install --enable-libmpx --with-mpc=/builddir/build/BUILD/gcc-6.3.1-20170216/obj-x86_64-redhat-linux/mpc-install --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 6.3.1 20170216 (Red Hat 6.3.1-3) (GCC)

/opt/rh/devtoolset-7/root/usr/bin/g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-7/root/usr --mandir=/opt/rh/devtoolset-7/root/usr/share/man --infodir=/opt/rh/devtoolset-7/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --with-default-libstdcxx-abi=gcc4-compatible --with-isl=/builddir/build/BUILD/gcc-7.2.1-20170829/obj-x86_64-redhat-linux/isl-install --enable-libmpx --with-mpc=/builddir/build/BUILD/gcc-7.2.1-20170829/obj-x86_64-redhat-linux/mpc-install --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 7.2.1 20170829 (Red Hat 7.2.1-1) (GCC)

If the settings compiler.libcxx is absent from the profile we wan still detect it this way and set valid build_info for the package.
Do you think it could be a new feature ?

@lasote
Copy link
Contributor

lasote commented Mar 15, 2018

I will discuss it with @memsharded later today. Note: The default profile will contain a value for compiler.libcxx but if you use a profile (or change the default). Only if this setting is not present it could be filled as the runtime. But we have to discuss it, this could be a breaking behavior.

@memsharded
Copy link
Member

Closing this issue as outdated:

  • Conan 2.0 do not force all settings to be defined, unless build system integrations explicitly require them and fail if not defined
  • Conan 2.0 also provide a profile.py plugin, that can dynamically check and modify the profile at will.

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

3 participants