How to build CGO program static linking to glibc and dynamic linking to libGL.so? - go

My os is Kali, running GLIBC_2.32. I need to build an CGO application for a debian 10 system, which is running GLIBC_2.28.
If I go build with dynamic linking, it can't be run on the debian system, it shows GLIBC mismatch:
version `GLIBC_2.29` not found
version `GLIBCXX_3.4.29` not found
version `GLIBC_2.32` not found
So I tried static linking: CGO_LDFLAGS='-static' go build. A gui library uses OpenGL and it shows error:
# github.com/go-gl/gl/v3.2-core/gl
/usr/bin/ld: cannot find -lGL
After searching a while I found the libGL is related to the gpu driver and can't be statically linked.
Then I tried linking libGL.so dynamically and statically linking other libraries by:
CGO_LDFLAGS='-L/usr/lib/x86_64-linux-gnu -Bdynamic -lGL -static' go build
But same error: "cannot find -lGL"
I don't want to use docker, it's too heavy. And I don't think upgrading from debian 10 to 11 solves the problem, there maybe some other clients running different os in the future. What's the best solution?

Then I tried linking libGL.so dynamically and statically linking other libraries by:
CGO_LDFLAGS='-L/usr/lib/x86_64-linux-gnu -Bdynamic -lGL -static' go build
The -static flag tells the linker: perform a completely static link. It doesn't matter whether you put it before or after -lGL, the meaning is the same.
To link some libraries statically and link others dynamically, see this answer.
That said, what you are trying to do is impossible: if you have any dynamic libraries in your link, then libc.so.6 must also be dynamically linked.
I don't want to use docker, it's too heavy.
Too bad. You'll have to use docker, or set up a chroot environment, or build yourself a "Linux to older Linux" crosscompiler. The docker is likely easiest to implement.

Related

GCC gprof complaining GLIBC_2.16 is not found

I have a code running on a PowerPC e500v2 embedded Linux and I want to measure its performance since it is running in an infinite loop. I tried gcc's gprof which was simply by adding -pg option to gcc. When I run the binary on the target device I get this:
./main: /lib/libc.so.6: version GLIBC_2.16 not found (required by ./main)
I am using ELDK 5.6 toolchain with the default CFLAGS and LDFLAGS and these flags: -Wall -lrt -pthread -D_GNU_SOURCE nothing else. Some article suggested defining FORTIFY_SOURCE along with an optimization level but it did not work. I searched for some gcc's feature test macros and tried defining some GLIBC 2.16 specific macros but it did not work.
I faced similar issue with GLIBC 2.17 when I used some structures and functions from <sched.h>, adding _GNU_SOURCE resolved it. Any idea on how to resolve it?
When I run the binary on the target device I get this
Your tool chain targets a version of GLIBC that is newer than what is installed on the target.
This doesn't bite you in non-pg compiles only by accident. An "innocent" change to your source can cause the same problem.
You need to upgrade your target to the version of GLIBC which your toolchain actually builds for.

Autotools - libtool: link: -rpath with #executable_path on MacOS

I'm trying to build a framework with Autotools on MacOS. This frameworks contains a library, let's call it libmytools.dylib, and an executable that uses the library.
What I want is to link this library dynamically at runtime.
The executable is usually installed to /Library/Frameworks/mytools.Framework/Versions/Current/Commands/mytools
The library is usually installed to
/Library/Frameworks/mytools.Framework/Versions/Current/Libraries/libmytools.dylib
In case the framework is installed in that location, everything works fine, but when the framework is not installed on the machine but instead it's only embedded in another project, the library can't be found.
What I need is a so called "Runpath Dependent Library" as described here:
https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html
So what I did was adding mytools_LDFLAGS = -rpath #executable_path/../Libraries to the makefile.
But unfortunately libtool refuses to link my executable with the dynamic -rpath
and shows the following error: libtool: link: only absolute run-paths are allowed.
I also tried mytools_LDFLAGS = -dynamic -rpath #executable_path/../Libraries but the result is the same...
What am I doing wrong??
This is the current libtool design. This thread from the libtool patches list may have a suggestion which will work for you. The suggestion is:
build as normal and then postprocess using install_name_tool
If you don't like this suggestion, it may be possible to adapt the hacky patch that started off that thread to work for you, and apply the patch to the generated libtool as part of bootstrap.sh configuration.

Can't get GCC's -static-libgcc working with DYLIB libraries on Mac OS X

