Download emk: .zip .tar.gz View On GitHub

Link Module

The link module is an emk module for linking compiled code (ie, .o files) into libraries/executables. It can support various linkers by setting the linker property to a different instance. The default linker instance uses GCC and associated tools for linking. You can create a new instance of link.GccLinker to use a different version of gcc (eg for cross-compilation). To support other linkers, you would need to implement a linker class (see “Linker Support” below).

This module defines emk rules during the second prebuild stage, so that the c module’s prebuild step is executed before any link rules are defined. Future modules that create linkable files (eg assembler?) could work in a similar manner to the c module, adding to the link.objects dict during the prebuild stage.

By default, the link module will autodetect object files that contain a main() function; those object files will each be linked into an executable. The other files (that do not contain main()) are linked into a static library, which is used when linking the executables. You may specify dependencies on other directories managed by emk (in the same project or a different project); the static libraries from those directories will be linked in as well.

You can also build a shared library instead of or in addition to the static library. Note that on many platforms, the object files linked into a shared library must be compiled as position independent code (eg ‘-fPIC’ or ‘-fpic’ with gcc). You must configure the necessary flags in the c module for this to work.

Using the depdirs or projdirs properties, you can specify dependencies on other directories that are built using emk. When linking an executable or shared library, emk will gather all (non-local) linker flags and libraries from all depdirs and projdirs (transitively) to pass to the linker. This allows you to specify flags with the code that requires them, instead of where that code is being linked in.

By default, the main() function detection occurs after the object files have been generated. This is to allow inspection of the symbols in the object files to see if they export a main() function - this is much faster and more exact than trying to parse the source code. One side effect of this is that the link module’s rules are (by default) executed in the second build phase. If this is undesirable for some reason, you can configure the link module to do “simple” main() detection (by parsing the source code) by setting the detect_exe property to “simple”. If this is set (or if main() detection is disabled entirely), the link rules will be defined and executed in the first build phase.

The link module will always define rules creating the link.__static_lib__ and link.__exes__ targets. link.__static_lib__ depends on the static library being generated (or nothing, if there is no static library to generate). link.__exes__ depends on all executables being linked. If a shared library is being created, the link module will define a rule for link.__shared_lib__ that depends on the shared library.

If the ‘detect_exe’ property is set to “exact”, then the link module defines an autobuild rule for link.__interim__ which depends on all object files. This will cause all object files to be built if required in the first build phase, so that main() detection can occur in postbuild.

For an object file <name>.o that is being linked into an executable, the generated executable path will be <build dir>/<name><link.exe_ext> (note that the ‘exe_ext’ property is ”” by default).

Classes

Properties (defaults set based on the path prefix passed to the constructor):

OsxGccLinker: A linker class for linking using gcc/g++ on OS X; inherits from GccLinker. Uses libtool to create static libraries for multi-arch support.

Properties (defaults set based on the path prefix passed to the constructor):

MingwGccLinker: A linker class for linking using gcc/g++ on Windows; inherits from GccLinker.

MsvcLinker: A linker class for linking using Microsoft’s Visual C++ tools on Windows.

Properties (defaults set based on the path prefix passed to the constructor):

Properties

All properties are inherited from the parent scope if there is one.

Linker Support

To add support for a new linker, you must implement a linker class for use by the link module (and then set the link module’s linker property to an instance of the linker class). A linker class must provide the following methods:

contains_main_function(self, objfile)

Determine if an object file contains a main() function. This is used by the link module to autodetect which object files should be linked into executables. Returns True if the object file contains a main() function, False otherwise.

Arguments:

create_static_lib(self, dest, source_objs, other_libs)

Create a static library (archive) containing the given object files and all object files contained in the given other libs (which will be static libraries as well).

Called by the link module to create a static library. If the link module’s lib_in_lib property is True, the link module will pass in the library dependencies of this library in the ‘other_libs’ argument. This method must include the contents of all the other libraries in the generated static library.

Arguments:

static_lib_cwd_safe(self)

Returns True if creating a static library using the create_static_lib() method is cwd_safe (ie, does not use anything that depends on the current working directory); returns False otherwise.

shlib_opts(self)

Returns a list of options that the link module should use when linking a shared library.

exe_opts(self)

Returns a list of options that the link module should use when linking an executable.

do_link(self, dest, source_objs, abs_libs, lib_dirs, rel_libs, flags, cxx_mode)

Link a shared library or executable. The link module does not order the libraries to be linked in, so this method must ensure that any ordering dependencies are solved. The GCC linker uses the ’–start-group’ and ’–end-group’ options to make sure that library ordering is not an issue; the documentation says that this can be slow but in reality it makes very little difference.

Arguments:

link_cwd_safe(self)

Returns True if linking a shared library or executable using the do_link() method is cwd_safe (ie, does not use anything that depends on the current working directory); returns False otherwise.

strip(self, path)

Strip unnecessary symbols from the given shared library / executable. Called by the link module after linking if its strip property is True.

Arguments:

obj_ext(self)

This function will be called to get the extension of object files consumed by this linker.