注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

熊猫正正的博客

熊猫正正的天空

 
 
 

日志

 
 

Static and Dynamic Libraries  

2015-11-18 10:10:59|  分类: ios开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Linking Libraries

The act of linking libraries is a form of code dependency management. When any app is run, its executable code is loaded into memory. Additionally, any code libraries that it depends on are also loaded into memory. There are two type of linking: static, and dynamic. Both offer different benefits to the developer and should be used according to these benefits. This blog post will cover the benefits offered by each and then explain the basics of how to create and link your own libraries on OS X and iOS.


Dynamic Linking

Dynamic linking is most commonly used on OS X and iOS. When dynamic libraries are linked, none of the library's code is included directly into the linked target. Instead, the libraries are loaded into memory at runtime prior to having symbols getting resolved. Because the code isn't statically linked into the executable binary, there are some benefits from loading at runtime. Mainly, the libraries can be updated with new features or bug-fixes without having to recompile and relink executable. In addition, being loaded at runtime means that individual code libraries can have their own initializers and clean up after their own tasks before being unloaded from memory. For more information on overview and design, see Apple's Dynamic Library Programming Topics.

? Libraries

Dynamic libraries are a type of Mach-O binary1 that is loaded at launch or runtime of an application. Since the executable code in a dynamic library isn't statically linked into target executable, this affords some benefits when needing to reuse the same code. For example, if you have an application and a daemon or extension that needs to make use of the same code, that code only has to exist in a single location -- the dynamic library, rather than in both the executable's binary and the daemon's binary. Since dynamic libraries are loaded at runtime, the library is responsible for telling the linker what additional code is needed. This removes the burden of managing what all of the code that you use needs to operate.

? Frameworks

Dynamic frameworks are similar to dynamic libraries. Both are dynamically linkable libraries, except a dynamic framework is a dynamic library embedded in a bundle. This allows for versioning of a dynamic library and sorting additional assets that are used by the library's code.

? Building

This is a walk-through of the steps required to build de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libfoo_dynamic.dylibde>

bar.h

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >#ifndef __foo__bar__
#define __foo__bar__

#include <stdio.h>

int fizz();

#endif /* defined(__foo__bar__) */de>

bar.c

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >#include "bar.h"
#include <CoreFoundation/CoreFoundation.h>

int fizz() {
    CFShow(CFSTR("buzz"));
    
    return 0;
}de>

Starting out with the files de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >bar.hde> and de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >bar.cde>. The header file defines the function de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizz()de>, which returns an integer value. The implementation file imports the CoreFoundation framework and implements the function de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizzde> to print the strings "buzz" before returning de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >0de>.

Compiling:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ clang -c bar.c -o bar.ode>

This creates the object file2, Mach-O binary with type de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >MH_OBJECTde>, named "bar". One of these will be generated for each of the files compiled in the library.

Creating Library:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ libtool -dynamic bar.o -o libfoo_dynamic.dylib -framework CoreFoundation -lSystemde>

This creates the dylib (dynamic library) and links against de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libSystemde> and de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >CoreFoundation.frameworkde>. The dylib is a Mach-O binary file with a type de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >MH_DYLIBde>. This will be loaded dynamically at launch time by dyld as a dependency of another binary.

? Linking

main.c

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >#include "bar.h"

int main() {
    return fizz();
}de>

In this example, importing the "bar.h" header for the dynamic library, and calling de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizz()de> directly.

Compiling:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ clang -c main.c -o main.ode>

This will generate the object file for main.

Linking:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ ld main.o -lSystem -L. -lfoo_dynamic -o test_dynamicde>

This will generate a binary executable from the main object file, also passing

  • de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >-lSystemde> for de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >dyld_stub_binderde>
  • de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >-lfoo_dynamicde> for linking against de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libfoo_dynamic.dylibde>

and finally, outputting a binary named de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >test_dynamicde>.

Running:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ ./test_dynamic
buzzde>

