Using gcc libraries with mingw for cross-compiling? - windows

While I am sure that gcc libraries (.a) are incompatible with mingw lubraries (also .a), I want to know. Can I cross-compile a windows executable with mingw using the gcc .a library generated for unix systems?
In code form, keep in mind this is a unix system:
cd mylibrarydirectory/
make #produces mylibrary.a
cd ../myprogramdirectory/
gcc -o UnixExecutable mysrc.c -L../mylibrary.a
#and I get a valid unix executable
i586-mingw32msvc-gcc -o Win32Executable.exe mysrc.c -L../mylibrary.a
#will I get a valid windows executable?

No. You have to recompile the library for Windows.
The second command should give an "incompatible library format" or something error. Or at least undefined references to whatever is linked in.

Related

Modify default library search dirs that gcc passes to ld

I want to force new GCC 12 on my old debian (that only has GCC 6 by default) to use fresh libstdc++ headers with new header-only features, but link with old stdlibc++,gcc_s (and other system/compiler libs used by GCC6) to keep binary compatibility with native runtime of old debian (so that users of old GCC6 can link with my binaries without having GCC12).
Of course I know that some functionality in the old runtime will be missing, and ABI is also different, but I guess I can fight with that. Afterall RedHat seems to be using similar scheme for their devtoolset packages (they try to link missing functionality of new runtime statically to your binary if these symbols are not found in native old runtime)
So far I am stuck with -L arguments that GCC is passing to ld.
Here is complete output of /usr/local/gcc12/bin/x86_64-linux-gnu-gcc-12 main.cpp -Wl,-v -v command for simple hello-world main.cpp:
https://pastebin.com/JhYSfg4x
The question: Where does GCC take all these -L paths from, and how do I remove/modify them? I don't want to accidentally link with new version of libraries that were built with GCC12:
-L/usr/lib/gcc/x86_64-linux-gnu -L/usr/local/gcc12/lib/gcc/x86_64-linux-gnu/12 -L/usr/local/gcc12/lib/gcc/x86_64-linux-gnu/12/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc -L/usr/local/gcc12/lib/gcc/x86_64-linux-gnu/12/../../.. /tmp/ccXfhCs4.o
System ld.conf does not mention any paths to /usr/local/gcc12 folder.
-nostdlib and -nodefaultlibs are removing some standard -l flags, but they are not doing anything to -L flags.
Update: I ended up just removing all *.a, .so, *.la files from include, lib and lib64 folders of gcc12, and I also added -L path to native libraries. This way I am sure gcc12 can't pickup one of its libraries for li nking. Not sure if this is good solution, but it works.

How to link and compile using specific library version installed at custom location?

I am trying to compile a program which uses GSL, in fact I am already able to compile it successfully on my local machine using
g++ -o program program.c prog0.o -L/usr/local/lib -lgsl -lgslcblas -lm
My problem is that I need to compile this program on a work machine in a shared system, but I know the program will not compile with an up to date version of GSL, so I need to install and use an older version.
I did this on my own system using the default installation, so the relevant files are located in /usr/local/lib on my local machine, and the compilation works for me with the above command.
But since the work machine is in a shared system, I cannot mess with the default directories, so I installed the correct GSL version on the work machine in my directory under /home/myname/gsl/.
So on the work machine the folder /home/myname/gsl/lib contains the same relevant files as the folder /usr/local/lib on my machine.
Now I did various attempts to try and tell g++ to use this custom installation folder, which I thought would come down to
g++ -o program program.c prog0.o -L/home/myname/gsl/lib -lgsl -lgslcblas -lm
but no success. No matter what I did g++ always used the GSL version installed on the shared system, even using just
g++ -o program program.c prog0.o
I only started programming C/C++ not long ago and only know the very basics of how to compile programs, so this linking thing is still always confusing me..
But as far as I can tell -L/dir/ should tell g++ to use the library in /dir/ and -lgsl -lgslcblas are the files which it should look for in that library... ?
But it seems g++ doesn't care what library I tell it here, it always seems to use whatever is in the PATH of the shared work system, which seems to include this up-to-date version of GSL that I cannot use. But I also cannot change the PATH since I only have access to my own subdirectories on the work system..
So how do I tell g++ to ignore the default version of GSL and use the one I installed manually at /home/myname/gsl/ ?
I figured out the answer, it is actually simple. The problem was just my lack of understanding proper usage of outside libraries and trying to fix the compilation command was the wrong approach.
In the code in program.c, gsl was included with
#include <gsl/gsl_blas.h>
and so on. Of course, the "<>" directly tell the compiler to look in known include directories, where the up-to-date GSL is installed on the shared system.. So the way to use a custom version was just to instead use
#include "/home/myname/gsl/lib/gsl_blas.h"
and so on, directly specifying that I want to use my custom installation.
I then compiled with
g++ -o program program.c prog0.o /home/myname/gsl/lib/libgsl.so /home/myname/gsl/lib/libgslcblas.so -lm
and it compiles successfully.
(This brought up some other unclarities for me, but at least this specific problem is solved.)

