How do I compile C++ with Clang? - c++

I have installed Clang by using apt-get in Ubuntu, and I can successfully compile C files using it. However, I have no idea how to compile C++ through it. What do I need to do to compile C++?

The command clang is for C, and the command clang++ is for C++.

I do not know why there is no answer directly addressing the problem. When you want to compile C++ program, it is best to use clang++, instead of using clang. For example, the following works for me:
clang++ -Wall -std=c++11 test.cc -o test
If compiled correctly, it will produce the executable file test, and you can run the file by using ./test.
Or you can just use clang++ test.cc to compile the program. It will produce a default executable file named a.out. Use ./a.out to run the file.
The whole process is a lot like g++ if you are familiar with g++. See this
post to check which warnings are included with -Wall option. This
page shows a list of diagnostic flags supported by Clang.
A note on using clang -x c++: Kim Gräsman says that you can also use
clang -x c++ to compile CPP programs, but that may not be always viable. For example, I am having a simple program below:
#include <iostream>
#include <vector>
int main() {
/* std::vector<int> v = {1, 2, 3, 4, 5}; */
std::vector<int> v(10, 5);
int sum = 0;
for (int i = 0; i < v.size(); i++){
sum += v[i]*2;
}
std::cout << "sum is " << sum << std::endl;
return 0;
}
clang++ test.cc -o test will compile successfully, but clang -x c++ will
not, showing a lot of undefined reference errors. So I guess they are not exactly equivalent. It is best to use clang++ instead of clang -x c++ when compiling c++ programs to avoid extra troubles.
clang version: 11.0.0
Platform: Ubuntu 16.04

Also, for posterity -- Clang (like GCC) accepts the -x switch to set the language of the input files, for example,
$ clang -x c++ some_random_file.txt
This mailing list thread explains the difference between clang and clang++ well: Difference between clang and clang++

Solution 1:
clang++ your.cpp
Solution 2:
clang your.cpp -lstdc++
Solution 3:
clang -x c++ your.cpp

I've had a similar problem when building Clang from source (but not with sudo apt-get install. This might depend on the version of Ubuntu which you're running).
It might be worth checking if clang++ can find the correct locations of your C++ libraries:
Compare the results of g++ -v <filename.cpp> and clang++ -v <filename.cpp>, under "#include < ... > search starts here:".

Open a Terminal window and navigate to your project directory. Run these sets of commands, depending on which compiler you have installed:
To compile multiple C++ files using clang++:
$ clang++ *.cpp
$ ./a.out
To compile multiple C++ files using g++:
$ g++ -c *.cpp
$ g++ -o temp.exe *.o
$ ./temp.exe

Related

Should compiling c++ in Xubuntu 19.04 be different then compiling c++ in Ubuntu 18.04

Will there ever be a case where C++ code compiles with no errors in Ubuntu 18.04 and not compile in Xubuntu 19.04. My original guess was no but then a professor told me about there being some linker issues that may cause that. Also let me also add that the code is compiled using the same std and using g++.
Will there ever be a case where C++ code compiles with no errors in Ubuntu 18.04 and not compile in Xubuntu 19.04.
Possibly, but it only arises in corner cases. Most C++ code won't be affected.
I think it depends on GCC version. Around that time GCC started enabling PIE by default, and it caused some linking issues. See, for example, Initial SUPERCOP Haswell results for round 2. From the mailing list message:
... The rest of this message explains the -fPIC -fPIE above. On
exactly the same long-term-support version of Ubuntu, with the
supposedly compatible system-provided versions of gcc and clang, if
you run
gcc -c x.c; clang -c y.c; gcc -o x x.o y.o
where x.c says
#include <stdio.h>
extern int thenumber(void);
int main() { printf("%d\n",thenumber()); return 0; }
and y.c says
static int myconstant = 5;
int thenumber(void) { return myconstant; }
then compilation fails, while doing
gcc -c x.c; clang -c y.c; clang -o x x.o y.o
or
gcc -c x.c; gcc -c y.c; gcc -o x x.o y.o
or
clang -c x.c; clang -c y.c; clang -o x x.o y.o
works fine. The underlying problem is compiler-writer mismanagement of
an ongoing transition to
-fPIC: compiling libraries as "position-independent code" (this is typically advertised as being important for shared libraries);
-fPIE: compiling main() etc. as position-independent code (this is typically advertised as being important for the claimed security
benefits of address-space layout randomization); and
-pie: linking position-independent executables.
Code that's compiled as position-independent code can be linked into
position-dependent executables or position-independent executables. A
correctly managed transition would have consisted of
turning on -fPIC and -fPIE by default,
issuing automatic warnings for any position-dependent code,
waiting a specified number of years for people to get rid of any previously compiled position-dependent code, and finally
turning on -pie by default.
What happened instead was gcc suddenly turning on -pie, clumsily
breaking all existing position-dependent code and even managing to
break compatibility with clang on the same system---clang still
produces position-dependent code, and then gcc fails to produce an
executable. This is also why gcc now breaks
crypto_kem/ntruhrss701/avx2.