Symbols:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ nm test_dynamic 
0000000000001000 A __mh_execute_header
                 U _fizz
0000000000001fa0 T _main
                 U dyld_stub_binderde>

This lists all of the symbols in the main binary. Both the symbol de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >mainde> and de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizzde> are listed here. The symbol de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizzde>does not have an address, because it does not exist inside of the main binary, it exists in the dynamic library that was created. This symbol will be resolved at launch time, after all the referenced dependencies are loaded into memory.

References:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ otool -L test_dynamic 
test_dynamic:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
    libfoo_dynamic.dylib (compatibility version 0.0.0, current version 0.0.0)de>

The resulting binary only links against libSystem and the dylib that was created. The library de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >foo_dynamicde> is responsible for linking against any additional libraries it needs. This is resolved at launch time, dynamically. In this case, the search path for de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libfoo_dynamic.dylibde> is going to be the same as the search location as the main executable.

Dynamic libraries and frameworks are loaded at launch time by the dynamic linker. They have associated search paths to help the linker find where they are located on the file system and load them.


Static Linking

Unlike dynamic, linking static libraries includes the object file code from the library into the target's binary. This results in a larger size on disk and slower launch times. Because the library's code is added directly to the linked target's binary, it means that to update any code in the library, the linked target would also have to be rebuilt.

Up until iOS 8, statically linked libraries were the de-facto way to ship and include any third-party code in an application.

Note: this is not to be confused with statically linking binaries.

? Libraries

A static library is a container for a set of object files. Static libraries use the file extension ".a", which comes from the (ar)chive file3 type. An archive file was designed to contain a collection of files. This is ideal for the transport and use of many object files that comprise a single code library. However the linker can only use object files of a single architecture, so there are two different container formats for static libraries based on if they support single or multiple architectures.

All object files of the same architecture are stored in a single archive file. This is the type of container file that the linker expects per architecture. The object files are packaged by the utility ar, which stores the contents of each object file. OS X uses an implementation of de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >arde> that is similar to the BSD variant; the task of organizing the symbol lookup and table creation to a tool called de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >ranlibde>. On OS X, this is an alias for libtool. This utility is responsible for mapping the symbols stored in the object files and will warn if there are mismatching architectures used. This will generate an archive file that can be examined and operated on using the de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >arde> utility.

Since a single archive file can only support a single architecture, a separate file format is used to act as a single container for multiple libraries. The file format chosen for this was the fat Mach-O binary. Due to this change in file type, de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >arde> can no longer operate on the static library. A fat Mach-O binary is a very simple container format that can house multiple files of different architectures.

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >// This is at the very beginning of the file
struct fat_header {
    uint32_t magic;     // This indicates the endianness of the binary file
    uint32_t nfat_arch; // This indicates how many architecture headers are defined for the file
};

// This is the architecture header definition, these definitions immediately follow the 'fat_header'
struct fat_arch {
    cpu_type_t cputype;         // This defines the CPU family type: "Intel", "ARM", "PPC"
    cpu_subtype_t cpusubtype;   // This defines the CPU variant for the family type: "i386", "x86_64", "armv7", "armv7s", "ppc64"
    uint32_t offset;            // Offset in the file where the architecture specific data starts
    uint32_t size;              // Length of the architecture specific data in the file
    uint32_t align;             // Power of 2 alignment data for the architecture type
};de>

While this is a Mach-O binary file type, it strictly acts as a safe container for multiple architectures. This format is used to store a copy of the library for each desired architecture type. To modify a static library that uses the fat Mach-O binary file type, the command lipo must be used. This can also extract a copy of the static library based on a specific architecture.

? Frameworks

A static framework is a bundle containing a static library file. These frameworks are just a convenient way to publish a static library that uses external assets; such as images, fonts, or language files. In addition, static frameworks behave exactly like static libraries. They are statically linked into the executable binary, not loaded at runtime.

? Building

This is a walk-through of building de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libfoo_static.ade>. This uses the same files used in the dynamic library example.

