I follow my tutorial in linux to install some package:
yum install -y pcre pcre-devel openssl openssl-devel gcc gcc++
I am not sure about the gcc means GPN Compiler Collection or GPN C Compiler, I just not sure, because if it means the latter, the gcc++ maybe means GNU Compiler C++.
Who is there to answer my doubts?
gcc is GCC and gcc++ is G++ which are both GNU compilers
GCC is GNU’s C Compiler, and
G++ is GNU’s C++ Compiler
The difference is:
GCC will compile both .c and .cpp files. However, it will treat .c files as C programs and .cpp files as C++ programs.
G++ will also compile both .c and .cpp files just like the GCC compiler. The difference is that it will treat both .c and .cpp files as C++ programs.
From the "Programming Languages Supported by GCC" page:
The abbreviation GCC has multiple meanings in common use. The current official meaning is “GNU Compiler Collection”, which refers generically to the complete suite of tools. The name historically stood for “GNU C Compiler”, and this usage is still common when the emphasis is on compiling C programs. Finally, the name is also used when speaking of the language-independent component of GCC: code shared among the compilers for all supported languages.
And regarding the difference between the gcc and g++ commands, see the "GCC Command Options" page:
The usual way to run GCC is to run the executable called gcc, or machine-gcc when cross-compiling, or machine-gcc-version to run a specific version of GCC. When you compile C++ programs, you should invoke GCC as g++ instead. See Compiling C++ Programs, for information about the differences in behavior between gcc and g++ when compiling C++ programs.
and from "Compiling C++ Programs"
the use of gcc does not add the C++ library. g++ is a program that calls GCC and automatically specifies linking against the C++ library. It treats ‘.c’, ‘.h’ and ‘.i’ files as C++ source files instead of C source files unless -x is used.
Related
Question
I want to override/clear g++ default search path for libraries, so that g++ does only search libraries under paths explicitly specified:
$ arm-linux-gnueabihf-g++ --print-search-dirs | grep libraries:
libraries: =/usr/lib/gcc-cross/arm-linux-gnueabihf/6/:/usr/lib/gcc-cross/arm-lin
ux-gnueabihf/6/../../../../arm-linux-gnueabihf/lib/arm-linux-gnueabihf/6/:/usr/l
ib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/lib/arm-linux
-gnueabihf/:/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnuea
bihf/lib/../lib/:/lib/arm-linux-gnueabihf/6/:/lib/arm-linux-gnueabihf/:/lib/../l
ib/:/usr/lib/arm-linux-gnueabihf/6/:/usr/lib/arm-linux-gnueabihf/:/usr/lib/../li
b/:/usr/lib/gcc-cross/arm-linux-gnueabihf/6/../../../../arm-linux-gnueabihf/lib/
:/lib/:/usr/lib/
Can this be done?
Background
I'm on Ubuntu 17.04 compiling c++ code for several cross-platform distributions.
I've installed Ubuntu g++-arm-linux-gnueabihf package, and created a target image under /opt/jessie_root, in this case for Jessie armhf. I also fixed all the links under this jessie_root image to be relative and not absolute.
I want to compile dynamic executables with the target rootfs libraries.
Initially I was compiling "fine" but I realized that I was linking to symbols on the host cross-toolchain libstdc++.
I'm using cmake, but for simplicity consider this commands:
/usr/bin/arm-linux-gnueabihf-g++ main.c
This will link to the host libstdc++ under /usr/lib/gcc-cross/arm-linux-gnueabihf/6/libstdc++.so, which is not desirable.
/usr/bin/arm-linux-gnueabihf-g++ main.cpp --sysroot=/opt/jessie_root -L=/usr/lib/gcc/arm-linux-gnueabihf/4.9 -D_GLIBCXX_USE_CXX11_ABI=0
This will link correctly to the target libstdc++ under /opt/jessie_root/usr/lib/gcc/arm-linux-gnueabihf/4.9/libstdc++.so, which I want.
The issue is that this seems a disaster waiting to happen, as if one of the default libs are not found on the target, the compiler will haply take one from the host cross-toolchain.
I could remove or rename them, but I don't want to mess on /usr/.
I have also played with GCC -nostdlib and LD -nostdlib, which seem to have different meanings. GCC -nostdlib is for libraries, and LD -nostdlib is for the search directories. LD -nostdlib have no effect, and GCC -nostdlib just forces me to specify the libraries manually, but it still keeps the search paths.
Naturally I could use another toolchain/compile my own, but I would prefer to stay on the packaged toolchain.
I am currently trying to use Oracle Linux 6 OS on a SPARC S7 server to run the NPB benchmarks (with OpenMP multithreading support). The OS comes preloaded with gcc 4.4.7, which is missing the Niagara 7 optimizations. I downloaded devtoolset-3 from the Oracle Yum Repository, which has gcc 4.9.2 installed in /opt/rh/devtoolset-3/root/usr/bin. However, when I compile the NPB benchmark using the newer gcc, it automatically links to libraries associated with the older gcc 4.4.7 (located in /usr/lib). This caused my program to segfault during execution. I believe that it is because libgomp 4.4.7 is incompatible with libgomp 4.9.2. I have tried several ways of linking to the libraries in the gcc 4.9.2 folder (which is /opt/rh/devtoolset-3/root/usr/lib/gcc); none of the methods work:
-Xlinker -rpath=lib_location
-Wl -Bstatic
-L lib_location
The closest I got was when using -Wl -Bstatic ~/libgomp.a or -static -L ~/libgomp.a. It fails to find libraries such as libm that reside in the default gcc lib folder (usr/lib).
The actual command used to link is:
/opt/rh/devtoolset-3/root/usr/bin/gcc -O3 -fopenmp -mcmodel=medmid -static -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2 -o ../bin/bt.W.x bt.o initialize.o exact_solution.o exact_rhs.o set_constants.o adi.o rhs.o x_solve.o y_solve.o solve_subs.o z_solve.o add.o error.o verify.o ../common/print_results.o ../common/c_timers.o ../common/wtime.o -lm -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2/lib/
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lm
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lrt
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lpthread
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lc
Is there a way I can link just the libgomp library from gcc 4.9.2 while linking the remaining libraries from gcc 4.4.7?
The devtoolset compilers are all using the system libgcc, libstdc++, version 4.4.7, and can therefore not compile e.g. c++11.
I guess the gcc53-c++-5.3.0-1.el6.x86_64.rpm will do. Comes with the internal */gcc53/lib64{libgcc_s.so**, libgomp.so**, libstdc++} (version 5.3.0) ... Provides /usr/bin/{ gcc53, g++53 }
The package was created a year ago ... well tested, as extra compiler. Download link : https://drive.google.com/file/d/0B7S255p3kFXNbTBneHgwSzBodFE/view?usp=sharing
If you're going to do the -Wl,-Bstatic thing, make sure to follow it immediately by -Wl,-Bdynamic to reset to normal after your added library argument. By default, not all system libraries have static versions installed, which is why you get e.g. cannot find -lc.
So you can try this as a modification of your workaround:
-Wl,-Bstatic ~/libgomp.a -Wl,-Bdynamic
Not pretty, and this question deserves a much better answer (this is still pretty much a hack), but it should get the job done for now.
I am trying to write a single CMakeLists.txt file for C++ compilation on Linux with G++ and on OSX with Clang.
I want to use the Target Library flags -Wl,--start-group and -Wl,--end-group with G++, but these give an error when linking with Clang: ld: unknown option: --start-group
The only results I can find choose to just delete these flags on Mac copies, but that doesn't allow easy project migration from linux to OSX. I tried to make these statements CMAKE conditions, but those are treated as literal libraries which are not found:
eg: $<IF($<NOT:APPLE>)> -Wl,--start-group $<ENDIF($<NOT:APPLE>)>
produces: c++: error: $<IF: No such file or directory
Is there a way to conditionally edit in the CMAKE TARGET_LINK_LIBRARIES field?
I'd try this:
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
set(START_GROUP "-Wl,--start-group")
set(END_GROUP "-Wl,--end-group")
else()
set(START_GROUP "")
set(END_GROUP "")
endif()
Then just replace those options with ${START_GROUP} and ${END_GROUP}, and they will only be used with the GNU compiler.
Don't switch based on platform if it's really the compiler that matters. Otherwise, Clang users on Linux won't be able to build your project.
I am having an issue that I believe is the result of compiler versions. I have three external libraries, we will call liba, libb, and libc. All of the libraries compiled without any issues using ifort 11.1 on Redhat Linux 5.3. This is the snippet of code from the makefile, which works just fine:
foo.exe: foo.o
ifort -m64 foo.o liba libb libc -o $#
I am trying to move the code to a new system, which is using ifort 16.0.2 on Redhat Linux 6.7. The makefiles for the external libraries work without any modification. However, when I go to compile the executable using the same code shown above, I get multiple undefined reference errors.
My guess is that there is an environmental variable I need to modify or a compiler/linker option that I need to add, but I am unsure where to go from here.
I would like to prepare GNU toolchain for bare metal ARM to use it with Geany IDE. There are some tutorials like this one: Building the GNU ARM Toolchain for Bare Metal but I do not understand few steps.
First of all, everyone who uses Linux OS implicitly has gcc, binutils and gdb so why to download others? Secondly all tutorials tell me to configure gcc with something like that: *./configure --target=arm-elf. What does it even do ? Does it just force me to call gcc in command line using arm-elf-gcc instead of gcc or does it change some internal options of my gcc ?
So far I have prepared makefile but I am still not sure about compiler options. I have not changed any gcc configure options and I call compiler with such flags:
CFLAGS = -Wall -std=c99 -march=armv7-m -mtune=cortex-m0
Can I prepare toolchain just with calling gcc with proper arguments or do I need to make some changes in gcc configuration ?
GCC and its target
GCC is always configured to emit binaries for a specific target. So normally the gcc which is already available on Linux has the target "i486-linux-gnu". You can't cross-compile to an ARM target using this compiler.
So you need to install another GCC configured for that target; then GCC and the other programs normally have a prefix indicating the target: In your case the prefix is arm-none-eabi, and then you call that GCC using arm-none-eabi-gcc. You can have multiple GCC installations, they do not interact (if they interact, you have probably screwed up something - always install in separate directories, if you do it manually).
Installing
If your Linux distribution provides a package, you could just install that one (on Debian this is "gcc-arm-none-eabi").
You can download a pre-compiled package: GNU Tools for ARM Embedded Processors.
You can try to compile one. Not really easy, if you want correct multi-libs.
If your Linux distribution provides a package > 4.8.0, you should try that one.
If you want to have multiple versions installed (and be able to switch between them easily), the second option is possibly better. I stopped compiling a GCC for ARM when the second option was available.
Cross-compiling
In your Makefile you have to make sure that the cross-compiler is used. You could use $(CC) in your Makefile, and assign it like this:
TOOLCHAIN = arm-none-eabi-
CC = $(TOOLCHAIN)gcc
Compiler flags for Cortex-M0 are -mcpu=cortex-m0 -mthumb -mfloat-abi=soft which is by convention assigned to CFLAGS
CFLAGS += -mcpu=cortex-m0 -mthumb -mfloat-abi=soft
Then a (simple) rule to compile .c to .o looks like
%.o: %.c
$(CC) $(CFLAGS) -o $# -c $<
Tutorials which use the arm-elf- prefix are out-dated. Currently arm-none-eabi- is in use.