Compiling a simple hello world program generates warnings when compiling with clang. I understand that using clang-cl will get rid of the warnings.
On Clang's website, it states: "clang-cl is an alternative command-line interface to Clang, designed for compatibility with the Visual C++ compiler, cl.exe."
I do not want to use Microsoft Visual C++'s tool chain. I want to use Clang as the compiler and LLD as the linker.
What is meant by "compatibility with the Visual C++ compiler"?
How do I know which linker is used by default? Clang's documentation says that LLD is used by default, but, if so, then why is there a warning? And why is clang-cl the recommended solution for this warning?
clang
I compiled:
clang main.cpp
and got warnings:
main-a354e7.o : warning LNK4217: locally defined symbol _CxxThrowException imported in function "class std::num_put<char,class std::ostreambuf_iterator<char,struct std::char_traits<char> > > const & __cdecl std::use_facet<class std::num_put<char,class std::ostreambuf_iterator<char,struct std::char_traits<char> > > >(class std::locale const &)" (??$use_facet#V?$num_put#DV?$ostreambuf_iterator#DU?$char_traits#D#std###std###std###std##YAAEBV?$num_put#DV?$ostreambuf_iterator#DU?$char_traits#D#std###std###0#AEBVlocale#0##Z)
main-a354e7.o : warning LNK4217: locally defined symbol __std_terminate imported in function "int `public: __cdecl std::locale::~locale(void)'::`1'::dtor$6" (?dtor$6#?0???1locale#std##QEAA#XZ#4HA)
It still generated an a.exe file. However, this same command generates no file when run in a Debian terminal (WSL Windows Subsystem for Linux) and has errors.
clang && lld [lld-link]
I tried compiling to object code and then passing this to LLD. It resulted in an error:
clang -c main.cpp -o main.o
lld-link main.o
lld-link: error: could not open libcpmt.lib: no such file or directory
What is this library? Where did it come from? Why is it not found?
main.cpp
#include <iostream>
using namespace std;
int add1(int x);
int main()
{
int a;
a = 1;
cout << a << endl; //prints a and goes to new line
a = add1(a);
return 0; //must return 0 to tell the OS the
//program executed successfully
}
int add1( int x )
{
x = x + 1;
return x;
}
clang is the C compiler, clang++ is the c++ one. So to compile as c++, you need clang -c main.cpp -o main.o
clang-cl on the other end is an alternative driver. If you don't want to use the toolchain, don't bother about it. However, if you are like me and try to compile a project that currently compiles with MSVC and want to also compile it with clang, it's really useful.
The main difference, if you don't play with triples is the platform ABI it links to.
Clang++ links against the mingw standard library while clang-cl uses the Microsoft runtime. As a consequence, the name mangling ... is also MSVC compatible. (Of, and it has a permissive mode in which it allows some invalid code for compatibility)
Related
I have a makefile for macOS and Linux, which contains the following command:
cc -std=c++14 foo.cpp bar.cpp
And it compiles fine. foo.cpp and bar.cpp are, as the name suggests C++ files and it contains C++11 syntax. The compilation works fine.
Now if I include <fstream> I get hundred of linker errors. I am wondering, why that is?
Undefined symbols for architecture x86_64:
"std::__1::locale::has_facet(std::__1::locale::id&) const", referenced from:
bool std::__1::has_facet<std::__1::codecvt<char, char, __mbstate_t> >(std::__1::locale const&) in DiceInvaders-6f5dd4.o
"std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
...
Afaik, cc links to the c compiler, and I would assume due to it's auto detection it compiles it with the C++ compiler. But why does it fail with an additional C++ include?
Is there any counterpart of cc for c++ on a system? If I use g++, I would assume that command is available, and what if the user actually wanted to compile it with his compiler of preference (as in cc)?
Edit: Is $(CXX) a good replacement for cc?
Most probably cc on your system is a symlink to gcc executable. Assuming that is true:
The difference between gcc and g++, quoting the man page, is:
g++ is a program that calls GCC and automatically specifies linking against the C++ library.
So when you invoke gcc it does not link against c++ library. You can link standard c++ library manually:
gcc -lstdc++ 1.cpp
Is there any counterpart of cc for c++ on a system?
The cc command is just a convention that most system follow. It's not standardized, at least I haven't heard where, the utility c99 is standarized by posix. On my linux system with archlinux distribution with the gcc package there is also installed symlink /usr/bin/c++ to g++.
I'm trying to use clang-tidy code analysis so I can check for CppCoreGuidelines. I downloaded LLVM 7.0.0 pre-built binary for Win 7 64 bits. I'm able to successfully compile with clang, I did a basic example compiling this code, I named the source test.cpp:
// test.cpp
#include <iostream>
int main(int argc, char const *argv[])
{
std::cout << "Hello World!" << std::endl;
return 0;
}
Then I ran this in the terminal:
clang test.cpp
I got this output when compiling:
test-c4b051.o : warning LNK4217: locally defined symbol __std_terminate imported in function "int `public: static unsigned __int64 __cdecl std::char_traits<char>::length(char const * const)'::`1'::dtor$2" (?dtor$2#?0??length#?$char_traits#D#std##SA_KQEBD#Z#4HA)
test-c4b051.o : warning LNK4217: locally defined symbol _CxxThrowException imported in function "public: void __cdecl std::ios_base::clear(int,bool)" (?clear#ios_base#std##QEAAXH_N#Z)
But it worked fine printing "Hello World" and everything goes fine until here, but when I want to run clang-tidy I get the following output when I run this, I took the reference from here Extra Clang Tools 8 documentation:
clang-tidy test.cpp -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus*
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "test.cpp"
No compilation database found in C:\Users\uidr8361\Desktop\C++ or any parent directory
fixed-compilation-database: Error while opening fixed database: no such file or directory
json-compilation-database: Error while opening JSON database: no such file or directory
Running without flags.
I read this thread but this seems to apply for clang compilation and I don't know if this also applies for clang extra tools, clang-tidy in particular:
How to compile Clang on Windows
Just put -- (minus minus) on the command line at the end
clang-tidy -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus* test.cpp --
You would normally put your cl,gcc,clang arguments afterwards
clang-tidy -checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus* test.cpp -- -DDEBUG -I./include
I am 100% new at c++ so bear with me :)
I am getting an error with this file and not sure why. any help is appreciated.
#include <iostream>
using namespace std;
int main()
{
cout << "hi" << endl;
return 0;
}
------------ Build: Debug in 1600 (compiler: GNU GCC Compiler)-------------
g++ -o bin/Debug/1600 obj/Debug/main.o obj/Debug/src/test.o obj/Debug/test03.o
duplicate symbol _main in:
obj/Debug/main.o
obj/Debug/test03.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
From the source files symbols are created. main in the .cpp file becomes _main as a symbol. During linking there can be only one main function, hence only one _main symbol is expected and allowed.
You have three object files that were created:
obj/Debug/main.o which contains main
obj/Debug/src/test.o
obj/Debug/test03.o which also contains main
Probably because you have a .cpp file for each of them and the command line or IDE you are using asked for them all to be compiled.
duplicate symbol _main
The text above is telling you that the linker (trying to make sense of all the compiled object (.o) files) found more than one main.
So the solution is to look at your IDE settings and remove the other files (or at least remove main from the other files) because you are only interested in compiling the one source file.
Its hard to tell what you're running from the question.
Here is how to build a simple C++ program using gcc
In
my_program.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "hi" << endl;
return 0;
}
To compile to object files type
g++ -c my_program.cpp
To link (you'd normally have more files here)
g++ -o my_program my_program.o
So, this isn't very fun so most people use a build system like make, cmake, msbuild or whatever the CLion IDE uses.
I have a simple proof case file, which is called main.c
void bar(void);
void foo(void)
{
bar();
}
int main(void)
{
return 0;
}
As you can see there is no definition for bar()
My goal is to compile this on windows using cygwin's gcc.
I have figured out that I could use the following linker option:
--unresolved-symbols=ignore-all
This should tell the linker not to care about missing symbols. In the main.c example the missing symbol would not even be an issue, as foo is never called, therefore there should not be an undefined behavior when the program is executed.
I have 2 flavors of gcc, one for embedded ARM targets, and one from cygwin 64bit for windows.
The embedded ARM gcc is from here: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm , version 4_9-2015q3.
The Cygwin gcc is taken from https://cygwin.com 's 64bit installer, version 7.3.0-1
I use these compile options with the compilers:
arm-none-eabi-g++.exe -Wl,--unresolved-symbols=ignore-all main.c
g++.exe -Wl,--unresolved-symbols=ignore-all main.c
The first compiles and links without errors, as for the second I get this error message:
/cygdrive/c/Users/user/AppData/Local/Temp/ccRF8tf5.o:main.c:(.text+0x9): undefined reference to `bar()'
/cygdrive/c/Users/user/AppData/Local/Temp/ccRF8tf5.o:main.c:(.text+0x9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `bar()'
collect2: error: ld returned 1 exit status
Where clearly the undefined reference to `bar()' message should have been suppressed by the option -Wl,--unresolved-symbols=ignore-all
(The second error message does not appear, if I use gcc from the 32 bit cygwin installer.)
The --help command for the cygwin ld shows the --unresolved-symbols=ignore-all as a valid option.
I suppose the cygwin gcc has been compiled in a way, that this option does not work, even though it is not complaining that it can not validate this option.
If for example I use this command:
g++.exe -Wl,--unresolved-symbols=dummy main.c
I get this error message:
/usr/lib/gcc/x86_64-pc-cygwin/7.3.0/../../../../x86_64-pc-cygwin/bin/ld: bad --unresolved-symbols option: dummy
Which for me tells, that --unresolved-symbols is in fact is an accepted command.
My questions would be:
Is there a way to see which commands are truly accepted by gcc
Is there some other way that could work using cygwin's gcc to compile this main.c example?
Compiling gcc for windows from sources with the proper option could maybe get --unresolved-symbols to work?
My motivation for this whole thing is that I want to unit test a single function from big files, that have multiple functions. Like in the following example:
#include "foobar.h"
int foo(void)
{
return 0;
}
void bar(void)
{
foobar();
}
The declaration of foobar() is in the foobar.h and the definition is in another file called foobar.c
If I wanted to run a unit test, which just links against the symbol foo() I would still get a linker error because of the missing symbol for foobar(). (linking against foobar.o would lead me to link to the complete chain of dependencies, which I want to avoid)
If this --unresolved-symbols option would work, then I would not need to mock or stub the foobar() function in my unit test.
I do understand that there are tools that can create automatically mocks, nevertheless I would like to get this to work.
Thanks for reading through.
I'm trying to compile my projects on Arch Linux x64 using libc++, libc++abi and clang++ 3.6.0.
The projects compile properly, but fail to link with the following error:
error: CMakeFiles/main.cpp.o: undefined reference to symbol '__cxa_thread_atexit##CXXABI_1.3.7'
/usr/lib/libstdc++.so.6:-1: error: error adding symbols: DSO missing from command line
I'm compiling and linking using the -stdlib=libc++ -lc++abi flags.
Is there any additional library I should link? Am I missing a flag?
Either link with -lsupc++ or provide a small wrapper function
(probably the better way for libc++) for the glibc implementation:
extern "C" int __cxa_thread_atexit(void (*func)(), void *obj,
void *dso_symbol) {
int __cxa_thread_atexit_impl(void (*)(), void *, void *);
return __cxa_thread_atexit_impl(func, obj, dso_symbol);
}
It may be worth to mention that this only works with glibc >= 2.18.