Compiling on linux with c++ standard libraries

Hi have the following example code:
func.h - header file for functions
#include <vector>
#include <tuple>
using std::vector;
using std::tuple;
tuple <double,double> A(vector<int>& n);
func.cpp - function cpp file
#include <iostream>
#include <vector>
#include <tuple>
using namespace std;
tuple <double,double> A(vector<int>& n)
{
double a1=n.size();
double a2=a1+0.5;
return make_tuple(a1,a2);
}
main.cpp - main cpp file
#include <iostream>
#include <vector>
#include <tuple>
#include "func.h"
using namespace std;
int main()
{
double a1,a2;
vector<int> n;
n.push_back(1);
n.push_back(2);
tie(a1,a2)=A(n);
return 0;
}
This compiles well in visual studio.
I have a problem compiling it on Linux (gcc version 4.4.7 20120313 Red Hat 4.4.7-11) with:
g++ -03 -std=c++0x main.cpp func.cpp -lm
It does not compile, I get the following errors:
1. In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/array:35,from main.cpp:5:/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/c++0x_warning.h:31:2: error: #error This file requires compiler and library suppcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
2. ‘std::tuple’ has not been declared
3. expected constructor, destructor, or type conversion before ‘<’ token
Any guidance on how to deal with this will be helpful!
Surprisingly the error seems to tell you that std=c++0x is not set.
Double check your compilation command. it should be
g++ -std=c++0x -o b main.cpp func.cpp -O3 -lm
and not
g++ -o -std=c++0x b main.cpp func.cpp -03 -lm
as in the original question.
You are telling GCC to output to the file named "-std=c++0x", and thus not setting that option at all, leading to this error. What it does with "b" afterwards, I have no idea. But you should always do "-o outputfilename" and not put other options between the "-o" option and its argument.
I cut and pasted your three files (func.h, func.cpp and main.cpp) and I can assure you that on my Linux box (CentOS 7.2) with g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) everything works fine (your original command had some errors):
g++ -o myProg -O3 -std=c++0x main.cpp func.cpp -lm
Update your GCC (even from sources if you have several hours ;) ) .
Since you want to run an executable (compiled from recent C++11 or C++14 source code) on a server with an old version of Linux and of GCC -you have GCC 4.4 which does not support recent C++ standards, because it appeared in 2009 before the publication date (2011) of C++11- you could try the following:
install a recent Linux distribution on your own laptop (or computer) and check that its GCC compiler is at least GCC 5 (and preferably GCC 6) by running g++ --version (you might need to use g++-5 instead of g++, etc...)
compile and link statically your program on that laptop using g++ -static -std=c++14 -Wall func.cpp main.cpp -lm -o mybinprog (and perhaps also -O3 if you want to optimize and/or -g for debugging -better do the debugging locally-)
copy (e.g. using scp mybinprog remotehost:) the executable to the remote server and run it there
It is very probable (but not certain) that a statically linked executable built on a newer Linux (laptop) would run on some older Linux server.
BTW, to compile a multi-source file program, better learn how to use GNU make
Notice that order of program arguments to g++ matters a big lot, so read the documentation about Invoking GCC.
PS. Technically you might even try to link dynamically the C library and statically the C++ standard library.

Compiler command and GCC version

I'm taking part in a programming contest and the requirement is that code will be compiled using following command:
g++ -std=c++11 -O2 -o a.out orienteering.cpp
How do I check if my code works for this command? (I use DevC++ for coding and it has automatic compilation).
Also compiler should be GCC 4.8.2 or later. What does this mean? Is my older GCC version (4.7.2) not suitable?
You check your code by placing it in a file named orienteering.cpp, and running this command in the same directory:
g++ -std=c++11 -O2 -o a.out orienteering.cpp
If the compiler spits out any messages at all then you have a problem. If the compiler is silent and creates a file named a.out, then all is well.
GCC 4.7.2 does not meet the criteria "GCC 4.8.2 or later".

