gazebosim/gz-utils

ignition utils 1.2.0 doesn't build with ign-cmake 2.10.0 and with clang-6.0 compiler

ggulgulia opened this issue · 7 comments

Environment

  • OS Version: Ubuntu 18.04
  • Source or binary build?
    • Source build from branch releasing ign-utils 1.2.0 (3991dca05d041dba5477e5aa53f6b058183cd111)
    • compiler clang-6.0 (CC and CXX)
    • ign-cmake 2.10.0 version built from source with clang-6.0 compiler. (source branch: 7eb246daaa6248db3f7c85183789fc1e752423c9)

Description

  • Expected behavior: building ign-utils 1.2.0 with clang-6.0 compiler works
  • Actual behavior: linker error happens when building ign-utils 1.2.0 with clang-6.0 compiler

Steps to reproduce

To reproduce the error, you will need a system with Clang-6.0 compiler

  1. Build ign-cmake 2.10.0 from source with clang-6.0 compiler
  • Clone ign-cmake 2.10.0 from (here)
  • Browse to repository, open a terminal in it and run
mkdir build 
cd build
  • ensure compiler is set to clang-6.0:
export CC=clang-6.0 
export CXX=clang++-6.0
  • create a local installation dir for ign-cmake:
mkdir $HOME/ign-cmake-2.10.0
  • build and install ign-cmake-2.10.0:
cmake -DCMAKE_INSTALL_PREFIX=$HOME/ign-cmake-2.10.0 ..
make
make install
  1. Build ign-uitls 1.2.0 from source with clang-6.0 compiler
  • clone ign-utils 1.2.0 (from here)
  • browse to the repository, open a terminal in it and run
mkdir build 
cd build
  • ensure compilers are set to clang-6.0:
export CC=clang-6.0 
export CXX=clang++-6.0
  • build ign-utils with correct prefix path to ign-cmake-2.10.0:
cmake -DCMAKE_PREFIX_PATH=$HOME/ign-cmake-2.10.0 ..
make

Output

Cmake configuration for ign-utils:

g.gulgulia:~/gg_workspace/ign-utils/build$ export CXX=clang++-6.0
g.gulgulia:~/gg_workspace/ign-utils/build$ export CC=clang-6.0
g.gulgulia:~/gg_workspace/ign-utils/build$ cmake -DCMAKE_PREFIX_PATH=$HOME/ign-cmake-2.10.0 ..
-- The C compiler identification is Clang 6.0.0
-- The CXX compiler identification is Clang 6.0.0
-- Check for working C compiler: /usr/bin/clang-6.0
-- Check for working C compiler: /usr/bin/clang-6.0 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/clang++-6.0
-- Check for working CXX compiler: /usr/bin/clang++-6.0 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- ignition-utils1 version 1.2.0
-- Operating system is Linux
-- Found CPack generators: DEB
-- 
-- Searching for host SSE information
-- SSE2 found
-- SSE3 found
-- SSE4.1 found
-- SSE4.2 found
-- Configuring library: ignition-utils1
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Adding 2 UNIT tests
-- No tests have been specified for INTEGRATION
-- Adding 1 INTEGRATION tests
-- No tests have been specified for PERFORMANCE
-- No tests have been specified for REGRESSION
-- Configuring library: ignition-utils1-cli
-- The program [cppcheck] was not found! Skipping codecheck setup
-- Build configuration successful
-- Build type: RelWithDebInfo
-- Install prefix: /usr/local
-- Looking for ronn to generate manpages - found
-- Found Doxygen: /usr/bin/doxygen (found version "1.8.13") found components:  doxygen dot 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/g.gulgulia/gg_workspace/ign-utils/build