How to compile fortran code to run without gfortran installed

I have downloaded Bellhop, which is an underwater acoustic simulator written in Fortran. It can be found here with the Makefile.
Question 1: I would like to know if it is possible to compile Fortran code, including everything needed, so a user without gfortran installed, can run it.
I have read here the following:
static linking
This section does not apply to Windows users, except for Cygwin users with gcc4-4.3.2-2 or later.
gfortran is composed of two main parts: the compiler, which creates the executable program from your code, and the library, which is used when you run your program afterwards. That explains why, if gfortran is installed in a non-standard directory, it may compile your code fine but the executable may fail with an error message like library not found. One way to avoid this (more ideas can be found on the binaries page) is to use the so-called "static linking", available with option -static gfortran then put the library code inside the program created, thus enabling it to run without the library present (like, on a computer where gfortran is not installed). Complete example is:
gfortran -static myfile.f -o program.exe
Reading this, I suppose that it is possible to do what I'm asking but I'm not very familiarized with fortran and makefiles. I don't understand this:
put the library code inside the program created
Question 2: How can I put the library code inside the program? Where can I find the library? What does "inside the program" means?
I'm running OSX 10.9.4 and gfortran
I solved my problem about compiling Fortran code with gfortran using static libraries.
As #M.S.B. said, using static-libgfortran worked for me under MacOS.
If somebody is having issues with linking the libquadmath.0.dylb library, remove libquadmath.0.dylib and libquadmath.dylib from /usr/local/gfortran/lib/
This doest the trick. Further information can be found here
I think the meaning of the bold part is actually
gfortran then puts the library code inside the
program created
That means using -static should be enough, there is no additional step. Just be advised you will need a static version of all the libraries that you link with.
I know this is very old tracker, but maybe somebody will be still interested in the solution that works.
Let's say we have code:
! fort_sample.f90
program main
write (*,*) 'Hello'
stop
end
First, compile the stuff:
gfortran -c -o fort_sample.o fort_sample.f90
Then, link stuff
ld -o ./fort_sample -no_compact_unwind \
-arch x86_64 -macosx_version_min 10.12.0 \
-lSystem \
/usr/local/gfortran/lib/libgfortran.a \
/usr/local/gfortran/lib/libquadmath.a \
/usr/local/gfortran/lib/gcc/x86_64-apple-darwin16/6.3.0/libgcc.a \
fort_sample.o
You can execute it
./fort_sample
Hello
You can notice that quadmath is no longer there
> otool -L fort_sample
fort_sample:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.51.1)
I guess this is what you were looking for in a first place. No removing dylibs, no symbolic links, etc.
The current version of the option is -static-libgfortran. This means that the Fortran specific libraries of gfortran will be included into the executable. These are libraries are automatically found for a good installation of gfortran. This should produce an executable that should run on other computers with the same OS, even if that computer doesn't have gfortran installed. This option likely doesn't statically link all libraries, so there is some risk that some other shared library used on your computer won't be available on the other computer.

mingw32-make tries to create subfolder .lib an illegal name

