Using libraries compiled with GCC in a VisualC++ project (and vice versa) - visual-c++

It's possible to use code (and libraries) compiled with VisualC++ (so with .lib extension) in a project that will use GCC as compiler (and vice versa)? Or I have to rebuild them?
I'm trying to use SOCI 3.1 libraries that I have compiled with VisualC++ in a project that has GCC as compiler, but I'm getting some errors, and I don't know why..

You have to produce binaries for GCC using MinGW tools: reimp and dlltool. Here is MinGW wiki with complete explanation of the procedures: MSVC and MinGW DLLs
Short example:
reimp -d libmysql.lib
dlltool -k --input-def libmysql.def --dllname libmysql.dll --output-lib libmysql.a
reimp libmysql.lib
By the way, here is related thread on SOCI users mailing list which: MySQL Build fails. Look for useful links given in the thread.

Related

Use private C++ runtime library on linux

In Windows, the dynamic loader always looks for modules in the path of the loaded executable first, making it possible to have private libraries without affecting system libraries.
The dynamic loader on Linux only looks for libraries in a fixed path, in the sense that it is independent on the chosen binary. I needed GCC 5 for its overflow checked arithmetic functions, but since the C++ ABI changed between 4.9 and 5, some applications became unstable and recompiling them solved the issue. While waiting for my distro [kubuntu] to upgrade the default compiler, is it possible to have newly compiled application linking to the new runtime, while packaged application still links to the old library, either by static linkage, or something that mimics the Windows behavior?
One way of emulating it would be to create a wrapper script
#!/bin/bash
LD_LIBRARY_PATH=$(dirname $(which your_file)) your_file
And after the linking step copy the affected library but it is sort of a hack.
You can use rpath.
Let's say your "new ABI" shared libraries are in /usr/local/newapi-libs.
gcc -L/usr/local/newapi-libs
-Wl,-rpath,/usr/local/newapi-libs
program.cpp -o program -lsomething`
The -rpath option of the linker is the runtime counterpart to -L. When a program compiled this way is run, the linker will first look in /usr/local/newapi-libs before searching the system library paths.
More information here and here.
You can emulate the Windows behavior of looking in the executable's directory by specifying -Wl,-rpath,.
[edit] added missing -L parameter and dashes before rpath.

How do I compile and link a 32-bit Windows executable using mingw-w64

I am using Ubuntu 13.04 and installed mingw-w64 using apt-get install mingw-w64. I can compile and link a working 64-bit version of my program with the following command:
x86_64-w64-mingw32-g++ code.cpp -o app.exe
Which generates a 64-bit app.exe file.
What binary or command line flags do I use to generate a 32-bit version of app.exe?
That depends on which variant of toolchain you're currently using. Both DWARF and SEH variants (which come starting from GCC 4.8.0) are only single-target. You can see it yourself by inspecting the directory structure of their distributions, i.e. they contain only the libraries with either 64- or 32-bit addressing, but not both. On the other hand, plain old SJLJ distributions are indeed dual-target, and in order to build 32-bit target, just supply -m32 flag. If that doesn't work, then just build with i686-w64-mingw32-g++.
BONUS
By the way, the three corresponding dynamic-link libraries (DLLs) implementing each GCC exception model are
libgcc_s_dw2-1.dll (DWARF);
libgcc_s_seh-1.dll (SEH);
libgcc_s_sjlj-1.dll (SJLJ).
Hence, to find out what exception model does your current MinGW-w64 distribution exactly provide, you can either
inspect directory and file structure of MinGW-w64 installation in hope to locate one of those DLLs (typically in bin); or
build some real or test C++ code involving exception handling to force linkage with one of those DLLs and then see on which one of those DLLs does the built target depend (for example, can be seen with Dependency Walker on Windows); or
take brute force approach and compile some test code to assembly (instead of machine code) and look for presence of references like ___gxx_personality_v* (DWARF), ___gxx_personality_seh* (SEH), ___gxx_personality_sj* (SJLJ); see Obtaining current GCC exception model.

How to see which static libraries were used for gcc/g++ compilation from the generated binary?

Context: I'm using a linux toolchain (includes g++, other build tools, libs, headers, etc) to build my code with statically linked libraries. I want to ensure that I'm using ONLY libraries/headers from my toolchain, not the default ones on the build machine. I can use strace to see what g++ is doing (which libraries it is using) while it is compiling which would be helpful in a normal scenario - but my build system has many wrappers around g++ that hide all of the output.
Question: is there a way to obtain from a statically-linked binary any useful information regarding the library and header files which were used to create the binary? I've taken a look at the objdump tool but I'm not sure if it will help much.
Just pass -v to g++ or gcc at link time. It will show all the linked libraries. Perhaps try make CC='gcc -v' CXX='g++ -v'
More generally, -v passed g++ or gcc shows you the underlying command with its arguments because gcc or g++ is just a driver program (starting cc1, ld or collect2, as, ...)
By passing the -H flag to GCC (i.e. g++ or gcc) you can see every included header. So you can check that only the heanders you expect are included.
You cannot see what static library has been linked, because linking a static library just means linking the relevant object file members in it, so a static library can (and usually is) linked in only partly.
You could use the nm command to find names from such libraries.
If you can simply recompile, then there are ways (using some of the techniques that Basile explained) to get the headers and libraries (static or dynamic) but, unfortunately, there is no way to know which libraries were used after the compilation is complete.

What is libg2c library?

I have found the code which links against of 'g2c' library. Why do I need it? Just would like to understand why it might be important and what it does in general.
Thanks!
What is GNU Fortran?
g77 consists of several components:
A modified version of the gcc command, which also might be installed as the system's cc command. (In many cases, cc refers to the system's “native” C compiler, which might be a non-GNU compiler, or an older version of gcc considered more stable or that is used to build the operating system kernel.)
The g77 command itself, which also might be installed as the system's f77 command.
The libg2c run-time library. This library contains the machine code needed to support capabilities of the Fortran language that are not directly provided by the machine code generated by the g77 compilation phase.
libg2c is just the unique name g77 gives to its version of libf2c to distinguish it from any copy of libf2c installed from f2c (or versions of g77 that built libf2c under that same name) on the system.
You may think of it as, libg2c is to g77 as libc is to gcc.
Note that as of the GCC 4.x series, g77 has been discontinued, replaced by gfortran, which produces programs that do not require an extra libg2c runtime library.
"This library contains the machine code needed to support capabilities of the Fortran language that are not directly provided by the machine code generated by the g77 compilation phase."
from this link
Installing compat-gcc-34-g77 solves this requirement.
(gcc-34 must be replaced by your gcc version)

How to GCC compile without _alloca?

For some reason, I should use gcc to compile a C file, then link against Visual C++ 2008 project.
(I used the current latest gcc version: cygwin gcc 4.3.4 20090804.)
But there is one problem: gcc always allocate a big array with _alloca,
and VC linker can't resolve the symbol __alloca.
for example,
int func()
{
int big[10240];
....
}
this code makes the _alloca dependency although I didn't call the _alloca function explicitly.
(array size matters. if i change 10240 -> 128, everything ok)
I tried gcc option -fno-builtin-alloca or -fno-builtin, but no luck.
Is it possible to make gcc not to use _alloca ? (or adjust the threshold?)
Best thing to do would be to compile all code with VC++. If that's not possible..
You should use the mingw gcc instead of the cygwin one. It's designed to output code that will be linked against the VC++ runtime, not the cygwin libraries. In particular, it will call the VC++ runtime function __chkstk instead of __alloca.
You could just write your own _alloca routine and link against that. Look at the gcc library source to see what it's supposed to do.
It looks like _alloca has been deprecated by Microsoft and is no longer in their runtime libraries after VS2005. Newer runtime libraries support _malloca.
Your options don't look good. You can try to build with VS2005 instead. Perhaps cygwin has an option where you can tell it you are using a newer runtime library (and if they don't support that yet, you could file it as a feature request).
some related discussions:
cygwin: gcc and alloca
GNU Compiler Collection (GCC) Internals
gcc and alloca

Resources