Warning

This is an experimental feature subject to breaking changes in future releases.

MakeToolchain

The MakeToolchain can be used in the generate() method of conanfile.py:

from conans import ConanFile
from conan.tools.gnu import MakeToolchain

class App(ConanFile):
    settings = "os", "arch", "compiler", "build_type"
    requires = "hello/0.1"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}

    def generate(self):
        tc = MakeToolchain(self)
        tc.generate()

The MakeToolchain will generate the following file during conan install command (or before calling the build() method when the package is being built in the cache): conan_toolchain.mak. To use the variables generated by Conan, include this file in your existing Makefile such as:

include conan_toolchain.mak

Or to make it optional:

-include conan_toolchain.mak

conan_toolchain.mak will contain the definitions of all the Make variables related to the Conan options and settings for the current package, platform, etc. This includes but is not limited to the following:

  • Detection of target type: “executable”, “shared” or “static”

    • Based on existance/value of a option named shared

    • Based on result, defines -shared linker flag

  • Detection of fPIC

    • Based on existance/value of a option named fPIC

    • Combines with detection of target type above

    • Sets -fPIC flag for compiler

    • Sets -fPIC flag for linker when building shared library

    • Sets -pie flag for linker when building executable

  • Detection of build_type from Conan settings

    • Sets -DNDEBUG flag for Release builds

  • Definition of the C++ standard as necessary

  • Definition of the standard library used for C++

  • Definition of rpaths based on libpaths in conan cache

NOTE: Simply including this file will have no effect on your Makefile build.

All variables in this file are prefixed with CONAN_TC_ and so existing makefiles will robably makes no references to variables with these names. Users can modify their makefiles to make use of these variables by name. That is certainly supported, however such a process tighly couples Makefiles to Conan which can be undesirable, so Conan provides an alternative. There is list of well-known “standard”/”conventional” variables used within GnuMake, Autotools, and other related tools:

Gnu Make Well-Known Variables

The relevant content from the GnuMake manual is provided here for convenience:

CFLAGS Extra flags to give to the C compiler.

CXXFLAGS Extra flags to give to the C++ compiler.

CPPFLAGS Extra flags to give to the C preprocessor and programs that use it (the C and Fortran compilers).

LDFLAGS Extra flags to give to compilers when they are supposed to invoke the linker, ‘ld’, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable instead.

LDLIBS Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS variable.

To have the CONAN_TC_ variables appended to these standard GnuMake variables, simply add the following function call to your Makefile somewhere after the include statement:

  • $(call CONAN_TC_SETUP)

To be clear, this only has the desired “automatic” effect if your Makefile(s) all use of these standard variables in the conventional way. If your Makefile(s) use custom variables, you would need to teach them to append/include/use the CONAN_TC_ variables manually.

Also, while we are appending “standard” variables in a seemingly sensible way, this function makes a lot of assumptions which are likely not going to hold true in many environments. The goal is to make as much of the behavior configurable as possible. Based on user requests, we will continue to add parameters to the constructor. If you would like a behavior added to the list of configurable items, please provide feedback at: https://github.com/conan-io/conan/issues

definitions

This attribute allows defining preprocessor definitions the same way that build helpers do:

def generate(self):
    tc = MakeToolchain(self)
    tc.definitions["MYVAR"] = "MyValue"
    tc.generate()

This will be translated to:

  • -DMYVAR=MYVAL being appended to the CONAN_TC_CPPFLAGS variable

generators

The MakeGenerator is being developed in-tandem with this toolchain because ideally they would be used in the same recipes and workflows. They have consistent conventions and strategy, however they are currently completely independent from each other. Thus, you can use this toolchain without using the MakeGenerator.

Using the toolchain in developer flow

One of the advantages of using Conan toolchains is that it provides exact same “toolchain-related” variables that Conan will have within a recipe’s build() method to the build system when the user calls the build system directly in their workspace. This was not possible prior to Conan’s toolchain feature. Here’s an example:

# Lets start in the folder containing a conanfile.py
# Add the toolchain method with the MakeToolchain as shown in the example
$ mkdir build && cd build
# Install both debug and release deps and create the toolchain
$ conan install ..
# Add the following lines to Makefile:
#    -include build/conan_toolchain.mak
#    $(call CONAN_TC_SETUP)
$ make

NOTE As stated previously, this will only have the desired effect if the Makefile makes conventional use of the standard variables.

We can actually achieve the same goal without modifying the Makefile at all, it simply requires passing a few more parameters to GnuMake.

$ conan install ..
$ make -E='include build/conan_toolchain.mak' -E='$(call CONAN_TC_SETUP)'

Autotools Build Helper

This toolchain should not be used together with the existing AutoToolsBuildEnvironment build helper in Conan at this time. They perform a number of similar and probably conflicting operations on the standard GnuMake variables. There is a goal to continue adding features to this toolchain until is achieves feature parity with AutoToolsBuildEnvironment which will take some time. During that process, we’ll be trying to determine if it’s desirable and feasible to make the two co-exist and/or even work together. At this time, it’s unclear.