I am trying to compile a project that required freetype library so I was figuring out how to install freetype to mingw32 and the more safer way is to compile it.
Anyway the problem was compiling freetype-2.4.11
I went into bash provided in msys
I did ./configure within freetype's main dir and everything looks fine
next I did mingw32-make which created the problem
libtool: compile: gcc -pedantic -ansi -Ig:/Downloads/freetype-2.4.11/objs -I./b
uilds/unix -Ig:/Downloads/freetype-2.4.11/include -c -Wall -g -O2 "-DFT_CONFIG_C
ONFIG_H=<ftconfig.h>" -DFT2_BUILD_LIBRARY "-DFT_CONFIG_MODULES_H=<ftmodule.h>" g
:/Downloads/freetype-2.4.11/src/base/ftsystem.c -DDLL_EXPORT -DPIC -o g:/Downlo
ads/freetype-2.4.11/objs/.libs/ftsystem.o
Assembler messages:
Fatal error: can't create g:/Downloads/freetype-2.4.11/objs/.libs/ftsystem.o: No
such file or directory
g:/Downloads/freetype-2.4.11/builds/freetype.mk:198: recipe for target 'g:/Downl
oads/freetype-2.4.11/objs/ftsystem.lo' failed
mingw32-make[4]: *** [g:/Downloads/freetype-2.4.11/objs/ftsystem.lo] Error 1
g:/Downloads/freetype-2.4.11/objs/.libs/ftsystem.o seemed like it is trying to use a directory that is illegal in windows.
Thanks in advance
Try to use make instead (i.e. the one from MSYS distribution), and avoid using mingw32-make (from MinGW distribution) in the future to save yourself time and nerves. Extract from MinGW Wiki:
What's the difference between make and mingw32-make?
The "native" (i.e.: MSVCRT dependent) port of make is lacking in some functionality and has modified functionality due to the lack of POSIX on Win32. There also exists a version of make in the MSYS distribution that is dependent on the MSYS runtime. This port operates more as make was intended to operate and gives less headaches during execution. Based on this, the MinGW developers/maintainers/packagers decided it would be best to rename the native version so that both the "native" version and the MSYS version could be present at the same time without file name collision.

boost_thread not linking on NaCl

I receive this error when linking -lboost_thread into my executable on google Native Client (pepper_19):
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/x86_64-nacl/usr/lib/libboost_thread.a: could not read symbols: Archive has no index; run ranlib to add one
I compiled boost according to the instructions at naclports here: http://code.google.com/p/naclports/wiki/InstallingSDL (except using the boost library directory instead of SDL... I also used this same process to correctly compile NaCl zlib library)
cd naclports/src/libraries/boost_1_47_0
export NACL_PACKAGES_BITSIZE=32; ./nacl-boost_1_47_0.sh
export NACL_PACKAGES_BITSIZE=64; ./nacl-boost_1_47_0.sh
this generates the libboost_thread.a file and puts it them in the /usr/lib directories of my NACL installation. I thought maybe somehow I mistakenly built a wrong type of library for linking with NaCl. Is there a way to check this and/or fix it?
I tried:
cd naclports/src/out/repository-x86_64/boost_1_47_0/bin.v2/libs/thread/build/darwin-4.2.1/release/link-static/threading-multi
nm libboost_thread.a
and this yielded:
libboost_thread.a(thread.o):
0000000000052d08 s EH_frame0
000000000004f50c s GCC_except_table100
000000000004f534 s GCC_except_table101
000000000004f574 s GCC_except_table102
000000000004f5c0 s GCC_except_table103
000000000004f600 s GCC_except_table104
000000000004f64c s GCC_except_table105
000000000004f68c s GCC_except_table106
000000000004f6d8 s GCC_except_table107
.
.
.
.
etc, etc..
However then I ran:
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/bin/x86_64-nacl-nm libboost_thread.a
and got:
__.SYMDEF SORTED: File format not recognized
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/bin/x86_64-nacl-nm: thread.o: File format not recognized
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/bin/x86_64-nacl-nm: once.o: File format not recognized
And finally. I ran:
file pthread/thread.o
pthread/thread.o: Mach-O 64-bit object x86_64
however the same command on a zlib object file results in:
ELF 64-bit LSB relocatable, x86-64, version 1, not stripped
I would appreciate advice on building a correctly cross-compiled NaCl libboost_thread.a
Thank you.
Some libraries in NaCl ports can only be built on linux. So you have to either find why boost decides to use system ar instead of x86_64-nacl-ar or install VM with linux where they are the same.

Resources