39

How can i create a static build of a .c file on Mac OS X ? When i try:

gcc -o test Main.c -static

I get:

ld: library not found for -lcrt0.o
collect2: ld returned 1 exit status
Paul R
  • 208,748
  • 37
  • 389
  • 560
Daniel
  • 3,017
  • 12
  • 44
  • 61
  • possible duplicate of [How to static link on OS X](http://stackoverflow.com/questions/844819/how-to-static-link-on-os-x) – osgx Mar 10 '11 at 12:09

3 Answers3

34

It is not supported in Mac OS X's gcc:

http://discussions.apple.com/message.jspa?messageID=11053384

Perhaps that "-static" flag flat out won't work on MacOS X. Not all features of gcc are implemented on MacOS X. Apple won't even be using gcc in future versions of the OS.

I don't know how to link using "-static". I can't think of any reason to do so on MacOSX. If I knew why you wanted to use "-static" I might be more interested in the problem. Right now, I just don't get it. By asking for help, you are essentially asking for collaborators on the project - even if it is only for 10 minutes. You need to get me interested.

And http://developer.apple.com/library/mac/#qa/qa2001/qa1118.html

Static linking of user binaries is not supported on Mac OS X. Tying user binaries to the internal implementation of Mac OS X libraries and interfaces would limit our ability to update and enhance Mac OS X. Instead, dynamic linking is supported (linking against crt1.o automatically instead of looking for crt0.o, for example).

We strongly recommend that you consider the limitations of statically linking very carefully, and consider your customer and their needs, plus the long-term support you will need to provide.

Update: The prohibited is a static binary. But you still can compile some static library and use it with you another program. Program will be linked statically with your library, but other libraries like libc will be dynamic, so program will be a dynamic executable.

Community
  • 1
  • 1
osgx
  • 90,338
  • 53
  • 357
  • 513
  • one reason to would use `-static` in compilation will be in creating kernels. I recently came across this issue too. Does this mean one cannot develop a kernel on an OS X machine? – Igbanam Apr 14 '13 at 05:14
  • 2
    linking of kernel (OS kernel) is a special phase in any case. Kernel usually has no external libraries (so called freestanding mode of C language, `-nostdlib` and `-nodefaultlibs` option of gcc; no crt* files will be used), and is linked not to typical object format (ELF/Mach-O; or at least doesn't use dynamic linker ld.so). Special linker script and some postprocessing are used to convert object into raw binary boot image. So, I believe it is possible to compile Darwin kernel on Mac OS X. – osgx Apr 14 '13 at 12:32
  • 3
    I'm new to c, but I can see at least 3 reasons for static: pedagogic (following a c book), portability, stability (if you accidentally delete a linked file, the executable won't work). – ling Aug 19 '15 at 18:47
16

A binary that has no dynamic loaded libraries can not be built under OSX. I tried both apple llvm-gcc and macports gcc. However what no answer mentioned so far is that this is not needed. You can link the c/c++ library statically (and live with some dynamic part).

File hello.cpp:

#include <iostream>
using namespace std; 
int main()
{
    cout << "Hello World!";
}

Compile as usual:

g++ hello.cpp -o hello

Check linkage:

otool -L hello
hello:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

We can not get rid of the libSystem.B.dylib dependency but with macports gcc we can do this:

g++-mp-4.6 -static-libgcc -static-libstdc++ hello.cpp -o hello

otool -L hello
hello:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

Apparently just Apple does not support static linking:

llvm-g++ -static-libgcc -static-libstdc++ hello.cpp -o hello

otool -L hello
hello:
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
gbasler
  • 199
  • 1
  • 7
  • Does `-static-libgcc -static-libstdc++` work for gcc (not g++)? – Hanxue Dec 02 '13 at 15:14
  • `-static-libstdc++` is not needed for C programs, only for C++ programs. So, yes, both options will work with gcc too. – osgx Apr 13 '14 at 17:00
7

Imagine that you want to convert some functions into a library.

File: example.c

#include <stdio.h>

void aFunction( int a )
{
    printf( "%d\n", a );
}

File: example.h

void aFunction( int a );

File: main.c

#include "example.h"

int main( ) 
{
    aFunction( 3 );

    return 0;
}

To create the library:

gcc -c example.c
ar -r libmylibrary.a  example.o

To link the library:

gcc main.c -lmylibrary -L. -I.

And then the file example.c is a static build of the entire program.

momboco
  • 1,088
  • 8
  • 8
  • How can i confirm that its a static build? – Daniel Mar 10 '11 at 12:16
  • But the program a.out will be dynamic linked! – osgx Mar 10 '11 at 12:17
  • 3
    So in other words you can compile a library as static but not a program? – Daniel Mar 10 '11 at 12:18
  • the preprocessor will include the code of the library into the final executable. When the function "aFunction" is required, the o.s. doesn't have to bind with the library because the code is inside the executable. – momboco Mar 10 '11 at 12:21
  • @momboco, not a preprocessor, but a linker (`ld`) – osgx Mar 10 '11 at 12:23
  • I don't understand: compile a static program. The o.s. loads your program and execute it. On the middle, the process can load dynamic libraries with code. In other hand, the code is embedded in your binary before being executed. – momboco Mar 10 '11 at 12:26
  • `ar cr` on linux; `ar -r` on mac (just for Google). +1, that's what I was looking for. – Qix - MONICA WAS MISTREATED Sep 29 '14 at 21:01