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:

  1. from conan import ConanFile
  2. from conan.tools.gnu import Autotools
  3. class App(ConanFile):
  4. settings = "os", "arch", "compiler", "build_type"
  5. def build(self):
  6. autotools = Autotools(self)
  7. autotools.configure()
  8. 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 projects

      • args – (Optional, Defaulted to None): List of arguments to use for the make 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 the make call. By default an argument DESTDIR=unix_path(self.package_folder) is added to the call if the passed value is None. See more information about tools.microsoft.unix_path() function

      • target – (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 the autoreconf 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:

  1. $ otool -l path/to/libMyLib.dylib
  2. ...
  3. cmd LC_ID_DYLIB
  4. cmdsize 48
  5. name path/to/libMyLib.dylib (offset 24)
  6. time stamp 1 Thu Jan 1 01:00:01 1970
  7. current version 1.0.0
  8. compatibility version 1.0.0
  9. ...
  10. Load command 11
  11. cmd LC_LOAD_DYLIB
  12. cmdsize 48
  13. name path/to/dependency.dylib (offset 24)
  14. time stamp 2 Thu Jan 1 01:00:02 1970
  15. current version 1.0.0
  16. compatibility version 1.0.0
  17. ...

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:

  1. from conan.tools.apple import fix_apple_shared_install_name
  2. class HelloConan(ConanFile):
  3. ...
  4. def package(self):
  5. autotools = Autotools(self)
  6. autotools.install()
  7. 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:

  1. $ otool -l path/to/libMyLib.dylib
  2. ...
  3. cmd LC_ID_DYLIB
  4. cmdsize 48
  5. name @rpath/libMyLib.dylib (offset 24)
  6. time stamp 1 Thu Jan 1 01:00:01 1970
  7. current version 1.0.0
  8. compatibility version 1.0.0
  9. ...
  10. Load command 11
  11. cmd LC_LOAD_DYLIB
  12. cmdsize 48
  13. name @rpath/dependency.dylib (offset 24)
  14. time stamp 2 Thu Jan 1 01:00:02 1970
  15. current version 1.0.0
  16. 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.