I've got a problem that's a bit strange.
We have a project that we compile for several different architectures, notably these 2: SH4 and MIPS.
We've had a problem for some time, where some code would compile in SH4, but not for MIPS, because of missing includes. I've narrowed down the problem to this test file:
#include <sstream>
// deliberately not including the needed includes
int main()
{
const char *toto = "Hello World";
// using printf and strlen which require <stdio.h> and <string.h>
printf("Toto has len %d\n", strlen(toto));
return 0;
}
Compiling to SH4 with this command
$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -o test
$
-> no problem at all. The file actually executes normally.
Whereas with MIPS
$ mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -o test
test.cpp: In function 'int main()':
test.cpp:6: error: 'strlen' was not declared in this scope
$
Now, I've run several things, notably the dependency generation of both g++. What I see is this:
SH4
$ sh4-linux-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"
/opt/STM/STLinux-2.3/devkit/sh4/target/usr/include/string.h \
-> string.h automatically included.
MIPS
mips-linux-gnu-g++ -O0 -g -Wall -Werror -Wno-write-strings \
-fno-rtti -fno-exceptions test.cpp -M |grep "/string.h"
-> string.h missing in includes
For information:
SH4 version = 4.2.4 (2007)
MIPS version = 4.3.2 (2008)
What's going on here? The <sstream> include seems to drag along all what's needed for strlen() when compiling on SH4, whereas on MIPS it doesn't. I suspect this is because the versions are different, but I'm not sure.
My real problem, in the end, is that when I develop on SH4, I'd like to be sure that if it compiles, it will compile on all targets.
Is there a solution to this?
What's going on here?
You're basically asking "why does my non-standard code compile with one version of a compiler but not another?" Of course it's because the versions are different.
See the GCC 4.3 changes which say this under the Runtime Library (libstdc++) section:
Header dependencies have been streamlined, reducing unnecessary includes and pre-processed bloat.
We've continued reducing header dependencies in more recent versions too, to be stricter and to reduce namespace pollution (e.g. 4.6 avoids including <cstddef> unnecessarily, and 4.7 no longer includes <unistd.h> unnecessarily), so to answer your final question I would suggest using the most recent GCC version you can (even if only to check the code not for production builds) as it has the strictest, cleanest headers and will find the most problems. Another option would be to use an even stricter standard library implementation, such as libcomo.
Related
I am using gcc 4.9.2 with ccache 3.1.10. My shell environment contains GCC_COLORS=auto (from here; tried yes and always too).
As a minimal test I compile this main.c file
int main() {
int a;
return 0;
}
with gcc -c main.c -Wall -o main.o and observe (as desired)
main.c: In function ‘main’:
main.c:2:7: warning: unused variable ‘a’ [-Wunused-variable]
int a;
^
with main.c: and main.c:2:7:, ‘main’: and ‘a’ in bold face, the ^ in boldface green, and the warning: in magenta bold face.
Compiling with ccache the colorisation disappears.
NB: ccache gcc -Wall -c main.c -o main.o is colorless, but ccache gcc -Wall main.c -o main remains colored.
NB2: ccache gcc -Wall -c main.c -o main.o -fdiagnostics-color also preserves colors in the output.
Question: Is there a recommended way to have the export GCC_COLORS functionality with ccache? I'd prefer to have colors globally enabled (as through the ~/.MYSHELLrc) and without adding -fdiagnostics-color globally to $CFLAGS[0] and I want to avoid custom wrappers which parse the output messages (and might get confused with LC_MESSAGES settings).
[0]: I have many Makefiles which don't add their config to CFLAGS but overwrite the environment settings.
Not really sure it's relevant anymore, but I just tested with GCC_COLORS=yes with ccache version 3.4.1 and gcc 7.4.0 and that seems to work fine for me. I had the same issue when GCC_COLORS wasn't set.
I made a simple quick sort algorithm using C language, named test.c
I'm trying to maximize the optimization, so I use -O3 options like belows.
gcc -S -O3 -o test.s test.c
gcc -S -O3 -o test1.s test.s
gcc -S -O3 -o test2.s test1.s
gcc -S -O3 -o test3.s test2.s
.
.
.
But strange thing happens. The more times I did above procedure, the more number of line assembly get.
I don't know why this happens, because I think that I have to get more optimized assembly file that has smaller number of line as I did above procedure.
If this is not right way, using -O3 only one time is the way of the best optimization?
Thanks
Most of the gcc optimizations operate on the representation of C source code in an intermediate language. I'm not aware of any optimization specifically operating at the assembler instruction level other than peephole. But that would also be included in -O3.
So yes, -O3 is supposed to be used only once, when turning C source into object files.
gcc experts,
I'm trying to use gcc lto with library archives, as the gcc comes with my system (RedHat Enterprise Linux 5.7) doesn't work with -flto (neither for my Ubuntu 14.10), so I build binutils && gcc from scratch.
Here is what I did:
1. Build binutils-2.22 with --enable-plugins
2. Build gcc-4.7.2 with --with-plugin-ld=/path/to/ld/built/in/step1 --enable-lto
3. Then for the following simple test:
// 1.c:
int foo(void)
{ return 0; }
// 2.c:
extern int foo(void)
int main(void)
{ return foo(); }
The following can get foo() inlined:
my_gcc -O3 -flto -c -o 1.o 1.c
my_gcc -O3 -flto -c -o 2.o 2.c
my_gcc -O3 -flto -o a.out 1.o 2.o
While the following can't:
my_gcc -O3 -flto -c -o 1.o 1.c
my_gcc -O3 -flto -c -o 2.o 2.c
my_ar cr --plugin <my_gcc>/libexec/gcc/x86_64-redhat-linux/4.7.2/liblto_plugin.so 1.a 1.o
my_ar cr --plugin <my_gcc>/libexec/gcc/x86_64-redhat-linux/4.7.2/liblto_plugin.so 2.a 2.o
gcc -O3 -flto -fuse-linker-plugin -o a.out 1.a 2.a
As the building system for the product I'm working on has to use archives, then what I can do to let lto work with library archive?
Your help will be much much appreciated.
Thanks a lot.
When linking, the order in which the libraries are listed on the command line, matters. So when compiling from the archives, you should swap 1.a and 2.a:
gcc -O3 -flto -fuse-linker-plugin -o a.out 2.a 1.a
I tested with gcc 4.9.2 and the disassembly, obtained with objdump -d a.out, shows that foo() is being inlined.
I use the following LLVM tools to convert a cpp project which is written in multiple files into "ONE" single assembly file.
clang *.cpp -S -emit-llvm
llvm-link *.s -S -o all.s
llc all.s -march=mips
Is there any way of doing this in GCC? In particular, is there any way of linking GCC generated assembly files into one assembly file? i.e., what is the equivalent of LLVM-LINK?
Perhaps LTO (Link Time Optimization) is what you want.
Then, compile each compilation unit with gcc -flto e.g.
gcc -flto -O -Wall -c src1.c
g++ -flto -O -Wall -c src2.cc
and use also -flto (and the same optimizations) to link them:
g++ -flto -O src1.o src2.o -lsomething
LTO works in GCC by putting, in each generated assembly file and object file, some representation of the internal GCC representations (like Gimple). See its documentation
You might want to use MELT to customize GCC (or simply use its probe to understand the Gimple, or try just gcc -fdump-tree-all).
I'm trying to combine object files created from C++ files into an executable using gcc. Unfortunately, gcc is giving me thousands of undefined reference errors to strings, arrays, etc.
I am doing this on a Windows machine, so no terminal commands; only cmd commands.
I'm simply doing:
gcc a.o b.o c.o -o prgm.exe
What am I missing/doing wrong?
EDIT:
I recreated the .o files with g++ doing:
g++ a.cpp -g -c -Wall -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -IC:\SDL-1.2.14\include -o a.o, where a.cpp and a.o are the directories where i keep the files, not the g++ directory
Then, I did g++ a.o b.o c.o -o prgm.exe. This gave dozens (I guess that's an improvement?) errors like
undefined reference to `_SDL_SetColorKey'
but I included SDL didnt I?
The final error from this is:
c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../li
bmingw32.a(main.o):main.c:(.text.startup+0xa7): undefined reference to `_WinMain
#16'
collect2.exe: error: ld returned 1 exit status
int main(int argc, char * argv[]) is in the code
You are trying to link a C++ program with the C linker. You need to use g++ instead of gcc.
Generally speaking gcc is for compiling/linking C, while g++ is for C++. IIRC compiling C++-code with gcc works by virtue of dispatching according to the file extension. Linking C++ code with gcc however does not work, since it won't link the C++ standard libraries, resulting in your undefined reference errors.
If this does not solve your problem, you might want to give us a more concrete description of your errors and your system.
Based upon your updates then I think you'd need to do the following:
g++ a.cpp b.cpp c.cpp -g -Wall -IC:\SDL-1.2.14\include -LC:\SDL-1.2.14\lib -std=c++0x -lSDLmain -lSDL -lSDL_image -lSDL_ttf -o prgm.exe
I'm guessing C:\SDL-1.2.14\lib exists based upon where the headers are located.
GCC is the C compiler. Your code is C++ so you need to use G++ to do the linking:
g++ a.o b.o c.o -o prgm.exe
This automatically adds the C++ libraries to the link line, resolving many if not all of your missing references.