bar.h

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >#ifndef __foo__bar__
#define __foo__bar__

#include <stdio.h>

int fizz();

#endif /* defined(__foo__bar__) */de>

bar.c

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >#include "bar.h"
#include <CoreFoundation/CoreFoundation.h>

int fizz() {
    CFShow(CFSTR("buzz"));
    
    return 0;
}de>

Compiling:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ clang -c bar.c -o bar.ode>

This creates the object file named "bar". Again, one of these will be generated for each of the files compiled in the library.

Creating Library:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ ar -rcs libfoo_static.a bar.o
or
$ libtool -static bar.o -o libfoo_static.ade>

Unlike the dynamic library, when creating the static library there are no other libraries that are linked against it. This is because the (ar)chive file is just a container for the object files that need to be built. By running either de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >arde> orde style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libtoolde> on the set of object files generated by the compiler, they will be packaged up into an archive that can contain multiple sets of architecture and symbol definitions.

Running de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >arde> directly will produce a single archive file with just the object files that were passed. It will then callde style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >ranlibde> on this archive file it creates to sort the object files and also resolve any duplicate symbol names contained in the archive. Using de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libtoolde> instead results in the same behavior and output, the code path for it changes slightly to call against de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libstuffde> instead of the tool de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >arde>.

Due to the fact this is not an executable binary file, static libraries do not retain any linkage they might need. This pushes the burden of tracking which dependencies to use onto the linked target executable file rather than on the static library itself. Luckily, Apple has implemented a load command for handling this, de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >LC_LINKER_OPTIONde>. This appears in a target's build settings in Xcode under the name "Link Frameworks Automatically". Enabling this option will append new load commands to each object file that specify linker flags that should be used with each object file. These flags can be displayed by using the following command:

de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >$ otool -l <static library> | grep LC_LINKER_OPTION -A 4de>

? Linking

main.c

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >#include "bar.h"

int main() {
    return fizz();
}de>

In this example, importing the "bar.h" header for the static library, and calling de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizz()de> directly.

Compiling:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ clang -c main.c -o main.ode>

This will generate the object file for main.

Linking:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ ld main.o -framework CoreFoundation -lSystem -L. -lfoo_static -o test_staticde>

This will generate a binary executable from the main object file, also passing

  • de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >-lSystemde> for de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >dyld_stub_binderde>
  • de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >-framework CoreFoundationde> for linking against de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >CoreFoundation.frameworkde>
  • de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >-lfoo_staticde> for linking against de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libfoo_static.ade>

and finally, outputting a binary named de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >test_staticde>.

Running:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ ./test_static
buzzde>

Symbols:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ nm test_static
                 U _CFShow
                 U ___CFConstantStringClassReference
0000000000001000 A __mh_execute_header
0000000000001f90 T _fizz
0000000000001f70 T _main
                 U dyld_stub_binderde>

Here we see that the symbol de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizzde>, which was part of the static library, has an address associated with it. This is because the executable code that was associated with calling the function de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >fizz()de> is now stored inside the main binary executable. Additionally there are references to de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >CFShowde> and de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >CFConstantStringClassReferencede>, which exist as part of the CoreFoundation framework.

References:

de style="-webkit-print-color-adjust: exact; border: none; border-radius: 3px; margin: 0px; padding: 0px; background: transparent;"  >$ otool -L test_static 
test_static:
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.17.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)de>

When checking the list of linked libraries via otool, the main binary only links against libsystem. This is because now that the symbols from de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libfoo_staticde> have been added to the main binary file. Since the code from de style="-webkit-print-color-adjust: exact; border: 1px solid rgb(234, 234, 234); border-radius: 3px; margin: 0px 2px; padding: 0px 5px; white-space: nowrap; background-color: rgb(248, 248, 248);" >libfoo_staticde>depended on being linked against CoreFoundation, there is a dependency reference to that in the main binary.


转自:http://samdmarshall.com/blog/static_and_dynamic_libraries.html

  评论这张
 
阅读(146)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017