I have noticed that when using go build the binary result can be in excess of 2MB; but using gccgo the binary is less than 35k.
The other issue that I noticed when using gccgo is that the produced binary isn't runnable on another linux box (missing libgo.so I believe) but the go build binary runs just fine (so I imagine its because the binary includes all that is necessary to run?); is there a way to do this with gccgo?
You have to use the -static flag:
Use the -static option to do a fully static link (the default for the gc compiler).
http://golang.org/doc/install/gccgo
You can link libgo statically, while still linking the system libraries dynamically, by using the -static-libgo option. (This applies to gccgo only).
With go 1.8 or above, if go is built with CGO_ENABLED=1 (default to 1), a native compilation links dynamically. Check this variable by running go env CGO_ENABLED.
You can switch to link statically by set the environment variable CGO_ENABLED to 0 when running go build.
CGO_ENABLED=0 go build
BTW, cross compiling uses static linkage automatically.
Related
Now, I have the bash code which can import the version value to the go source code in compiling time using the linker which is in the go tool. This code can run normally with GC.
go build -ldflags "-X something:something" main.go
But I am testing my code in the machine whose architecture only supports gccgo instead of gc, and gccgo does not support -ldflags which is a linker tool in gc. Though gccgo has flag options which is -gccgoflags, I didn't see the linking flag I need.
I want to know whether there are any relative flags in gccgo or are there any alternative way to insert the value into source code?
I don't want to hard code this feature with bash.
Thanks.
I'm a student doing research involving extending the TM capabilities of gcc. My goal is to make changes to gcc source, build gcc from the modified source, and, use the new executable the same way I'd use my distro's vanilla gcc.
I built and installed gcc in a different location (not /usr/bin/gcc), specifically because the modified gcc will be unstable, and because our project goal is to compare transactional programs compiled with the two different versions.
Our changes to gcc source impact both /gcc and /libitm. This means we are making a change to libitm.so, one of the shared libraries that get built.
My expectation:
when compiling myprogram.cpp with /usr/bin/g++, the version of libitm.so that will get linked should be the one that came with my distro;
when compiling it with ~/project/install-dir/bin/g++, the version of libitm.so that will get linked should be the one that just got built when I built my modified gcc.
But in reality it seems both native gcc and mine are using the same libitm, /usr/lib/x86_64-linux-gnu/libitm.so.1.
I only have a rough grasp of gcc internals as they apply to our project, but this is my understanding:
Our changes tell one compiler pass to conditionally insert our own "function builtin" instead of one it would normally use, and this is / becomes a "symbol" which needs to link to libitm.
When I use the new gcc to compile my program, that pass detects those conditions and successfully inserts the symbol, but then at runtime my program gives a "relocation error" indicating the symbol is not defined in the file it is searching in: ./test: relocation error: ./test: symbol _ITM_S1RU4, version LIBITM_1.0 not defined in file libitm.so.1 with link time reference
readelf shows me that /usr/lib/x86_64-linux-gnu/libitm.so.1 does not contain our new symbols while ~/project/install-dir/lib64/libitm.so.1 does; if I re-run my program after simply copying the latter libitm over the former (backing it up first, of course), it does not produce the relocation error anymore. But naturally this is not a permanent solution.
So I want the gcc I built to use the shared libs that were built along with it when linking. And I don't want to have to tell it where they are every time - my feeling is that it should know where to look for them since I deliberately built it somewhere else to behave differently.
This sounds like the kind of problem any amateur gcc developer would have when trying to make a dev environment and still be able to use both versions of gcc, but I had difficulty finding similar questions. I am thinking this is a matter of lacking certain config options when I configure gcc before building it. What is the right configuration to do this?
My small understanding of the instructions for building and installing gcc led me to do the following:
cd ~/project/
mkdir objdir
cd objdir
../source-dir/configure --enable-languages=c,c++ --prefix=/home/myusername/project/install-dir
make -j2
make install
I only have those config options because they seemed like the ones closest related to "only building the parts I need" and "not overwriting native gcc", but I could be wrong. After the initial config step I just re-run make -j2 and make install every time I change the code. All these steps do complete without errors, and they produce the ~/project/install-dir/bin/ folder, containing the gcc and g++ which behave as described.
I use ~/project/install-dir/bin/g++ -fgnu-tm -o myprogram myprogram.cpp to compile a transactional program, possibly with other options for programs with threads.
(I am using Xubuntu 16.04.3 (64 bit), within VirtualBox on Windows. The installed /usr/bin/gcc is version 5.4.0. Our source at ~/project/source-dir/ is a modified version of 5.3.0.)
You’re running into build- versus run-time linking differences. When you build with -fgnu-tm, the compiler knows where the library it needs is found, and it tells the linker where to find it; you can see this by adding -v to your g++ command. However when you run the resulting program, the dynamic linker doesn’t know it should look somewhere special for the ITM library, so it uses the default library in /usr/lib/x86_64-linux-gnu.
Things get even more confusing with ITM on Ubuntu because the library is installed system-wide, but the link script is installed in a GCC-private directory. This doesn’t happen with the default GCC build, so your own GCC build doesn’t do this, and you’ll see libitm.so in ~/project/install-dir/lib64.
To fix this at run-time, you need to tell the dynamic linker where to find the right library. You can do this either by setting LD_LIBRARY_PATH (to /home/.../project/install-dir/lib64), or by storing the path in the binary using -Wl,-rpath=/home/.../project/install-dir/lib64 when you build it.
I'm using go 1.5 and I'm cross compiling like specified here.
The problem is that when compiling the project it will override the binary the last compilation created. Moreover - I will never know which OS/ARCH the executable file that I'm running was compiled to (in any case that is not windows).
Is there a way to rename the file at compile command?
You could use the "-o" argument, like this:
GOOS=linux GOARCH=386 CGO_ENABLED=0 go build -o test/output/myapp
From the page you linked to:
-o may be used to alter the name and destination of your binary, but remember that go build takes a value that is relative to your $GOPATH/src, not your working directory, so changing directories then executing the go build command is also an option.
If you use GOOS and GOARCH in the name, you should be able to achieve what you want.
I know how to build gcc from source, what I still have to figure out is what are the exact environmental variables used by gcc when configure and building gcc itself, I'm actually trying to build the compiler from source using another version of gcc with different ABI.
Any idea on how to get this kind of information beside "try to grep all the variable that starts with $ inside all makefiles and configuration files" ?
You can see a list of Environment Variables Affecting GCC.
To create a completly independent gcc with a new toolset, have a look at LFS, they explain how to build gcc from an existing OS for a future OS.
There is also a page about building gcc, which talks about BOOT_CFLAGS='-O' and CFLAGS_FOR_TARGET and STAGE1_TFLAGS and BUILD_CONFIG. There is also some additional variables for cross-compiling and ada compiler.
I want to compile a source code, but there are some compiling errors about __sync_xxx functions (__sync_bool_compare_and_swap etc.)
GCC version on machine is 3.4.3 (it must be gcc 4.1 or over for supporting atomic builtins), so I have downloaded GCC v4.6, copied it to another directory (I didn't remove v3.4.3) then change the $PATH path for GCC but it doesn't work (the same error occurs).
I want to ask that is only changing gcc path with export PATH=... enough for compiling with new GCC?
Use the following configure option when compiling gcc:
--program-prefix=foo --program-suffix=bar
and it will produce bin programs of the form "foo-gcc-bar", so that you may differentiate different builds of gcc.
Replace foo and/or bar with an appropriate "tag" for your build (eg "-4.6" for example).
This way if it doesn't find your toolchain correctly it will fail fast rather than using the 3.4 version.
It also means that different toolchain builds can coexist in the standard installation prefix directories.
We have to use -march=686 switch to get it to work on intel.
Try checking and updating LD_LIBRARY_PATH, to use the lib path for the new gcc installed.