Cross-compiling a Conan package - c++

I'm writing a small C++ cross-platform library which uses CMake, Clang, Ninja and Conan. I've managed to cross-compile the library, but I'm having difficulties adding a Conan package. For a test, I've added fmt as a dependecy in conanfile like so:
conanfile.py
from conan import ConanFile
from conan.tools.cmake import CMakeDeps, CMakeToolchain
class App(ConanFile):
name = "example_library"
version = "1.0.0"
settings = "os", "compiler", "build_type", "arch"
requires = "fmt/9.0.0"
default_options = {"fmt:shared": True}
And I've made two conan profiles:
clanglinux
[settings]
os=Linux
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=clang
compiler.version=14
build_type=Release
[env]
CC=clang
CXX=clang++
CONAN_CMAKE_GENERATOR=Ninja
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
[options]
[build_requires]
clangwindows
[settings]
os=Windows
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=clang
compiler.version=14
build_type=Release
[env]
CC=clang
CXX=clang++
CONAN_CMAKE_GENERATOR=Ninja
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
[options]
[build_requires]
When executing conan install for a native platform (in this case Windows) everything works as expected. However, when I try to cross-compile the dependency for Linux with conan install . --build=missing -pr:h=clanglinux -pr:b=clangwindows, I get the following error:
CMake Error at CMakeLists.txt:231 (add_library):
The install of the fmt target requires changing an RPATH from the build
tree, but this is not supported with the Ninja generator unless on an
ELF-based or XCOFF-based platform. The CMAKE_BUILD_WITH_INSTALL_RPATH
variable may be set to avoid this relinking step.
This error occurs after Conan's build() function get's called for the fmt package. It calls cmake with the following arguments:
cmake -G "Ninja"
-DCMAKE_TOOLCHAIN_FILE="C:/Users/name.surname/.conan/data/fmt/9.0.0/_/_/build/048e14dd7a94fe623d3253718843fce321999150/build/generators/conan_toolchain.cmake"
-DCMAKE_INSTALL_PREFIX="C:/Users/name.surname/.conan/data/fmt/9.0.0/_/_/package/048e14dd7a94fe623d3253718843fce321999150"
-DFMT_DOC="OFF"
-DFMT_TEST="OFF"
-DFMT_INSTALL="ON"
-DFMT_LIB_DIR="lib"
-DFMT_OS="ON"
-DCMAKE_POLICY_DEFAULT_CMP0091="NEW"
-DCMAKE_BUILD_TYPE="Release"
"C:\Users\name.surname\.conan\data\fmt\9.0.0\_\_\build\048e14dd7a94fe623d3253718843fce321999150\src"
As far as I know (correct me if I'm wrong), this command is specified in the fmt conanfile and I don't have a lot of control over it. But according to the error message, I should add -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON argument to the command. Is there a way to achieve this?
Also, why is it necessary to set CMAKE_BUILD_WITH_INSTALL_RPATH variable, can it be avoided altogether?
Thanks.

Related

How to use GCC with Conan & CMake on MacOS

I am tryting to setup a build of a project on my Macbook which should use GCC with both Conan & CMake.
I have set the following environment variables:
export CC=/usr/local/bin/gcc-12
export CXX=/usr/local/bin/g++-12
When I run Conan all libraries are installed (and built if missing):
conan install ../ --build=missing
My .conan/profiles/default shows that Conan has used gcc-12.
[settings]
os=Macos
os_build=Macos
arch=armv8
arch_build=armv8
compiler=gcc
compiler.version=12
compiler.libcxx=libstdc++11
build_type=Release
[options]
[build_requires]
[env]
When I run CMake with:
cmake -DCMAKE_C_COMPILER=/usr/local/bin/gcc-12 -DCMAKE_CXX_COMPILER=/usr/local/bin/g++-12 ../
I get the following error
cmake ../
-- Ubuntu: Using Conan to manage dependencies
-- Conan: Adjusting output directories
-- Conan: Using cmake global configuration
-- Conan: Adjusting default RPATHs Conan policies
-- Conan: Adjusting language standard
-- Current conanbuildinfo.cmake directory:
~/some-dir/build
CMake Error at build/conanbuildinfo.cmake:1812 (message):
Incorrect 'apple-clang', is not the one detected by CMake: 'GNU'
Call Stack (most recent call first):
build/conanbuildinfo.cmake:1369 (conan_check_compiler)
CMakeLists.txt:62 (conan_basic_setup)
build/conanbuildinfo.cmake:1369 contains the following:
message(FATAL_ERROR "Incorrect '${CONAN_COMPILER}', is not the one
detected by CMake: '${CMAKE_CXX_COMPILER_ID}'")
This indicates that CMake has detected the Conan compiler as AppleClang NOT GCC
I cannot see where conanbuildinfo.cmake gets the value for CONAN_COMPILER from.
How can I force CMake & Conan to use GCC-12?

CMake with Conan cannot find assimp-vc142-mt.lib

I'm trying to link assimp into a simple C++ project using Conan and CMake. However, when I build, it's giving me the following error:
LINK : fatal error LNK1104: cannot open file 'assimp-vc142-mt.lib' [C:\dev\test0\build\test.vcxproj]
Here is my conan default profile:
[settings]
os=Windows
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=Visual Studio
compiler.runtime=MD
compiler.version=16
build_type=Release
[options]
[build_requires]
[env]
I've made sure to use the same architecture for installing with Conan and building with CMake.
I've double checked that the library is installed.
I've installed other libraries (e.g. glfw) with no issues. Is this an issue with the Conan package, or am I missing something?
https://github.com/conan-io/conan-center-index/issues/7342
I had the CMake directives in the wrong order. You must do conan_basic_setup() before creating your executable and linking any libraries.

Need help completing command line installation of {fmt} on Windows 10

I'm a Linux user who's trying to set up a dev environment on Windows. I've cloned the fmt repo and built it the way I'm used to on Linux:
C:\Users\me\Development> git clone https://github.com/fmtlib/fmt.git
C:\Users\me\Development> cd fmt
C:\Users\me\Development> mkdir build
C:\Users\me\Development> cd build
C:\Users\me\Development> cmake ..
C:\Users\me\Development> cmake --build . --config Release
Now I want to install it so that I can include it in projects. Normally I would $ sudo make install but I'm not sure what to do on Windows and the fmt doc page has nothing for Windows installation.
When I did this same set of steps with FLTK there was a variable that I had to set to help me find things:
# CMakeLists.txt
set(FLTK_DIR "Path/to/installation")
find_package(FLTK REQUIRED NO_MODULE)
But it seems to be looking for the installation point, not the build dir. How can I get this to work?
You can run:
cmake --install . [--prefix <install-dir>]
The prefix is optional. On Windows, the default CMAKE_INSTALL_PREFIX is set to:
C:/Program Files (x86)/<project name>
Which in the case fmtlib would be:
C:/Program Files (x86)/FMT
Another option is to use vcpkg on Windows, which will install fmtlib locally in its own vcpkg install prefix. Then you can use it via:
find_package(fmt REQUIRED)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE fmt::fmt)
You just have to pass the vcpkg cmake toolchain file to your cmake invocation:
cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake

How to use conan to handle ImGui-SFML dependency in a cmake gcc project in Linux?

I want to handle the dependencies of a C++/cmake/gcc project in Linux using conan, and build an ImGui C++ demo as shown here: using imgui by Elias Daler
I have used conan to handle Boost dependencies successfully, but with ImGui-SFML I am having a linking error.
My conanfile.txt has the following instructions:
[requires]
imgui-sfml/2.1#bincrafters/stable
[imports]
bin, *.so -> ./bin
lib, *.a -> ./lib
[generators]
cmake_find_package
cmake_paths
cmake
And I added these lines to my CMakeLists.txt to work with conan:
include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
link_directories(${CONAN_LIB_DIRS})
target_link_libraries(my_project ${CONAN_LIBS})
Then, inside build/ I run the following command to build the library and install the dependencies:
conan install .. --build imgui-sfml
So far so good with conan, the libImGui-SFML.a is generated (it is also copied to build/lib because of the [imports], though I think the copy shouldn't be required since I'm adding the link_directories() instruction).
Then, I generate the makefiles
cmake ..
Finally, when I try to build the project
cmake --build ./
I get these linking errors:
/usr/bin/ld: cannot find -lImGui-SFML
/usr/bin/ld: cannot find -lopenal
/usr/bin/ld: cannot find -lFLAC++
/usr/bin/ld: cannot find -lFLAC
The libs generated by conan are static:
libFLAC.a
libFLAC++.a
libfreetype.a
libImGui-SFML.a
libogg.a
libopenal.a
This post looks related, but didn't work for ImGui: Installing gtest with conan
Is the program looking for shared libraries?
Am I missing some configuration in the conanfile.txt or in the CMakeLists.txt file?
Edit:
Conan version 1.25.2
According to this reported issue, this solution for a similar question, and conan's basic setup documentation, in this case the CMakeLists.txt should include: adding the argument TARGET in the setup, and the call to conan_target_link_libraries instead of the usual target_link_libraries, as follows:
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
conan_target_link_libraries(${PROJECT_NAME})
So the conanfile.txt just needs these instructions:
[requires]
imgui-sfml/2.1#bincrafters/stable
[generators]
cmake

How to set GoogleTest variables GTEST_LIBRARY GTEST_INCLUDE_DIR and GTEST_MAIN_LIBRARY to CMake on Windows?

There is a project that was developed for linux environment. Now I am trying to build this on windows using CMake.
I keep trying to build the project and always get this error:
CMake Error at C:/Program Files(x86)/CMake/share/cmake-3.3/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)
Call Stack (most recent call first):
C:/Program Files(x86)/CMake/share/cmake-3.3/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
C:/Program Files(x86)/CMake/share/cmake-3.3/Modules/FindGTest.cmake:204 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
C:/Users/awy9/git/cmake_modules/modules/SigeoGTest.cmake:21 (find_package)
C:/Users/awy9/git/cmake_modules/modules/SigeoInit.cmake:29 (include)
CMakeLists.txt:12 (include)
How can I set these variables to work on this project now on Windows?
Honestly It's not the best idea to set hardcoded variables like you've done with GTEST_LIBRARY and GTEST_MAIN_LIBRARY.
I had the exact same problem. I was using gtest 1.7.0 on windows and getting the same error.
Turns out "GTest" should be "gtest" (not capitalized).
So the code in my CMakeLists.txt became:
find_package(gtest REQUIRED)
Note that I was using CMake 3.9
EDIT
I would highly recommend following this guide now:
http://crascit.com/2015/07/25/cmake-gtest/
It is by far the best method I have found to use unbuilt gtest and gmock in your cmake project.
UPDATE
#Tsyvarev helped me solving the first problem and I quote him:
This is standard CMake message, when requested package(GTest in your case) is not found. You should install GTest before configuring your project. Or, if you already have installed it into non-standard location, pass this location via GTEST_ROOT variable: cmake -DGTEST_ROOT= ...
As alternative for the passing variable to cmake, you can set environment variable: set GTEST_ROOT=
This solved the problem with the value of GTEST_INCLUDE_DIR, but I still had these errors:
CMake Error at C:/Program Files (x86)/CMake/share/cmake-3.3/Modules/FindPackageH andleStandardArgs.cmake:148 (message): Could NOT find GTest (missing: GTEST_LIBRARY GTEST_MAIN_LIBRARY)
SOLUTION
I figured that on Windows environment some values are different from what the manuals say.
After compiling Gtest, I got two libs: gtest.lib and gtest_main.lib
Then, I set these filepath variables:
GTEST_LIBRARY=C:\Users\awy9\Softwares\Gtest\gtest-1.7.0\Debug\gtest.lib
GTEST_MAIN_LIBRARY=C:\Users\awy9\Softwares\Gtest\gtest-1.7.0\Debug\gtest_main.lib
Now everything is working!
Thank you
I've come up with a similar issue when building my project through GitHub Actions on Windows platform.
Even if I export the CMAKE_PREFIX_PATH to enable the find_package(GTest REQUIRED) to properly find the framework library (Windows is a bit nasty BTW), it continues to fail with Could NOT find GTest (missing: GTEST_LIBRARY GTEST_MAIN_LIBRARY). Note that it correctly fetches the include directory.
After digging a little bit deeper into the issue I realized that on Windows the command cmake --build . --target install without any --config options, builds the library in Debug configuration, contrary to Linux and macOS.
If you are then building your project in Release, e.g. cmake .. -DCMAKE_BUILD_TYPE=Release && cmake --build . --config Release --target install, the find_package(GTest REQUIRED) won't find any GTest library because it searches for the nonexistent Release build.
In this case a better solution is to install GTest in Release mode w.r.t. hardcoding the library paths to fetch the Debug\ directory builds.
I attach also the GitHub Action steps which may be helpful for someone:
steps:
- name: Clone GTest
shell: bash
working-directory: ${{runner.workspace}}
run: git clone https://github.com/google/googletest.git
- name: Create GTest Build Environment
shell: bash
working-directory: ${{runner.workspace}}/googletest
run: cmake -E make_directory build
- name: Configure GTest CMake
shell: bash
working-directory: ${{runner.workspace}}/googletest/build
run: cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS=-std=c++11
- name: Install GTest
shell: bash
working-directory: ${{runner.workspace}}/googletest/build
run: cmake --build . --config $BUILD_TYPE --target install || sudo cmake --build . --config $BUILD_TYPE --target install
- name: Export CMAKE_PREFIX_PATH on Windows
shell: bash
if: runner.os == 'Windows'
run: echo '::set-env name=CMAKE_PREFIX_PATH::C:/Program Files (x86)/googletest-distribution'
- name: Checkout
uses: actions/checkout#v2
- ... your project build steps