1

Googling around finds several pages showing instructions based on yum for older variants of clang. I'm an experienced programmer but know almost nothing about administration, for instance don't know yum and the commands don't seem to work as shown. I do use dnf, and the following resulted in clang being runnable but apparently either not finding or not knowing to link to the Standard C++ library, math library and so on. The same command with g++ works fine.

[root@localhost Linux5.3.7-301.fc31.x86_64]# dnf provides clang
Last metadata expiration check: 2:44:22 ago on Sat May  9 10:25:22 2020.
clang-9.0.0-1.fc31.i686 : A C language family front-end for LLVM
Repo        : fedora
Matched from:
Provide    : clang = 9.0.0-1.fc31

clang-9.0.0-1.fc31.x86_64 : A C language family front-end for LLVM
Repo        : fedora
Matched from:
Provide    : clang = 9.0.0-1.fc31

clang-9.0.1-2.fc31.i686 : A C language family front-end for LLVM
Repo        : updates
Matched from:
Provide    : clang = 9.0.1-2.fc31

clang-9.0.1-2.fc31.x86_64 : A C language family front-end for LLVM
Repo        : updates
Matched from:
Provide    : clang = 9.0.1-2.fc31

[root@localhost Linux5.3.7-301.fc31.x86_64]# dnf install clang-9.0.1-2.fc31.x86_64
Last metadata expiration check: 2:44:43 ago on Sat May  9 10:25:22 2020.
Dependencies resolved.
========================================================================================================================================================
 Package                               Architecture                     Version                                 Repository                         Size
========================================================================================================================================================
Installing:
 clang                                 x86_64                           9.0.1-2.fc31                            updates                           379 k
Installing dependencies:
 clang-libs                            x86_64                           9.0.1-2.fc31                            updates                            32 M
Installing weak dependencies:
 compiler-rt                           x86_64                           9.0.1-1.fc31                            updates                           1.9 M
 libomp                                x86_64                           9.0.1-1.fc31                            updates                           350 k

Transaction Summary
========================================================================================================================================================
Install  4 Packages

Total download size: 34 M
Installed size: 164 M
Is this ok [y/N]: Y
Downloading Packages:
(1/4): clang-9.0.1-2.fc31.x86_64.rpm                                                                                     33 kB/s | 379 kB     00:11
(2/4): libomp-9.0.1-1.fc31.x86_64.rpm                                                                                    90 kB/s | 350 kB     00:03
(3/4): compiler-rt-9.0.1-1.fc31.x86_64.rpm                                                                              117 kB/s | 1.9 MB     00:16
(4/4): clang-libs-9.0.1-2.fc31.x86_64.rpm                                                                               228 kB/s |  32 MB     02:22
--------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                   245 kB/s |  34 MB     02:23
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                1/1
  Installing       : libomp-9.0.1-1.fc31.x86_64                                                                                                     1/4
  Installing       : compiler-rt-9.0.1-1.fc31.x86_64                                                                                                2/4
  Installing       : clang-libs-9.0.1-2.fc31.x86_64                                                                                                 3/4
  Installing       : clang-9.0.1-2.fc31.x86_64                                                                                                      4/4
  Running scriptlet: clang-9.0.1-2.fc31.x86_64                                                                                                      4/4
  Verifying        : clang-9.0.1-2.fc31.x86_64                                                                                                      1/4
  Verifying        : clang-libs-9.0.1-2.fc31.x86_64                                                                                                 2/4
  Verifying        : compiler-rt-9.0.1-1.fc31.x86_64                                                                                                3/4
  Verifying        : libomp-9.0.1-1.fc31.x86_64                                                                                                     4/4

Installed:
  clang-9.0.1-2.fc31.x86_64         clang-libs-9.0.1-2.fc31.x86_64         compiler-rt-9.0.1-1.fc31.x86_64         libomp-9.0.1-1.fc31.x86_64

Complete!

Then, naively perhaps simply changing g++ to clang, results in an apparently good compile but linker doesn't find, or doesn't even look for, the standard library etc.:

> clang -DLinux -fPIC -pthread tsfoo.o -Wall -Wno-parentheses -Werror -L../../release/Linux5.3.7-301.fc31.x86_64/lib -L/usr/X11/lib -L/X/lib -L/X/lib -latomic -lFooDebug -lFooTopDebug -o tsfoo