To check if ign-cmake 2.10.0 was correctly used, I ran from build dir: ccmake .. . The output is below:

 BUILD_DOCS                       ON                                                                                                                                                                              
 BUILD_SHARED_LIBS                ON                                                                                                                                                                              
 BUILD_TESTING                    ON                                                                                                                                                                              
 CMAKE_BUILD_TYPE                                                                                                                                                                                                 
 CMAKE_INSTALL_PREFIX             /usr/local                                                                                                                                                                      
 CPPCHECK_PATH                    CPPCHECK_PATH-NOTFOUND                                                                                                                                                          
 DPKG_PROGRAM                     /usr/bin/dpkg                                                                                                                                                                   
 FIND_PATH                        /usr/bin/find                                                                                                                                                                   
 GZIP                             /bin/gzip                                                                                                                                                                       
 IGN_UTILS_VENDOR_CLI11           ON                                                                                                                                                                              
 PYTHON_VERSION                                                                                                                                                                                                   
 RONN                             /usr/bin/ronn                                                                                                                                                                   
 RPMBUILD_PROGRAM                 RPMBUILD_PROGRAM-NOTFOUND                                                                                                                                                       
 SSE2_FOUND                       ON                                                                                                                                                                              
 SSE3_FOUND                       ON                                                                                                                                                                              
 SSE4_1_FOUND                     ON                                                                                                                                                                              
 SSE4_2_FOUND                     ON                                                                                                                                                                              
 SSSE3_FOUND                      ON                                                                                                                                                                              
 USE_FULL_RPATH                   OFF                                                                                                                                                                             
 USE_HOST_SSE_FLAGS               ON                                                                                                                                                                              
 USE_IGN_RECOMMENDED_FLAGS        ON                                                                                                                                                                              
 ignition-cmake2_DIR              /home/g.gulgulia/ign-cmake-2.10.0/share/cmake/ignition-cmake2

after that I build ign-utils and encounter a linker error when UNIT_Environment_TEST is being linked against library Environment

g.gulgulia:~/gg_workspace/ign-utils/build$ make
-- ignition-utils1 version 1.2.0
-- Operating system is Linux
-- Found CPack generators: DEB
-- 
-- Searching for host SSE information
-- SSE2 found
-- SSE3 found
-- SSE4.1 found
-- SSE4.2 found
-- Configuring library: ignition-utils1
-- Adding 2 UNIT tests
-- No tests have been specified for INTEGRATION
-- Adding 1 INTEGRATION tests
-- No tests have been specified for PERFORMANCE
-- No tests have been specified for REGRESSION
-- Configuring library: ignition-utils1-cli
-- The program [cppcheck] was not found! Skipping codecheck setup
-- Build configuration successful
-- Build type: RelWithDebInfo
-- Install prefix: /usr/local
-- Looking for ronn to generate manpages - found
-- Configuring done
-- Generating done
-- Build files have been written to: /home/g.gulgulia/gg_workspace/ign-utils/build
Scanning dependencies of target doc
[  6%] Generating API documentation with Doxygen
[  6%] Built target doc
Scanning dependencies of target gtest
[ 13%] Building CXX object test/CMakeFiles/gtest.dir/gtest/src/gtest-all.cc.o
[ 20%] Linking CXX static library ../lib/libgtest.a
[ 20%] Built target gtest
Scanning dependencies of target ignition-utils1
[ 26%] Building CXX object src/CMakeFiles/ignition-utils1.dir/Environment.cc.o
[ 33%] Linking CXX shared library ../lib/libignition-utils1.so
[ 33%] Built target ignition-utils1
Scanning dependencies of target gtest_main
[ 40%] Building CXX object test/CMakeFiles/gtest_main.dir/gtest/src/gtest_main.cc.o
[ 46%] Linking CXX static library ../lib/libgtest_main.a
[ 46%] Built target gtest_main
Scanning dependencies of target UNIT_Environment_TEST
[ 53%] Building CXX object src/CMakeFiles/UNIT_Environment_TEST.dir/Environment_TEST.cc.o
[ 60%] Linking CXX executable ../bin/UNIT_Environment_TEST
CMakeFiles/UNIT_Environment_TEST.dir/Environment_TEST.cc.o: In function `Environment_emptyENV_Test::TestBody()':
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:28: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
CMakeFiles/UNIT_Environment_TEST.dir/Environment_TEST.cc.o: In function `Environment_envSet_Test::TestBody()':
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:36: undefined reference to `ignition::utils::v1::setenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:41: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:49: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:57: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:62: undefined reference to `ignition::utils::v1::unsetenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
CMakeFiles/UNIT_Environment_TEST.dir/Environment_TEST.cc.o: In function `Environment_envUnset_Test::TestBody()':
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:69: undefined reference to `ignition::utils::v1::unsetenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:74: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:81: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:88: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:91: undefined reference to `ignition::utils::v1::unsetenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
CMakeFiles/UNIT_Environment_TEST.dir/Environment_TEST.cc.o: In function `Util_TEST_envSetEmpty_Test::TestBody()':
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:99: undefined reference to `ignition::utils::v1::setenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:100: undefined reference to `ignition::utils::v1::setenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:105: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:121: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:129: undefined reference to `ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)'
/home/g.gulgulia/gg_workspace/ign-utils/src/Environment_TEST.cc:132: undefined reference to `ignition::utils::v1::unsetenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
src/CMakeFiles/UNIT_Environment_TEST.dir/build.make:98: recipe for target 'bin/UNIT_Environment_TEST' failed
make[2]: *** [bin/UNIT_Environment_TEST] Error 1
CMakeFiles/Makefile2:1088: recipe for target 'src/CMakeFiles/UNIT_Environment_TEST.dir/all' failed
make[1]: *** [src/CMakeFiles/UNIT_Environment_TEST.dir/all] Error 2
Makefile:162: recipe for target 'all' failed
make: *** [all] Error 2