I've installed GCC 4.6.3 into a non-system path on a Mac system and it works fine. However, GCC wants to use code from libgcc for all the binaries I compile, and running otool -L shows that these compiled programs look for libgcc_s.1.dylib in GCC's install path. I can override this by passing -static-libgcc, which just compiles the stuff needed into the binary and that's fine. The problem is this only seems to work with executables, not shared libraries. If I use GCC to compile some third-party lib I want to use in one of my programs as a .dylib, these libraries still look for libgcc_s.1.dylib in the local GCC install path even if I specify -static-libgcc! Needless to say, this is a problem as there's no guarantee that those libraries will find libgcc when run on some other system.
I tried this with ffmpeg. If I look at config.log, the -static-libgcc is most certainly being used. GCC is just not linking libgcc statically with the resulting dylibs. I even tried the -nostdlib, -nostartfiles and -nodefaultlibs options but they were ignored. Again, I checked config.log and they're definitely there!
I believe this is to do with throwing exceptions across the shared library boundary. This page says:
There are several situations in which an application should use the
shared libgcc instead of the static version. The most common of these
is when the application wishes to throw and catch exceptions across
different shared libraries. In that case, each of the libraries as
well as the application itself should use the shared libgcc.
Therefore, the G++ and GCJ drivers automatically add -shared-libgcc
whenever you build a shared library or a main executable, because C++
and Java programs typically use exceptions, so this is the right thing
to do.
The rest of that sections gives a possible workaround (it appears) and that is to use the GCC driver to link your shared library, however if the statically-linked library throws exceptions you'll probably get a Segmentation Violation.

Is it possible to build gcc statically using buildroot?

I am using buildroot to build a fresh gcc cross-compiler on a dedicated machine.
It worked fine, but I now need to run this gcc from another machine, on which I have not the same libc version :-(. Of course gcc then crashed.
Is it possible to build gcc statically using buildroot ?
You could try passing -static to the linker (via LDFLAGS), but be aware that full static linking is not supported by glibc anymore (resp. it needs a glibc build which supports static linking).
This is due to the fact that nss libraries (name server switch) will be loaded dynamically (unless you compile your own glibc - but that defeats the purpose of nss). This might be enough for you however to reduce dependencies against system libraries.
But I could assume that a statically linked gcc is fairly huge - this might result in long startup times.
If your objective is only to make a relocatable toolchain, statically link with expat, gmp, mpfr and mpc should enough. You can simply apply https://patchwork.ozlabs.org/patch/359841/

How to statically compile an SDL game on Windows

I have been trying to produce a statically linked "single binary" version of my game for windows. I want to link with sdl, sdl_image and sdl_mixer which in turn pull in a few support libraries. Unfortunately I haven't found a way to get them all to compile and link using cygwin/mingw/gcc. As far as I can tell all existing public versions are only shared libraries / dlls.
Please note that I'm not talking about licencing here. The source will be open thus the GPL/LGPLness of sdl is not relevant.
When compiling your project, you need to make just a couple changes to your makefile.
Instead of sdl-config --libs, use sdl-config --static-libs
Surround the use of the above-mentioned sdl-config --static-libs with -Wl,-Bstatic and -Wl,-Bdynamic. This tells GCC to force static linking, but only for the libraries specified between them.
If your makefile currently looks like:
SDLLIBS=`sdl-config --libs`
Change it to:
SDLLIBS=-Wl,-Bstatic `sdl-config --static-libs` -Wl,-Bdynamic
These are actually the same things you should do on Unix-like systems, but it usually doesn't cause as many errors on Unix-likes if you use the simpler -static flag to GCC, like it does on Windows.
Via this SDL mailing list post it seems that the sdl development tools ship with a sdl-config script that you can use with the --static-libs flag to determine what linker flags you need to use.
Environment: VMWare Virtual Machine with Windows 7 x64 and Equipment we Dev c + + build 7.4.2.569, complilador g+ + (tdm-1) 4.6.1
Once, SDL2-2.0.3 API installed as configuration Dev c ++ is not very clear what I've done as tradition requires command line.
The first problem is that Windows 7 appears to have changed the methodology and they go to his ball. Inventory. Ref. https://stackoverflow.com/users/464581/cheers-and-hth-alf
After the first hurdle, SDL_platform.h is that bad, it's down another, I do not remember where I downloaded, but the next does not work in the indicated version.
We must put SDL2.h ls in the directory of the executable.
D:\prg_desa\zsdl2>g++ bar.cpp main.cpp -o pepe1 -ID:\SDL2-2.0.3\i686-w64-mingw32\include\SDL2 -LD:\SDL2-2.0.3\i686-w64-mingw32\lib -lmingw32 -lSDL2main -lSDL2 -mwindow
I've finally compiled and works SDL2 testing.
That's because the SDL libs are under the LGPL-license.
If you want to static link the libs (you can do that if your recompile them. It needs some hacking into the makefiles though) you have to place your game under some compatible open source license as well.
The SDL-libs come as shared libraries because most programs that use them are closed source. The binary distribution comes in a form that most people need.
On my system (Ubuntu) I have to use the following flags:
-Wl,Bstatic -lSDL_image `sdl-config --libs` -lpng12 -lz -ltiff -ljpeg -lasound -laudio -lesd -Wl,-Bdynamic `directfb-config --libs` -lpulse-simple -lcaca -laa -ldl
That links SDL, SDL_image, and many of their dependencies as static. libdl you never want static, so making a fully-static binary that uses SDL_image is a poor idea. pulse,caca,aa, and directfb can probably be made static. I haven't got far enough to figure them out yet.

Resources