/usr/bin/ld: tsfoo.o: in function `main':
/t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/test/tsfoo.cxx:161: undefined reference to `std::chrono::_V2::system_clock::now()'
/usr/bin/ld: /t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/test/tsfoo.cxx:165: undefined reference to `std::chrono::_V2::system_clock::now()'
/usr/bin/ld: /t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/test/tsfoo.cxx:184: undefined reference to `std::chrono::_V2::system_clock::now()'
/usr/bin/ld: /t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/test/tsfoo.cxx:188: undefined reference to `std::chrono::_V2::system_clock::now()'
/usr/bin/ld: /t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/test/tsfoo.cxx:192: undefined reference to `std::chrono::_V2::system_clock::now()'
/usr/bin/ld: tsfoo.o:/t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/test/tsfoo.cxx:196: more undefined references to `std::chrono::_V2::system_clock::now()' follow
/usr/bin/ld: tsfoo.o: in function `main':
/t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/test/tsfoo.cxx:246: undefined reference to `std::thread::join()'
/usr/bin/ld: tsfoo.o: in function `__static_initialization_and_destruction_0(int, int)':
/usr/include/c++/9/iostream:74: undefined reference to `std::ios_base::Init::Init()'
/usr/bin/ld: /usr/include/c++/9/iostream:74: undefined reference to `std::ios_base::Init::~Init()'
/usr/bin/ld: tsfoo.o: in function `std::thread::~thread()':
/usr/include/c++/9/thread:139: undefined reference to `std::terminate()'
/usr/bin/ld: tsfoo.o: in function `void std::vector<std::thread, std::allocator<std::thread> >::_M_realloc_insert<void (&)(int), int&>(__gnu_cxx::__normal_iterator<std::thread*, std::vector<std::thread, std::allocator<std::thread> > >, void (&)(int), int&)':
/usr/include/c++/9/bits/vector.tcc:485: undefined reference to `__cxa_begin_catch'
/usr/bin/ld: /usr/include/c++/9/bits/vector.tcc:493: undefined reference to `__cxa_rethrow'
/usr/bin/ld: /usr/include/c++/9/bits/vector.tcc:485: undefined reference to `__cxa_end_catch'
/usr/bin/ld: tsfoo.o: in function `std::vector<std::thread, std::allocator<std::thread> >::_M_check_len(unsigned long, char const*) const':
/usr/include/c++/9/bits/stl_vector.h:1756: undefined reference to `std::__throw_length_error(char const*)'
/usr/bin/ld: tsfoo.o: in function `__gnu_cxx::new_allocator<std::thread>::deallocate(std::thread*, unsigned long)':
/usr/include/c++/9/ext/new_allocator.h:128: undefined reference to `operator delete(void*)'
/usr/bin/ld: tsfoo.o: in function `std::thread::thread<void (&)(int), int&, void>(void (&)(int), int&)':
/usr/include/c++/9/thread:130: undefined reference to `std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)())'
/usr/bin/ld: tsfoo.o: in function `std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> > std::thread::_S_make_state<std::thread::_Invoker<std::tuple<void (*)(int), int> > >(std::thread::_Invoker<std::tuple<void (*)(int), int> >&&)':
/usr/include/c++/9/thread:206: undefined reference to `operator new(unsigned long)'
/usr/bin/ld: tsfoo.o: in function `__gnu_cxx::new_allocator<std::thread>::allocate(unsigned long, void const*)':
/usr/include/c++/9/ext/new_allocator.h:105: undefined reference to `std::__throw_bad_alloc()'
/usr/bin/ld: /usr/include/c++/9/ext/new_allocator.h:114: undefined reference to `operator new(unsigned long)'
/usr/bin/ld: tsfoo.o: in function `std::thread::_State::_State()':
/usr/include/c++/9/thread:67: undefined reference to `vtable for std::thread::_State'
/usr/bin/ld: tsfoo.o: in function `std::thread* std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<std::thread*>, std::thread*>(std::move_iterator<std::thread*>, std::move_iterator<std::thread*>, std::thread*)':
/usr/include/c++/9/bits/stl_uninitialized.h:86: undefined reference to `__cxa_begin_catch'
/usr/bin/ld: /usr/include/c++/9/bits/stl_uninitialized.h:89: undefined reference to `__cxa_rethrow'
/usr/bin/ld: /usr/include/c++/9/bits/stl_uninitialized.h:86: undefined reference to `__cxa_end_catch'
/usr/bin/ld: tsfoo.o: in function `std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(int), int> > >::~_State_impl()':
/usr/include/c++/9/thread:187: undefined reference to `std::thread::_State::~_State()'
/usr/bin/ld: tsfoo.o: in function `std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(int), int> > >::~_State_impl()':
/usr/include/c++/9/thread:187: undefined reference to `operator delete(void*, unsigned long)'
/usr/bin/ld: tsfoo.o:(.data.rel.ro._ZTINSt6thread11_State_implINS_8_InvokerISt5tupleIJPFviEiEEEEEE[_ZTINSt6thread11_State_implINS_8_InvokerISt5tupleIJPFviEiEEEEEE]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/usr/bin/ld: tsfoo.o:(.data.rel.ro._ZTINSt6thread11_State_implINS_8_InvokerISt5tupleIJPFviEiEEEEEE[_ZTINSt6thread11_State_implINS_8_InvokerISt5tupleIJPFviEiEEEEEE]+0x10): undefined reference to `typeinfo for std::thread::_State'
/usr/bin/ld: tsfoo.o:(.data.rel.local.DW.ref.__gxx_personality_v0[DW.ref.__gxx_personality_v0]+0x0): undefined reference to `__gxx_personality_v0'
/usr/bin/ld: ../../release/Linux5.3.7-301.fc31.x86_64/lib/libFooDebug.a(akstdc.o): in function `AKFPDFromDbl':
/t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/libDebug/akstdc.c:159: undefined reference to `log10'
/usr/bin/ld: /t/proj/Foo/SC_2_3_1/Linux5.3.7-301.fc31.x86_64/libDebug/akstdc.c:161: undefined reference to `pow'
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
Swiss Frank
  • 1,985
  • 15
  • 33
  • `clang` is a `c` compiler. Why are you trying to link to `c++` libraries? `c++` is not `c` it is a different language, – DavidPostill May 09 '20 at 12:41
  • The first line of the clang manpage: _clang is a C, C++, and Objective-C compiler._ – Swiss Frank May 09 '20 at 13:53
  • The first line of the Wiki page: _Clang /ˈklæŋ/[5] is a compiler front end for the C, C++, Objective-C and Objective-C++ programming languages._ – Swiss Frank May 09 '20 at 13:54
  • The first line of the Clang homepage: _Clang: a C language **family** frontend for LLVM_ – Swiss Frank May 09 '20 at 13:58
  • What he means is, while Clang can compile several languages, the `clang` executable is intended for compiling C. Use `clang++`. – HolyBlackCat May 09 '20 at 15:49
  • No, what he means is to simply mock a questioner without supplying the answer. Thanks for actually answering, Holy, and I'd ask to make an answer which I'd mark as correct but Asteroids has already done so. – Swiss Frank May 10 '20 at 15:04
  • _You are not "entitled" to the supply of answers here_ Glad you at least agree it wasn't an answer, even if you don't agree that it was of mocking character. Good day to you sir and thanks again. – Swiss Frank May 10 '20 at 16:21