Here's a screenshot of the error

image

Note: I tried the same steps but with clang-8 and clang-9, and ign-utils could be compiled with clang-8 and clang-9

Thanks for reporting, I can reproduce on Ubuntu focal with clang-6.0.

My suspicion is that there is something incorrect with how name mangling works with inline namespace in clang-6.

When built with clang-6 the functions don't get the v1 namespace:

$ nm -a lib/libignition-utils1.so | c++filt | grep ignition::utils
00000000000011d0 T ignition::utils::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)
0000000000001290 T ignition::utils::setenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
00000000000012b0 T ignition::utils::unsetenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

Versus building with something newer (clang-12 in this case):

00000000000011d0 T ignition::utils::v1::env(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, bool)
0000000000001280 T ignition::utils::v1::setenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
00000000000012a0 T ignition::utils::v1::unsetenv(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)

The inline namespace pattern is pretty heavily used throughout the ignition stack, so if clang-6 doesn't correctly support it (or a workaround), we will likely have to note it as unsupported. I can't find any evidence that this wouldn't be supported as clang-6 should fully support the c++17 standard.

Here is a very minimal reproduction excluding everything ignition-related: https://github.com/mjcarroll/clang6-inline-namespace

@mjcarroll thanks for updates and moving the issue to development. Hope to see this working soon. Also I cannot edit the labels, if it is valid, then can you add edifice lable to the issue ?

Hope to see this working soon

After chatting with some colleagues, I'm inclined to say it's either a compiler bug or a weird edge case. I don't know that there will be anything on our side that we can do to handle it.

In the meantime, is there any way that you can use a newer compiler? I see that clang-7 is available via bionic-updates: https://packages.ubuntu.com/bionic-updates/clang-7

yes we can work with other compilers. The compilation error was detected when CI did an automatic build of the conan recipe with multiple compilers and clang-6.0 was one of them. We need only gcc compiler at the moment. To create the conan recipe, we have to simply disable ign-uitls 1.2.0 from the recipe. Hope this is not going to be a problem for other downstream dependencies of ignition-fortress ?

Hope this is not going to be a problem for other downstream dependencies of ignition-fortress ?

This is a pretty common pattern throughout the stack, so I would expect that clang-6 may have issues on all the other packages.

I think at the very least, we will make a note indicating that there are known issues with that compiler.

azeey commented

@ggulgulia Can you check if #39 fixes the problem for you?