Question:
Why were static libraries /usr/lib/*.a dropped from Solaris 10?
So it is NOT possible to generate statically-linked object?
Dynamically-linked compilation, is the only option?
You can still create your own *.a libraries and link to them, but the system libraries will always be dynamically linked.
See: this post from blogs.oracle.com
If you pass the right flags to the linker, then you can create a static library or application. However, why would you want to? Static libraries are a pain to provide fixes for.
It's a wise decision. The static linking idea does not really work well. Thats why LSB (Linux Standard Base) Project also forbids static linking. Compatibility moved away from system calls to a higher level in the last two decades.
Can't say I've ever gone looking for them, but did you check the "additional options" (or whatever they call it) CD/DVD? I remember it had other random "missing" things...
Related
Why is it that some static libraries (lib*.a) can be linked in the same way that shared libraries (lib*.so) are linked (ld -l switch), but some can not?
I had always been taught that all libraries, static or not, can be linked with -l..., however I've run into one library so far (GLFW), which does nothing but spew "undefined reference" link errors if I attempt to link it this way.
According to the response on this question, the "proper" way to link static libraries is to include them directly, along with my own object files, rather than using -l. And, in the case of the GLFW library, this certainly solves the issue. But every other static library I'm using works just fine when linked with -l.
So:
What could cause this one library to not work when linked rather than included directly? If I knew the cause, maybe I could edit and recompile the library to fix the issue.
Is it true that you're not supposed to link static libraries the same way you link shared libraries? (And if not, why not?)
Is the linker still able to eliminate unused library functions from the output executable when the library is directly included in this way?
Thanks for the replies! Turns out the problem was due to link order. Apparently, if you use a library which in turn has other library dependencies, those other dependencies must be listed after the library, not before as I had been doing. Learned something new!
Have you cared to indicate to GCC the path of your library (using -L) ? By using -l solely, GCC will only be able to link libraries available in standard directories.
-L[path] -l[lib]
The correct way to link a static library is using -l, but that only works if the library can be found on the search path. If it's not then you can add the directory to the list using -L or name the file by name, as you say.
The same is true for shared libraries, actually, although they're more likely to be found, perhaps.
The reason is historical. The "ar" tool was original the file archive tool on PDP11 unix, though it was later replaced entirely by "tar" for that purpose. It stores files (object files, in this case) in a package. And there's a separate extension containing the symbol table for the linker to use. It's possible if you are manually managing files in the archive that the symbol table can get out of date.
The short answer is that you can use the "ranlib" tool on any archive to recreate the symbol table. Try that. More broadly, try to figure out where the corrupt libraries are coming from and fix that.
I'm still not 100% sure with the framework linking process, but from what I've seen here before nobody has asked a similar question, perhaps because this could be a silly question, but I'll give it a go anyway.
In my current X-Code project, I'm using a custom framework, say example.framework. At the moment, as far as I'm aware of, in order for the program to function with the framework, I need to have it either in /Library/Frameworks, or I need to have it copied into the bundle resources in the build phase.
Would anybody know about adding a framework to a project in a way that it gets compiled into the executable, so I don't have to include the raw framework with the app? I'd rather not share the whole framework...
Thank you in advance! Any suggestions are also welcome!
A Mac OS X framework is basically a shared library, meaning it's a separate binary.
Basically, when your main executable is launched, the OS will load the framework/dylib into memory, and map the symbols, so your main executable can access them.
Note that a framework/dylib (bundled into the application or not), does not need to contain the header files, as those are only needed at compilation time.
With Xcode, you can actually decide whether or not to include the header files, when you are copying the framework to its installation directory (see your build phases).
If you don't copy header files, people won't be able to use your framework/dylib (unless they reverse-engineer it, of course).
If you still think a framework is not suitable for your needs, you may want to create a static library instead.
A static library is a separate object file (usually .a) that is «included» with your final binary, at link time.
This way, you only have a single binary file, containing the code from the library and from your project.
There are appear to be methods of creating a fat static library ala "http://stackoverflow.com/questions/3520977/build-fat-static-library-device-simulator-using-xcode-and-sdk-4". Is this recommended? Any special steps (i.e., disabling thumb)
Also, if I do use the fat static library, will monotouch/xcode clear out any unused code in the final product?
You definitely need to turn Thumb code off so you can link properly against the library. As far as creating the fat static library goes, I can only say that anecdotally I've done this for a few third-party libraries that I've used and haven't run into issues.
I assume you already know that you need to create the bindings necessary to make calls to the objective-c library from your MonoTouch code and add extra gcc flags in the project properties to link in the static lib. If not, you can get that information on how to do that from the MonoTouch website.
Which headers should I not use if I don't want my program to be linked with any of msvc*.dll ?
At the moment my application uses:
kernel32
user32
shell32
msvcp90
msvcr90
I want to get rid of the bottom two files. I don't mind if I will have to rewrite certain aspects of the program.
Because I know if you code in C and then link it won't link any msvc's
I believe you have to change the way the CRT is linked into your program. I think for that you have to change the C++->Code Generation->Runtime-Library to the static version. This is for Visual Studio 2005, don't know about newer versions.
Those libraries contain the C++ runtime - heap management and other stuff hard to get rid from.
You could link the C++ statically instead - use "C++ -> Code Generation -> Runtime Library" setting. Then you will not need those .dll files. However this is not the recommended way - if a vulnerability is found in the C++ runtime you'll have to recompile and reship your program.
Static link is the right answer. A related bit of advice is to use depends.exe to see what functions your exe is actually hitting in the dependent dlls. Those dependencies might be due to explicit use on your part or due to CRT implementation that you don't explicitly invoke.
I have a gcc-compiled application linked against dynamic libraries. Is there a way to impose the order in which libraries are loaded? (In my case one library constructor uses resources set up by other library constructor).
Thanks.
gcc isn't in-charge of loading the libraries, either ld.so does it automatically when your program loads, or you do it manually as #jldupont suggests.
And ld.so might deliberately randomise the order to prevent return-to-stdlib attacks.
So either:
Load the libraries yourself.
Or remove the dependencies between the library load scripts.
Make the libraries contain the dependencies themselves (might work, might not)
That is when you get to the point of linking each shared library, make sure it includes -l<dependentlib> in the link command. You can test this by creating a trival program that links only with that shared library - if it builds and runs, then the library contains all necessary dependent libs. This might help if ld.so loads the libraries in dependency order - which I think it has to do.
You can use dlopen and load the libraries yourself: this way, you can have a finer grain control over the loading/unloading process. See here.
Of course, this isn't a "gcc" based solution and it requires reworking your application... Maybe you could explain the "problem" you are facing in a bit more details?
You can disregard my solution if it doesn't fit your needs. Cheers!