Autotools
The Autotools
build helper is a wrapper around the command line invocation of autotools. It will abstract the calls like ./configure
or make
into Python method calls.
Usage:
from conan import ConanFile
from conan.tools.gnu import Autotools
class App(ConanFile):
settings = "os", "arch", "compiler", "build_type"
def build(self):
autotools = Autotools(self)
autotools.configure()
autotools.make()
It will read the conanbuild.conf
file generated by the AutotoolsToolchain to know read the arguments for calling the configure and make scripts:
configure_args: Arguments to call the
configure
script.make_args: Arguments to call the
make
script.
Reference
class Autotools(conanfile, namespace=None)
Parameters:
conanfile – The current recipe object. Always use
self
.namespace – this argument avoids collisions when you have multiple toolchain calls in the same recipe. By setting this argument, the conanbuild.conf file used to pass information to the toolchain will be named as: <namespace>_conanbuild.conf. The default value is
None
meaning that the name of the generated file is conanbuild.conf. This namespace must be also set with the same value in the constructor of the AutotoolsToolchain so that it reads the information from the proper file.
configure(build_script_folder=None, args=None)
Call the configure script.
Parameters:
args – List of arguments to use for the
configure
call.build_script_folder – Subfolder where the configure script is located. If not specified conanfile.source_folder is used.
make(target=None, args=None)
Call the make program.
Parameters:
target – (Optional, Defaulted to
None
): Choose which target to build. This allows building of e.g., docs, shared libraries or install for some AutoTools projectsargs – (Optional, Defaulted to
None
): List of arguments to use for themake
call.
install(args=None, target=’install’)
This is just an “alias” of
self.make(target="install")
Parameters:
args – (Optional, Defaulted to
None
): List of arguments to use for themake
call. By default an argumentDESTDIR=unix_path(self.package_folder)
is added to the call if the passed value isNone
. See more information about tools.microsoft.unix_path() functiontarget – (Optional, Defaulted to
None
): Choose which target to install.
autoreconf(build_script_folder=None, args=None)
Call
autoreconf
Parameters:
args – (Optional, Defaulted to
None
): List of arguments to use for theautoreconf
call.build_script_folder – Subfolder where the configure script is located. If not specified conanfile.source_folder is used.
A note about relocatable shared libraries in macOS built the Autotools build helper
When building a shared library with Autotools in macOS a section LC_ID_DYLIB
and another LC_LOAD_DYLIB
are added to the .dylib
. These sections store install_name
information, which is the location of the folder where the library or its dependencies are installed. You can check the install_name of your shared libraries using the otool command:
$ otool -l path/to/libMyLib.dylib
...
cmd LC_ID_DYLIB
cmdsize 48
name path/to/libMyLib.dylib (offset 24)
time stamp 1 Thu Jan 1 01:00:01 1970
current version 1.0.0
compatibility version 1.0.0
...
Load command 11
cmd LC_LOAD_DYLIB
cmdsize 48
name path/to/dependency.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1.0.0
compatibility version 1.0.0
...
Why is this a problem when using Conan?
When using Conan the library will be built in the local cache and this means that this location will point to Conan’s local cache folder where the library was installed. This location is where the library tells any other binaries using it where to load it at runtime. This is a problem since you can build the shared library in one machine, then upload it to a server and install it in another machine to use it. In this case, as Autotools behaves by default, you would have a library storing an install_name
pointing to a folder that does not exist in your current machine so you would get linker errors when building.
How to address this problem in Conan
The only thing Conan can do to make these shared libraries relocatable is to patch the built binaries after installation. To do this, when using the Autotools
build helper and after running the Makefile’s install()
step, you can use the fix_apple_shared_install_name() tool to search for the built .dylib
files and patch them by running the install_name_tool
macOS utility, like this:
from conan.tools.apple import fix_apple_shared_install_name
class HelloConan(ConanFile):
...
def package(self):
autotools = Autotools(self)
autotools.install()
fix_apple_shared_install_name(self)
This will change the value of the LC_ID_DYLIB
and LC_LOAD_DYLIB
sections in the .dylib
file to:
$ otool -l path/to/libMyLib.dylib
...
cmd LC_ID_DYLIB
cmdsize 48
name @rpath/libMyLib.dylib (offset 24)
time stamp 1 Thu Jan 1 01:00:01 1970
current version 1.0.0
compatibility version 1.0.0
...
Load command 11
cmd LC_LOAD_DYLIB
cmdsize 48
name @rpath/dependency.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1.0.0
compatibility version 1.0.0
The @rpath
special keyword will tell the loader to search a list of paths to find the library. These paths can be defined by the consumer of that library by defining the LC_RPATH
field. This is done by passing the -Wl,-rpath -Wl,/path/to/libMyLib.dylib
linker flag when building the consumer of the library. Then if Conan builds an executable that consumes the libMyLib.dylib
library, it will automatically add the -Wl,-rpath -Wl,/path/to/libMyLib.dylib
flag so that the library is correctly found when building.