views:

222

answers:

2

Some build scripts (such as the one in numpy) simply does the following to make a gcc-compiled library archive work with the Visual Studio linker:

copy libfoo.a foo.lib

Surprisingly it seems to work. Does anyone know why?

+1  A: 

While I do not know any details for the lib format, I can give some information on the lib*.a format. This is just a archive of *.o object files, and can be manipulated with the ar program (part of binutils).

prompt>ar t /usr/lib64/libc.a | head
init-first.o
libc-start.o
sysdep.o
version.o
check_fds.o
libc-tls.o
elf-init.o
dso_handle.o
errno.o
errno-loc.o
prompt>ar t /usr/lib64/libc.a | wc
   1447    1447   16904
prompt>

I assume then that *.lib also is an archive of object files with either a identical or compatible content index.

hlovdal
Yes - library files are basically an archive of the object files. The actual question is of course if they are compatible in both-ways (windows msvc <-> unix gcc)
Sridhar Ratnakumar
+2  A: 

Depending on several factors, it may or may not work - and for a couple reasons. I take it you mean full-on, reversible compatibility.

  1. For implibs that are used to bind DLLs to executables, the answer is no.

    I once tried to link an MSVC++ implib with a gcc-produced dll. If the formats were compatible, it would have worked when I renamed the library libfoo.a. To get around this, there is a utility called reimp that can produce a suitable gcc implib from a DLL. To reverse the process, microsoft's `lib` tool can create a static implib from a .def file, which gcc can produce with a DLL should it be given the correct flags. [Search "reimp" at the mingw website for more info]
  2. C++-compiled object files are also incompatible because of Name Mangling.

    Different C++ compilers mangle variable and object names differently, resulting in "[object] code ... that is not usually linkable"
  3. For a static library compiled as plain old C? Yes

    I'd need a bit more information as to what type of project you are concerned with, but if it is C and the `copy libfoo.a foo.lib` hack worked, this may be the case. Try to see if this works in reverse with Mingw or Dev-C++. Edit: Actually, this will only work when the library is compiled with gcc on a Windows platform (and it works both ways!). the only exceptions to this AFAIK are cross-compiled libraries - MSVC refuses to take them, at least with Ubuntu-provided "i586-mingw32msvc-ar".

Another alternative explanation is that MSVC linker is compatible with the .a format for historical reasons. IIRC, it has been around since the days of UNIX. Again, though I could only see this working for pure C, and not C++.
EDIT: It is actually the other way around. The Windows version of the GCC toolkit creates static libraries that are compatible with Microsoft's COFF format.

saullawl
Actually the MinGW linker (or more correctly, the binutils port) is written to be compatible with MSVC COFF object file format, not the other way around. For plain C object files it should work for most cases.
Filip Navara
The libraries in question are from lapack - http://www.netlib.org/lapack/ - (libblas.a, libatlas.a, etc..)
Sridhar Ratnakumar
@Filip That explains everything. I was just testing it out, and the MingW build tools on Windows are 100% compatible with MSVC. I should point out that this is not the case for libfoo.a when it is cross-compiled for a Windows target. In this case, the format is somehow incompatible with the MS COFF format.
saullawl
Don't forget the issue of runtime compatibility. e.g., if you malloc() some memory with the Visual C++ CRT, and pass it to a LIB or DLL produced by GCC, and that LIB/DLL tries to free() said memory, Bad Things will happen. Same if you fopen() with VC's CRT, and fread() with GCC's.
anelson