0

I have a third party library that I am now attempting to add a conan recipe so I can start to manage this library via conan...

this third party library has a CMakeLists.txt that I need to manually add a compiler option... is there a way I can do this in the recipe ?

CMakeLists.txt

cmake_minimum_required( VERSION 3.0 )
project( ProjectName
         LANGUAGES CXX )
add_compile_options(-std=c++11). //I have to add this line

conanfile.py

...
    def source(self):
        self.run("git clone --depth 1 --branch a_tag git@github.com:GITGROUP/project_name.git")

    def build(self):
        cmake = CMake(self)
        cmake.configure(source_folder="project_name")
        cmake.build()
...
Erik
  • 2,782
  • 3
  • 34
  • 64
  • 1
    If it's related to cppstd: https://docs.conan.io/en/latest/howtos/manage_cpp_standard.html (recommended because affects the package id). If you want to change flags, but don't change the package id: https://docs.conan.io/en/latest/reference/build_helpers/cmake.html#definitions (CONAN_CMAKE_CXX_STANDARD). – uilianries Nov 02 '20 at 02:07

2 Answers2

2

If you want to create a recipe for a third party library and you want to modify any file from that library, including CMakeLists.txt, you can do that with tools.replace_in_file in your source method. The module tools is in the conans package.

I often use something like

tools.replace_in_file("sources/CMakeLists.txt", "project (ProjectName)",
                              '''project (ProjectName)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()''')

such that I can use conan to get that third party library dependencies. You can add add_compile_options(-std=c++11) in the replacement string.

For instance, my full source method in a recipe for the vtk library is

def source(self):
        tools.get("https://www.vtk.org/files/release/{}/VTK-{}.tar.gz".format(
            ".".join(self.version.split(".")[:-1]), # Get only X.Y version, instead of X.Y.Z
            self.version))
        os.rename("VTK-{}".format(self.version), "sources")
        tools.replace_in_file("sources/CMakeLists.txt",
                              "project(VTK)",
                              """project(VTK)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
SET(CMAKE_INSTALL_RPATH "$ORIGIN")""")
darcamo
  • 3,294
  • 1
  • 16
  • 27
  • I actually realized this solution as well once I kept staring at the recipe template. thank you! – Erik Nov 02 '20 at 08:50
0

With later Conan versions, you no longer have to manually inject the conan cmake. You can simply ask Conan to use a cmake_paths generator and then "force-include" it using Conan.

from conans import ConanFile, CMake

class MyConanFile(ConanFile):
    name = ... # must match the name in the project() in CMake
    generators = 'cmake', 'cmake_paths'

    def _configure_cmake(self) -> CMake:
        cmake = CMake(self)
        cmake.definitions[f"CMAKE_PROJECT_{self.name}_INCLUDE"] = f"{self.build_folder}/conan_paths.cmake"
        # Add any definition you like
        cmake.definitions['FOO'] = '1'
        return cmake

    def build(self):
        cmake = self._configure_cmake()
        cmake.build()
emrainey
  • 51
  • 1
  • 7