4

I'm working on Ubuntu and I've made a static c library following the instructions on this site.

But the resulting .a package works only on the machine where it has been compiled.

I know that an .a archive contains object files (only one in my case), so, can I package together object files compiled in different machines (i386 and amd64) in a way so GCC can know which file should be using?

If I cannot, can at least make my library recognizable by other same-arch machines? (using -L. -llibraryname)

Example:

archive name "libvisualt64.a"

command: gcc -o main main.c -L. -lvisualt64

Says:

skipping incompatible ./libvisualt.a when searching for -lvisualt64
cannot find -lvisualt64
error: ld returned 1 exit status

In this case I compiled the source and built the archive in the same 64bit machine just yesterday. And yesterday it worked fine. This happens on 32bit machines too.

iehrlich
  • 3,572
  • 4
  • 34
  • 43
Lucide
  • 69
  • 1
  • 10
  • 1
    Can you perhaps elaborate on *how* it doesn't work on other systems using the same architecture? What errors do you get? – Some programmer dude Mar 30 '17 at 12:58
  • 3
    Apple has a dual-architecture system (it was quadruple at one time, when Macs used PPC chips). Normally, on Linux, you build a 32-but library and a 64-bit library and install them separately and link with them separately. – Jonathan Leffler Mar 30 '17 at 12:59
  • In any case, this is only peripherally related to C. You can build libraries of functions whose source is written in C, but such libraries are not themselves a C thing. – John Bollinger Mar 30 '17 at 13:24
  • 1
    Use `file` command to inspect the files. Also, use `ar` command to inspect the *.a* archive (read the man page to find out how, probably add `v` for verbose output). – hyde Mar 30 '17 at 13:53
  • Why not just ship a bunch of .a files in a directory structure like `.../artemis/$(uname -i)/$(uname -s)/libvisualt64.a"? Selecting the lib path in your build system is much simpler than using an exotic linker format. – Useless Mar 30 '17 at 13:58

1 Answers1

1

Linux uses an executable file format called ELF. An ELF file can only contain the necessary machine code for a single architecture.

There should be no problems using your library on another machine of the same architecture. The only potential issue could be related to dependencies.

If you really want a single binary to support multiple architectures, then you may be interested in FatELF... Though it is not supported without a kernel patch:

Up to now the FatELF is not integrated in the kernel mainline.


To address your edit, it is likely that your libvisualt64.a is not built for the same architecture that gcc is targeting...

You'll need to extract the object files from the archive, and compare them with gcc's target:

ar xv ${STATIC_LIBRARY}
file *.o
gcc -v 2>&1 | grep '^Target: '

I see the following (compatible) outputs:

test.o: ELF 64-bit LSB  relocatable, x86-64, version 1 (SYSV), not stripped
Target: x86_64-linux-gnu
Attie
  • 6,690
  • 2
  • 24
  • 34
  • 1
    You have dependence issue when you import exotic libraries? I think mine are quite standard: stdio.h stdlib.h string.h termios.h unistd.h time.h stdarg.h – Lucide Mar 30 '17 at 13:40
  • @Artemis These all sound standard enough... please see my edit, and report back. – Attie Mar 30 '17 at 13:44
  • I got: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped Target: i686-linux-gnu Eww.. is this possibile on a 64bit os? So i made two 32bit libraries.. That leaves the fact That neither 32bit versions are recognized by other 32bit machines – Lucide Mar 30 '17 at 14:03
  • Well there you go! :-) `x86-64` is not compatible with `i686`. Are you definately using the same toolchain between sessions? run: `which gcc` each time, and record it session to session. – Attie Mar 30 '17 at 14:04