Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OSX: How do I convert a static library to a dynamic one?

Suppose I have a third party library called somelib.a on a Mac running Mountain Lion with Xcode 4.4 installed. I want to get a dynamic library out of it called somelib.dylib. An appropriate Linux command would be:

g++ -fpic -shared -Wl,-whole-archive somelib.a -Wl,-no-whole-archive -o somelib.so

where -whole-archive and -no-whole-archive are passed to the linker. When I do the equivalent for Mac:

g++ -fpic -shared -Wl,-whole-archive somelib.a -Wl,-no-whole-archive -o somelib.dylib

ld fails with an error:

ld: unknown option: -whole-archive

It seems that the ld on OSX is different from GNU ld. How do I have to modify above command so I will get the desired result?

Thank you in advance!

like image 956
hanslovsky Avatar asked Apr 18 '13 12:04

hanslovsky


People also ask

Which is better static or dynamic library?

In C exist two kinds of libraries the first ones are the static that allows us to link to the program and are not relevant during the runtime, and the other ones are called dynamic libraries those are preferable use when you run a lot of programs at the same time who are using the same library and you want to be more ...

Can we create dynamic library in iOS?

At the time this question was asked, Dynamic libraries were not supported by iOS and will result in your app getting rejected. Only static libraries are allowed.

Are dynamic and shared libraries the same?

Dynamic and shared libraries are usually the same. But in your case, it looks as if you are doing something special. In the shared library case, you specify the shared library at compile-time. When the app is started, the operating system will load the shared library before the application starts.


2 Answers

I found out the solution to my problem:

g++ -fpic -shared -Wl,-force_load somelib.a -o somelib.dylib

The required argument is -force_load:

  • Which needs to be followed by a single library you wanna ensure gets loaded.
  • I mean, it needs to be repeated for each library (unlike -noall_load approach, which wrapped them).
  • For example, -Wl,-force_load libYetAnotherFile.a (where -Wl, part is only required because we don't pass parameter directly to linker).

Note that Old answer (before edit) was using -noall_load instead, but nowadays that causes a linker error (as -noall_load has been removed, was obsolete previously).

like image 159
hanslovsky Avatar answered Oct 20 '22 08:10

hanslovsky


Note: A link for the documentation of the OSX ld linker.

http://www.unix.com/man-page/osx/1/ld/

I know it is late to give an answer for this, but I do not have enough reputation to make a comment on @hanslovsky answer. However, it helps me a lot to have the docs of the options too. It helps what the options do exactly, and that other options the ld linker also has. So I just wanted to share with others who finds linking an issue.

UPDATE:

After the comment from @GhostCat I have decided to expand my answer.

The docs for -all_load is:

-all_load

Loads all members of static archive libraries.

So it loads for all static libraries that you note. If you want something similar to --whole-archive and --no-whole-archive, then you need to use -force_load and -noall_load.

-force_load "path_to_archive"

Loads all members of the specified static archive library. Note: - all_load forces all members of all archives to be loaded.
This option allows you to target a specific archive.

-noall_load

This is the default. This option is obsolete.

Then you can define which libraries to fully load with -force_load and then later turn it off again with -noall_load.

like image 39
Martin Kristjansen Avatar answered Oct 20 '22 08:10

Martin Kristjansen