Mac Link Dynamic Library Terminal

May 30, 2019  By default, the Library folder on Mac is hidden from the user. Apple keeps Library invisible in order to protect users from accidental deletion or modification of important files stored there: application settings, caches and other system files needed to run the programs. Building dynamic link libraries in OSX. GitHub Gist: instantly share code, notes, and snippets. However, when I use this gyp file and I build on Mac the library. How to Create and Use Symbolic Links (aka Symlinks) on Linux Chris Hoffman @chrisbhoffman Updated March 7, 2017, 8:27pm EDT Linux allows you to create symbolic links, or symlinks, that point to another file or folder on your machine. We can create a.dylib from the terminal shell with the following command: g -dynamiclib -o MyDynamicLib.dylib hello.cpp. Here we use the g compiler and set a flag to create a dynamic library file, -dynamiclib. The next flag -o MyDynamicLib.dylib, tells the compiler what to name the outputted file. Finally, we specify the file(s) to use. Configure Xamarin.iOS to link the library; Access the methods from the library. To bring the library into your project, Select the project from the solution explorer and press Command+Option+a. Navigate to the libMyLibrary.a and add it to the project. When prompted, tell Visual Studio for Mac or Visual Studio to copy it into the project. Furthermore, most operating systems allows one copy of a shared library in memory to be used by all running programs, thus, saving memory. The shared library codes can be upgraded without the need to recompile your program. Because of the advantage of dynamic linking, GCC, by default, links to the shared library if it is available.

When you need to use a dynamic library in your product, you have to install the library in your computer. You may use dynamic libraries as dependent libraries (by specifying them in your product’s link line) or as runtime loaded libraries (by loading them when they are needed, using dlopen(3) OS X Developer Tools Manual Page).

This article describes the process of installing and using dynamic libraries. It’s based on the Ratings dynamic library and the StarMeals, StarMeals2, and Grades programs, which are included in this document’s companion-file package. This article also shows how to use dynamic libraries as dependent libraries or as runtime-loaded libraries. Finally, this article demonstrates how to interpose the functions exported by a dynamic library.

Installing Dependent Libraries

Before you can use a dynamic library as a dependent library, the library and its header files must be installed on your computer. The standard locations for header files are ~/include, /usr/local/include and /usr/include. The standard locations for dynamic libraries are ~/lib, /usr/local/lib, and /usr/lib.

You may also place the .dylib file at a nonstandard location in your file system, but you must add that location to one of these environment variables:

  • LD_LIBRARY_PATH

  • DYLD_LIBRARY_PATH

  • DYLD_FALLBACK_LIBRARY_PATH

For details on how to add paths to these environment variables, see Opening Dynamic Libraries. To learn about installing dependent libraries in a relocatable directory, see Run-Path Dependent Libraries.

If you don’t want to change the environment variables and you want to place the dynamic library in a nonstandard location, you must specify where in your file system you placed the library when you link your image. See the description of the compiler -dylib_file option in http://gcc.gnu.org/onlinedocs/gcc/Darwin-Options.html#Darwin-Options for details.

For example, in OS X the executable code of apps can be packaged together with frameworks containing libraries created specifically for a particular app. These frameworks are known as private embedded frameworks. Applications that use private embedded frameworks, as well as the frameworks themselves, must be specially built. See “Creating a Framework” in Framework Programming Guide and “Loading Code at Runtime” in Mach-O Programming Topics for details.

Using Dependent Libraries requires that the Averages 1.1 and Ratings 1.1 dynamic libraries be installed on your computer. To install these libraries:

  1. Open this document’s companion-file package.

  2. In Terminal, execute these commands:

    Note: To uninstall the libraries, execute these commands:

Using Dependent Libraries

Using dynamic libraries as dependent libraries by linking your image with them provides several benefits, including producing smaller executable files and not having to get the address of the libraries’ exported symbols before using them in your code. However, you still have to make sure a weakly imported symbol exists before using it.

