conan-io / conan

Conan - The open-source C and C++ package manager
https://conan.io
MIT License
8.27k stars 981 forks source link

[question] cross compiling with existing cmake toolchain file #11964

Open JeffHough opened 2 years ago

JeffHough commented 2 years ago

I'm not 100% sure if this is a conan issue, or just a regular cmake issue:

I am trying to do cross-building using an existing toolchain file for a non-standard linux distro. The file looks like this:

set(toolchainpath /path/to/sysroots/folder)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR x86_64)

set(CMAKE_C_COMPILER ${toolchainpath}/path/to/c/compiler)
set(CMAKE_CXX_COMPILER ${toolchainpath}//path/to/cxx/compiler)

set(CMAKE_SYSROOT ${toolchainpath}/path/to/sysroot)
set(CMAKE_<LANG>_STANDARD_INCLUDE_DIRECTORIES
  ${toolchainpath}/path/to/c++/6.3.0
)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

From what I have read, the easiest way to do cross building is to create a conan package for your existing cmake toolchain file. I have done that like this:

from conan import ConanFile
import os

class ToolchainConan(ConanFile):
    name = "Toolchain"
    version = "1.0.0"
    exports_sources=["mytoolchain.cmake"]

    def package(self):
        # Copy all the required files for your toolchain
        self.copy("mytoolchain.cmake", dst=self.package_folder)

    def package_info(self):
        f = os.path.join(self.package_folder, "mytoolchain.cmake")
        self.conf_info.append("tools.cmake.cmaketoolchain:user_toolchain", [f])

I then have a conan profile called CrossCompile that looks like this:

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=6
compiler.libcxx=libstdc++11
build_type=Release

[options]

[build_requires]
Toolchain/1.0.0

[env]

I can build individual packages just fine, but if I try to build one package using the CrossCompile profile which depends on other packages build using the CrossCompile profile, then I get the following errors:

By not providing "FindEigen3.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Eigen3", but
  CMake did not find one.

But if I run with the usual -pr=default then things are totally fine. So I am thinking the existing toolchain file is messing up the cmake paths set up by CMakeDeps, but I am not sure how. Am I just using the existing toolchain file incorrectly?

Thanks again!

memsharded commented 2 years ago

Hi @JeffHough

We would need to understand a bit better the dependency graph, who depends on who, and who depends on Eigen, etc. Quick question: are you using the 2 profiles? The recommended way for cross-building is passing -pr:h=CrossCompile -pr:b=profilebuild. This will be by default in 2.0, but now in 1.X it is necessary to explicitly say -pr:b=xxx and pass a profile for the build machine.

jcar87 commented 2 years ago

Hi @JeffHough -

Could you try commenting the following lines out?

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

In particular the last one may interfere with find_package calls. Setting it to ONLY causes CMake to "re-root" the search path to the CMAKE_SYSROOT defined in the toolchain - so CMake will not consider other locations. You may have better luck setting it to NEVER or BOTH (but the correct one will largely depend on whether or not you need CMake to locate "System" libraries or packages, or if everything can be satisfied by Conan).

JeffHough commented 2 years ago

@jcar87 @memsharded Ahh yes, those flags are definitely the problem, makes a lot of sense (I had been setting those flags based on recommended settings without giving them too much thought). Thanks for the help!

For cross-compiling purposes, those flags are definitely there for a reason however (don't want to accidentally link with system libraries for example). I haven't run into any issues yet, but does conan have any reccomendations on how to deal with these flags, since they are pretty common in existing cmake toolchain files for cross-building?

giuliano-97 commented 8 months ago

For cross-compiling purposes, those flags are definitely there for a reason however (don't want to accidentally link with system libraries for example). I haven't run into any issues yet, but does conan have any reccomendations on how to deal with these flags, since they are pretty common in existing cmake toolchain files for cross-building?

@memsharded are there any guidelines on this? iirc for conan 1 there are clear guidelines on how to cross compile using a build SDK generated with yocto, what about conan 2?

memsharded commented 8 months ago

Hi @giuliano-97

This issue is a bit outdated, it referred to Conan 1, but the CMakeToolchain has been in Conan 1.X for years now, and it is mostly the same implementation in Conan 1 and in Conan 2, so in this regard it should be any difference. Are you seeing a different behavior in Conan 2? Could you please elaborate?