How to replace llvm-ld with clang?

Summary: llvm-ld has been removed from the LLVM 3.2 release. I am trying to figure out how to use clang in its place in my build system.
Note that I figured out the answer to my own question while writing it but I am still posting it in case it is useful to anyone else. Alternative answers are also welcome.
Details:
I have a build process which first generates bitcode using clang++ -emit-llvm. Then I take the bitcode files and link them together with llvm-link. Then I apply some standard optimization passes with opt. Then I apply another custom compiler pass with opt. Then I apply the standard optimization passes again using opt a third time. Finally I take the output from the last run of opt and use llvm-link to link with appropriate libraries to generate my executable. When I tried to replace llvm-link with clang++ in this process I get the error message: file not recognized: File format not recognized
To make this question more concrete I created a simplified example of what I am trying to do. First there are two files that I want to compile and link together
test1.cpp:
#include <stdio.h>
int getNum();
int main()
{
int value = getNum();
printf("value is %d\n", value);
return 0;
}
test2.cpp
int getNum()
{
return 5;
}
I executed the following sequence of commands:
clang++ -emit-llvm -c test1.cpp test2.cpp
llvm-link -o test.bc1 test1.o test2.o
opt test.bc1 -o test.bc2 -std-compile-opts
(Note that I am currently running llvm 3.1, but I'm trying to figure out the steps that will work for llvm 3.2. I assume that I should be able to make the LLVM 3.1 version work correctly using clang instead of llvm-ld)
Then if I run:
llvm-ld test.bc2 -o a.out -native
everything is fine and a.out prints out 5.
However, if I run:
clang++ test.bc2 -o a.out
Then I get the error message:
test.bc2: file not recognized: File format not recognized clang-3:
error: linker command failed with exit code 1 (use -v to see invocation)
Obviously I know that I can produce an executable file by running clang directly on the .cpp files. But I'm wondering what the best way to integrate clang with opt is.
The test case described in the question can be compiled using the following steps:
clang++ -emit-llvm -c test1.cpp test2.cpp
llvm-link -o test.bc1 test1.o test2.o
opt test.bc1 -o test.bc2 -std-compile-opts
llc -filetype=obj test.bc2 -o test.o
clang++ test.o
This produces a working a.out file.
It seems that llc is needed to convert from bitcode to machine code which can then be processed by clang as it normally would.
In general I've found that
llvm-ld x.bc y.bc
can be replaced with
llc x.bc
llc y.bc
clang x.s y.s

G++ compiler: option -s is obsolete and being ignored C++

I'm trying to compile and strip a very simple programm in C++ with the g++ compiler (4.6.0 on Mac OSX). But while compiling i get an warning.
source code:
#include </usr/local/Cellar/gcc/4.6.0/gcc/include/c++/4.6.0/iostream>
int main(){
std::cout << ("Hello World\n") ;
}
Terminal code:
g++ hello.cc -Wall -std=c++0x -s
/* or an alternative: */
g++ hello.cc -Wall -std=c++0x -o test -Wl,-s
Compiler warning:
ld: warning: option -s is obsolete and being ignored
Somebody any idea's about this weird warning?
Edit:
The weird thing is the size does decrease when using the -s flag, the decreases from 9,216 bytes to 9,008.
However when i use the following the size decreases to 8,896 bytes.
cp hello hello_stripped
strip hello_stripped
The error message is from ld, not from gcc or g++. (The gcc and g++ commands are a drivers that invokes the compiler, the linker, and other tools.)
gcc passes the -s option to the linker, as documented in the gcc 4.6.1 manual; apparently the MacOS port of gcc still does that.
The GNU linker (GNU ld) still accepts the -s option with its usual meaning. But the MacOS linker (also called ld) ignores it, as documented in the MacOS ld manual:
-s Completely strip the output, including removing the symbol table.
This file format variant is no longer supported. This option is
obsolete.
And the MacOS gcc manual, unlike GNU's gcc manual, doesn't mention "-s".
Apparently the -s flag is obsolete. You can use the strip program instead though.