All you need to do to use a dynamic library as a dependent library is include the library’s headers in your source code and link the library with your program or library. The library’s headers describe the symbols you can use. You should not use any other symbols to access the library’s functionality. Otherwise, you may get unexpected results, or your image may stop working for its users when they update the dependent library in their computers.

Listing 1 shows the source code of a small program that uses Ratings 1.1, developed in Creating Dynamic Libraries.

Listing 1 Using Ratings 1.1 as a dependent library

This list describes the highlighted lines:

  • Line 1: The meanRating function is guaranteed to exist in all versions of libRating.A.dylib. Therefore, no existence test is required.

  • Lines 2 and 3: The functions medianRating and frequentRating are available in Ratings 1.1 but not Ratings 1.0. Since StarMeals is to be backwards compatible with Ratings 1.0, it has to check for the existence of these functions before using them. Otherwise, StarMeals may crash.

To compile the StarMeals.c file, use the command shown in Listing 2.

Listing 2 Compiling and linking StarMeals

Notice that the exact location of the library StarMeals directly depends on (libRatings.dylib) is provided at the link line. The pathname <user_home>/lib/libRatings.dylib is actually a symbolic link to <user_home>/lib/libRatings.A.dylib. At link time, the static linker resolves the link and stores the library’s actual filename in the image it generates. With this approach, the dynamic linker always uses the library’s complete name when it looks for an image’s dependent libraries.

Listing 3 shows the output StarMeals produces when run in test mode:

Listing 3 Test output of the StarMeals program

Using Runtime-Loaded Libraries

An image that uses dynamic libraries as runtime-loaded libraries is smaller and loads faster than the image using the same libraries as dependent libraries. The static linker doesn’t add information about the runtime-loaded libraries to the image. And the dynamic loader doesn’t have to load the library’s dependent libraries when the image is loaded. However, this flexibility comes at a price. Before an image can use a dynamic library that is not one of its dependent libraries, it must load the library with dlopen(3) OS X Developer Tools Manual Page and get the address of each symbol it needs with dlsym(3) OS X Developer Tools Manual Page. The image must also call dlclose(3) OS X Developer Tools Manual Page when it’s done using the library.

The StarMeals2 program provides the same functionality that StarMeals provides. But StarMeals2 uses the Ratings 1.1 dynamic library as a runtime loaded library. Listing 4 shows the program’s source code.

Listing 4 Using Ratings 1.1 as a runtime-loaded library

Listing 5 shows to compile the StarMeals2 program.

Listing 5 Compiling and linking StarMeals2

The static linker doesn’t complain about the unresolved external references in libRatings.A.dylib because it’s not included at the link line. The dynamic linker resolves these references when StarMeals2 uses dlopen(3) OS X Developer Tools Manual Page to load libRatings.A.dylib.

Interposing Functions in Dependent Libraries

Sometimes you need to perform operations before or after a function is called to gather statistical data or to modify its inputs our outputs. For example, you may want to find out how many times a program calls a specific function to determine whether an algorithm should be optimized. However, you may not always have access to the function’s source code to make the modifications. Interposition is a mechanism through which you can define your own version of a function that’s defined in an image’s dependent libraries. In your version, you may or may not call the original function.

Note: In OS X you can interpose only dependent libraries. Symbols in runtime loaded libraries cannot be interposed.

To call an interposed function from a custom definition, you use the dlsym(RTLD_NEXT, '<function_name>') call to get the address of the “real” function. For example, Listing 6 shows how you may write a custom version of a function defined in a dynamic library.

Listing 6 Interposing a function

You may use interposition to adapt an existing dynamic library to your particular needs without changing its API. For example, this document’s companion package includes the implementations of two dynamic libraries called Ratings and RatingsAsGrades. The Ratings library implements a star-based rating system (it can be used to tally restaurant and hotel ratings; for example, *** and *****). The RatingsAsGrades library implements a letter-based grading system, which can be used to tally student grades; for example A and C. Instead of writing a new algorithm to manage letter grades, the RatingsAsGrades library leverages the functionality of the Ratings library. Listing 7 shows the interface and implementation of the RatingsAsGrades library.