1 Answers1

2

Clang, the project/toolchain, can indeed compile more than just C programs. It can also handle C++, Objective-C and Objective-C++.

But, you have to tell it to do so.

The project's binary clang deals with C, and thus will not (by default) link in the C++ standard library.

The project's binary clang++ will do so.

Write clang++ for C++.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • Thanks Asteroids. I assumed that it'd take the file name as a hint. Now it's working fine. – Swiss Frank May 10 '20 at 15:28
  • @SwissFrank The file name is `tsfoo.o`. It's an already-compiled object file. What language does the extension `.o` hint? – Asteroids With Wings May 10 '20 at 15:30
  • good point! Original problems were with compile-and-link invocations, so didn't realize my base assumption was proven impossible by the actual example I uploaded. I'm just confirming again that the Clang man page makes no mention of clang++, even as a SEE ALSO, despite discussing C++ at length. Now I'm wondering, how did you first learn that clang++ was the command when the project doesn't mention it? – Swiss Frank May 10 '20 at 16:26
  • 1
    @SwissFrank While the documentation could indeed be improved, the solution is findable by Googling "how to build C++ in clang" then reading the first couple of results. Takes a minute tops. – Asteroids With Wings May 10 '20 at 16:28
  • (I remember now, that I was wondering momentarily how `clang` would detect a need for the C++ std library, but instantly had some possible explanations: possibly the object file having unresolved C++ std library symbols in it would be a clue! Or perhaps they just threw the C++ std library in every effective link line, where it'd be available for C++ and silently ignored for C/ObjC. Or the presence of mangled C++ symbols, impossible to generate in C, would trigger the C++ std library. Indeed given the possible heuristics, one wonders why it's _not_ automatic.) – Swiss Frank May 10 '20 at 19:25
  • Because it is not worth the effort to implement complex heuristics that one person wants, when the rest of the world just runs `clang++`. – Asteroids With Wings May 10 '20 at 19:43
  • 1) I didn't say I wanted it, 2) I can't imagine what strikes you as complicated about, say, _throwing the C++ std library in every effective link line, where it'd be available for C++ and silently ignored for C/ObjC_. That could be as little as one line of code, don't you think? Regardless, thanks again for the solution. – Swiss Frank May 11 '20 at 02:51