Listing 7 RatingsAsGrades Interposing Ratings

Notice how the addRating, medianRating, and frequentRating functions, modify the input and output of the definitions they shadow.

The companion-files package includes the source code of the Grades program. This program uses the RatingsAsGrades library to tally the grades of students.

Follow these instructions to build and run the Grades program:

  1. Open this document’s companion-files package.

  2. In Terminal, perform these commands:

Listing 8 shows the output of the Grades program when ran in test mode.

Listing 8 Test output of the Grades program Mkl lib.


Unable to load dynamic library

Copyright © 2012 Apple Inc. All Rights Reserved. Terms of Use Privacy Policy Updated: 2012-07-23

Two important factors that determine the performance of apps are their launch times and their memory footprints. Reducing the size of an app’s executable file and minimizing its use of memory once it’s launched make the app launch faster and use less memory once it’s launched. Using dynamic libraries instead of static libraries reduces the executable file size of an app. They also allow apps to delay loading libraries with special functionality only when they’re needed instead of at launch time. This feature contributes further to reduced launch times and efficient memory use.

This article introduces dynamic libraries and shows how using dynamic libraries instead of static libraries reduces both the file size and initial memory footprint of the apps that use them. This article also provides an overview of the dynamic loader compatibility functions apps use to work with dynamic libraries at runtime.

What Are Dynamic Libraries?

Most of an app’s functionality is implemented in libraries of executable code. When an app is linked with a library using a static linker, the code that the app uses is copied to the generated executable file. A static linker collects compiled source code, known as object code, and library code into one executable file that is loaded into memory in its entirety at runtime. The kind of library that becomes part of an app’s executable file is known as a static library. Static libraries are collections or archives of object files.

Note: Static libraries are also known as static archive libraries and static linked shared libraries.

When an app is launched, the app’s code—which includes the code of the static libraries it was linked with—is loaded into the app’s address space. Linking many static libraries into an app produces large app executable files. Figure 1 shows the memory usage of an app that uses functionality implemented in static libraries. Applications with large executables suffer from slow launch times and large memory footprints. Also, when a static library is updated, its client apps don’t benefit from the improvements made to it. To gain access to the improved functionality, the app’s developer must link the app's object files with the new version of the library. And the apps users would have to replace their copy of the app with the latest version. Therefore, keeping an app up to date with the latest functionality provided by static libraries requires disruptive work by both developers and end users.

A better approach is for an app to load code into its address space when it’s actually needed, either at launch time or at runtime. The type of library that provides this flexibility is called dynamic library. Dynamic libraries are not statically linked into client apps; they don't become part of the executable file. Instead, dynamic libraries can be loaded (and linked) into an app either when the app is launched or as it runs.

Note: Dynamic libraries are also known as dynamic shared libraries, shared objects, or dynamically linked libraries.

Figure 2 shows how implementing some functionality as dynamic libraries instead of as static libraries reduces the memory used by the app after launch.

Using dynamic libraries, programs can benefit from improvements to the libraries they use automatically because their link to the libraries is dynamic, not static. That is, the functionality of the client apps can be improved and extended without requiring app developers to recompile the apps. Apps written for OS X benefit from this feature because all system libraries in OS X are dynamic libraries. This is how apps that use Carbon or Cocoa technologies benefit from improvements to OS X.

Another benefit dynamic libraries offer is that they can be initialized when they are loaded and can perform clean-up tasks when the client app terminates normally. Static libraries don’t have this feature. For details, see Module Initializers and Finalizers.

One issue that developers must keep in mind when developing dynamic libraries is maintaining compatibility with client apps as a library is updated. Because a library can be updated without the knowledge of the client-app’s developer, the app must be able to use the new version of the library without changes to its code. To that end, the library’s API should not change. However, there are times when improvements require API changes. In that case, the previous version of the library must remain in the user’s computer for the client app to run properly. Dynamic Library Design Guidelines explores the subject of managing compatibility with client apps as a dynamic library evolves.

How Dynamic Libraries Are Used

When an app is launched, the OS X kernel loads the app’s code and data into the address space of a new process. The kernel also loads the dynamic loader ( /usr/lib/dyld ) into the process and passes control to it. The dynamic loader then loads the app’s dependent libraries. These are the dynamic libraries the app was linked with. The static linker records the filenames of each of the dependent libraries at the time the app is linked. This filename is known as the dynamic library’s install name. The dynamic loader uses the app’s dependent libraries’ install names to locate them in the file system. If the dynamic loader doesn’t find all the app’s dependent libraries at launch time or if any of the libraries is not compatible with the app, the launch process is aborted. For more information on dependent-library compatibility, see Managing Client Compatibility With Dependent Libraries. Dynamic library developers can set a different install name for a library when they compile it using the gcc -install_name option. See the gcc man page for details.

The dynamic loader resolves only the undefined external symbols the app actually uses during the launch process. Other symbols remain unresolved until the app uses them. For details on the process the dynamic loader goes when an app is launched, see “Executing Mach-O Files” in Mach-O Programming Topics.

The dynamic loader—in addition to automatically loading dynamic libraries at launch time—loads dynamic libraries at runtime, at the app’s request. That is, if an app doesn't require that a dynamic library be loaded when it launches, developers can choose to not link the app’s object files with the dynamic library, and, instead, load the dynamic library only in the parts of the app that require it. Using dynamic libraries this way speeds up the launch process. Dynamic libraries loaded at runtime are known as dynamically loaded libraries. To load libraries at runtime, apps can use functions that interact with the dynamic loader for the platform under which they're running.

Terminal

Note: The target architecture of the client and the dynamic library must be the same. Otherwise, the dynamic loader doesn’t load the library.

Different platforms implement their dynamic loaders differently. They may also have custom dynamic code-loading interfaces that make code difficult to port across platforms. To facilitate porting an app from UNIX to Linux, for example, Jorge Acereda and Peter O'Gorman developed the dynamic loader compatibility (DLC) functions. They offer developers a standard, portable way to use dynamic libraries in their apps.

The DLC functions are declared in /usr/include/dlfcn.h. There are five of them:

  • dlopen(3) OS X Developer Tools Manual Page: Opens a dynamic library. An app calls this function before using any of the library’s exported symbols. If the dynamic library hasn’t been opened by the current process, the library is loaded into the process’s address space. The function returns a handle that’s used to refer to the opened library in calls to dlsym and dlclose. This handle is known as the dynamic library handle. This function maintains a reference count that indicates the number of times the current process has used dlopen to open a particular dynamic library.

  • dlsym(3) OS X Developer Tools Manual Page: Returns the address of a symbol exported by a dynamically loaded library. An app calls this function after obtaining a handle to the library through a call to dlopen. The dlsym function takes as parameters the handle returned by dlopen or a constant specifying the symbol search scope and the symbol name.

  • dladdr(3) OS X Developer Tools Manual Page: Returns information on the address provided. If the address corresponds to a dynamically loaded library within the app’s address space, this function returns information on the address. This information is returned in a Dl_info structure, which encapsulates the pathname of the dynamic library, the library’s base address, and the address and value of the nearest symbol to the address provided. If no dynamic library is found at the address provided, the function returns no information.

  • dlclose(3) OS X Developer Tools Manual Page: Closes a dynamically loaded library. This function takes as a parameter a handle returned by dlopen. When the reference count for that handle reaches 0, the library is unloaded from the current process’s address space.

  • dlerror(3) OS X Developer Tools Manual Page: Returns a string that describes an error condition encountered by the last call to dlopen, dlsym, or dlclose.

For more information on the DLC functions, see OS X ABI Dynamic Loader Reference.



Copyright © 2012 Apple Inc. All Rights Reserved. Terms of Use Privacy Policy Updated: 2012-07-23