Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] find_package can't find config files if cross compilation/2 profiles #9202

Closed
SpaceIm opened this issue Jul 4, 2021 · 15 comments · Fixed by #9437
Closed

[bug] find_package can't find config files if cross compilation/2 profiles #9202

SpaceIm opened this issue Jul 4, 2021 · 15 comments · Fixed by #9437
Milestone

Comments

@SpaceIm
Copy link
Contributor

SpaceIm commented Jul 4, 2021

Environment Details (include every applicable attribute)

  • Operating System+version: Macos Catalina
  • Compiler+version: AppleClang 12
  • Conan version: 1.38.0
  • Python version: 3.9.6

Steps to reproduce (Include if Applicable)

  • clone conan-center-index
  • in recipes/re2/all: conan create . re2/20210601 -pr:b profile_build -pr:h profile_host (profile_build and profile_host must be different, otherwise it works).
  • You can test all recipes where test package relies on cmake_find_package_multi, it will fail.

example of profiles on macOS:

profile_build:

[settings]
os=Macos
arch=x86_64
compiler=apple-clang
compiler.version=12.0
compiler.libcxx=libc++
build_type=Release
[options]
[build_requires]
[env]

profile_host:

[settings]
os=iOS
os.version=12.0
arch=x86_64
compiler=apple-clang
compiler.version=12.0
compiler.libcxx=libc++
build_type=Release
[options]
[build_requires]
[env]

Logs (Executed commands with output) (Include/Attach if Applicable)

re2/20210601 (test package): Calling build()
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: called by CMake conan helper
-- Conan: Adjusting output directories
-- Conan: Using cmake targets configuration
-- Library re2 found /Users/spaceim/.conan/data/re2/20210601/_/_/package/5839e36f8f9b4a19c6ebf23cc2d929e50f6634a3/lib/libre2.a
-- Conan: Adjusting default RPATHs Conan policies
-- Conan: Adjusting language standard
-- Conan: C++ stdlib: libc++
CMake Error at CMakeLists.txt:7 (find_package):
  Could not find a package configuration file provided by "re2" with any of
  the following names:

    re2Config.cmake
    re2-config.cmake

  Add the installation prefix of "re2" to CMAKE_PREFIX_PATH or set "re2_DIR"
  to a directory containing one of the above files.  If "re2" provides a
  separate development package or SDK, be sure it has been installed.


-- Configuring incomplete, errors occurred!
See also "/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47/CMakeFiles/CMakeOutput.log".
ERROR: re2/20210601 (test package): Error in build() method, line 11
	cmake.configure()
	ConanException: Error 1 while executing cd '/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47' && cmake -G "Ninja" -DCMAKE_BUILD_TYPE="Release" -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_OSX_SYSROOT="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.2.sdk" -DCMAKE_SYSTEM_NAME="iOS" -DCMAKE_SYSTEM_VERSION="12.0" -DCMAKE_OSX_DEPLOYMENT_TARGET="12.0" -DCONAN_IN_LOCAL_CACHE="OFF" -DCONAN_COMPILER="apple-clang" -DCONAN_COMPILER_VERSION="12.0" -DCONAN_CXX_FLAGS="-m64" -DCONAN_SHARED_LINKER_FLAGS="-m64" -DCONAN_C_FLAGS="-m64" -DCONAN_LIBCXX="libc++" -DCMAKE_INSTALL_PREFIX="/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47/package" -DCMAKE_INSTALL_BINDIR="bin" -DCMAKE_INSTALL_SBINDIR="bin" -DCMAKE_INSTALL_LIBEXECDIR="bin" -DCMAKE_INSTALL_LIBDIR="lib" -DCMAKE_INSTALL_INCLUDEDIR="include" -DCMAKE_INSTALL_OLDINCLUDEDIR="include" -DCMAKE_INSTALL_DATAROOTDIR="share" -DCMAKE_PREFIX_PATH="/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47" -DCMAKE_MODULE_PATH="/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package/build/2c279fb31e3d673fddcf5217074ac0c07e5dbc47" -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY="ON" -DCONAN_EXPORTED="1" -Wno-dev '/Users/spaceim/Documents/projects/conan-center-index/recipes/re2/all/test_package'
c

Is it related to CMake helper? conan_basic_setup()? I don't know. From what I saw, CMAKE_PREFIX_PATH and CMAKE_MODULE_PATH are properly set, and re2-config.cmake is located in build folder of test package.
If I replace in test package cmake_find_package_multi by cmake_find_package, and find_package(re2 REQUIRED CONFIG) by find_package(re2 REQUIRED), it works.
This is a simple example, but this issue breaks cross compilation of several more complex CCI recipes where CMake configuration of the lib itself relies on discovery of CMake config files generated by cmake_find_package_multi (I've seen this issue in libgeotiff originally, after fixing cross compilation issues of its (transitive) dependencies like proj, sqlite3 or jbig).

@SpaceIm SpaceIm changed the title [bug] find_package can't find config files with cross compilation and 2 profiles [bug] find_package can't find config files if cross compilation/2 profiles Jul 4, 2021
@memsharded
Copy link
Member

I have tried with Windows and Linux (I don't have a Mac), and even when the profile host and profile build are different (I tried compiling for 32 bits), it works.

Someone else that could try in OSX->iOS, please?

@SpaceIm it would be good to know if this is a 1.38 regression, and it used to work in 1.37 or also failing in previous Conan versions.

@memsharded memsharded added this to the 1.39 milestone Jul 4, 2021
@SpaceIm
Copy link
Contributor Author

SpaceIm commented Jul 6, 2021

I don't know for older versions of conan, I'll try.

@SpaceIm
Copy link
Contributor Author

SpaceIm commented Jul 6, 2021

I've tried with conan 1.35.0, 1.36.0 and 1.37.0, it fails with the same error.

@czoido
Copy link
Contributor

czoido commented Jul 9, 2021

Thanks for the detailed report, I could reproduce the error on Macos, I'll try to investigate further what could be the issue.

@memsharded
Copy link
Member

I think this issue was solved for OSX in the CMakeToolchain by @lasote, adding the XXX_DIR variable to packages for OSX exclusively.

@lasote
Copy link
Contributor

lasote commented Jul 12, 2021

Hi, yes, the new CMakeToolchain already solves this issue. With the old cmake generators you will need a workaround.
You can add set(re2_DIR ${CMAKE_BINARY_DIR}) in the CMakeLists.txt file after the conan_basic_setup() call.

Edit: The root cause is that CMake only search the Macos folders when crossbuilding. Another weird and unexpected behavior to be honest.

@memsharded
Copy link
Member

memsharded commented Jul 12, 2021

I have closed without merging #9250, this is solved in the new CMakeToolchain, fixing it in the old ones is complicated and risky, it only applies to one very specific scenario (OSX and cross-build) and a workaround is relatively straightforward. Thanks all!

@SpaceIm
Copy link
Contributor Author

SpaceIm commented Jul 13, 2021

@memsharded When you say "new CMakeToolchain", you refer to CMakeDeps?

FYI, this issue breaks several build of CCI recipes, and many test_package, so it prevents CCI to add a configuration for iOS. CCI can't use CMakeDeps for the moment, and some recipes must model Find AND config files because they are different (like protobuf).

@memsharded
Copy link
Member

memsharded commented Jul 13, 2021

@memsharded When you say "new CMakeToolchain", you refer to CMakeDeps?

No, it is included in the find_paths block of CMakeToolchain. This is not about the deps itself, but where to locate the xxx-config.cmake files generated by Conan.

FYI, this issue breaks several build of CCI recipes, and many test_package, so it prevents CCI to add a configuration for iOS.

How can it break the build, if CCI is not cross-building and not using 2 profiles? It is not intended to add iOS as a configuration to ConanCenter.

CCI can't use CMakeDeps for the moment, and some recipes must model Find AND config files because they are different (like protobuf).

It will also be possible to use CMakeDeps and CMakeToolchain in ConanCenter very soon.

@SpaceIm
Copy link
Contributor Author

SpaceIm commented Jul 13, 2021

@memsharded It's true that CCI doesn't build binaries for iOS currently, but @jgsogo may add this profile conan-io/conan-center-index#6045 (comment). So yes it doesn't break CI of CCI, but it might break consumers using others profiles. It's not because CI of CCI doesn't test those profiles, that CCI recipes shouldn't support them.

Here is a simple fix in cmake generator (prepend build_modules paths of requirements + CMAKE_CURRENT_LIST_DIR to CONAN_CMAKE_FIND_ROOT_PATH in conanbuildinfo.cmake): conan-io/conan-center-index#6315 (comment)

@jgsogo
Copy link
Contributor

jgsogo commented Jul 14, 2021

Hi! This kind of addition/fixes/enhancements would be very valuable from the point of view of conan-center-index. Right now we are building Macos/armv8 using two profiles (cross-building from regular Macos) and we have fixed many recipes, not because now it works for this new configuration, but because in the way we have removed legacy and improve their quality for other configurations.

Right now we are receiving a lot of PRs related to iOS, some of them adding support and some others just fixing things that were working but some PR broke (I've broken several recipes for other configurations while trying to add support for M1). It translates into many more PRs and more burden on some people that are really taking care of conan-center-index and recipe quality. It happens for iOS, but also for Android and Linux/ARM. If we don't test a configuration, someone will break it.

Gathering feedback from the community, we feel that it would be very valuable to add some of these configurations to ensure that the recipes are not broken when we fix something (M1, iOS, Android, Conan v2,...). The plan is to stop generating some of the current configurations following the lead of the new docker images and the data about most used configurations that we are starting to collect... and use that spare capacity to build other configurations that will be much more valuable.

It will take time to provide this capability in ConanCenter, I'm not sure if by that time all the new CMakeDeps/CMakeToolchain will be fully available and stable. Anyway, the sooner we can have the right recipes for these configurations, the better, that way contributors can work on consumer recipes, otherwise whenever we find one of these blockers, we cannot work on dependents... and it really takes time to progress on the graph of dependencies.

@SpaceIm
Copy link
Contributor Author

SpaceIm commented Jul 16, 2021

Just to mention that the fact that CONAN_CMAKE_FIND_ROOT_PATH is not properly set in conanbuildinfo.cmake doesn't break only find_package() of config files, but things like find_library() or find_path(), or targets defined by pkg_check_modules(), making some libraries very hard to package for iOS.

set(re2_DIR ${CMAKE_BINARY_DIR}) is a workaround to find config files only, but ti doesn't help when we package libraries using a custom Find module file calling find_library() and find_path(). Moreover, I'm not sure it's a good idea to add more complexity in CCI recipes just for one configuration.

Here are several CCI recipes whose build is broken (not only test package) due to this issue:

  • grpc
  • ignition-math
  • libgeotiff
  • libmysqlclient
  • libnghttp2
  • redis-plus-plus
  • tesseract
  • vcglib

@SpaceIm
Copy link
Contributor Author

SpaceIm commented Jul 16, 2021

@memsharded Sorry to bother you, but I have a fix that I've tested locally with several recipes in native and cross-build scenario:

--- a/conans/client/generators/cmake_common.py
+++ b/conans/client/generators/cmake_common.py
@@ -108,6 +108,7 @@ set(CONAN_FRAMEWORKS_FOUND{build_type} "")  # Will be filled later
 set(CONAN_DEFINES{build_type} {deps.defines} ${{CONAN_DEFINES{build_type}}})
 set(CONAN_BUILD_MODULES_PATHS{build_type} {deps.build_modules_paths} ${{CONAN_BUILD_MODULES_PATHS{build_type}}})
 set(CONAN_CMAKE_MODULE_PATH{build_type} {deps.build_paths} ${{CONAN_CMAKE_MODULE_PATH{build_type}}})
+set(CONAN_CMAKE_FIND_ROOT_PATH{build_type} {deps.build_paths} ${{CMAKE_CURRENT_LIST_DIR}} ${{CONAN_CMAKE_FIND_ROOT_PATH{build_type}}})
 
 set(CONAN_CXX_FLAGS{build_type} "{deps.cxxflags} ${{CONAN_CXX_FLAGS{build_type}}}")
 set(CONAN_SHARED_LINKER_FLAGS{build_type} "{deps.sharedlinkflags} ${{CONAN_SHARED_LINKER_FLAGS{build_type}}}")

Would you consider a PR for this issue?

SpaceIm added a commit to SpaceIm/conan-center-index that referenced this issue Jul 16, 2021
it's worth noting that recipe still fails if cross-building to iOS due to conan-io/conan#9202
conan-center-bot pushed a commit to conan-io/conan-center-index that referenced this issue Jul 19, 2021
* fix bundle destination for iOS/tvOS/watchOS

it's worth noting that recipe still fails if cross-building to iOS due to conan-io/conan#9202

* bump leptonica

* no os.rename

* move checks to validate()
AndreyMlashkin pushed a commit to AndreyMlashkin/conan-center-index that referenced this issue Jul 19, 2021
…nize

* fix bundle destination for iOS/tvOS/watchOS

it's worth noting that recipe still fails if cross-building to iOS due to conan-io/conan#9202

* bump leptonica

* no os.rename

* move checks to validate()
@SpaceIm
Copy link
Contributor Author

SpaceIm commented Jul 31, 2021

After more experimentations, the less fragile solution I've found is:

--- a/conans/client/generators/cmake_common.py
+++ b/conans/client/generators/cmake_common.py
@@ -108,6 +108,7 @@ set(CONAN_FRAMEWORKS_FOUND{build_type} "")  # Will be filled later
 set(CONAN_DEFINES{build_type} {deps.defines} ${{CONAN_DEFINES{build_type}}})
 set(CONAN_BUILD_MODULES_PATHS{build_type} {deps.build_modules_paths} ${{CONAN_BUILD_MODULES_PATHS{build_type}}})
 set(CONAN_CMAKE_MODULE_PATH{build_type} {deps.build_paths} ${{CONAN_CMAKE_MODULE_PATH{build_type}}})
+set(CONAN_CMAKE_FIND_ROOT_PATH{build_type} ${{CMAKE_CURRENT_LIST_DIR}} ${{CONAN_CMAKE_FIND_ROOT_PATH{build_type}}})
 
 set(CONAN_CXX_FLAGS{build_type} "{deps.cxxflags} ${{CONAN_CXX_FLAGS{build_type}}}")
 set(CONAN_SHARED_LINKER_FLAGS{build_type} "{deps.sharedlinkflags} ${{CONAN_SHARED_LINKER_FLAGS{build_type}}}")

${{CMAKE_CURRENT_LIST_DIR}} => for conan generated config files

{deps.build_paths} can't be added, because it would put executables paths of host context in CMAKE_FIND_ROOT_PATH. It's important for recipes where the same dependency is in requirements() dans build_requirements() (for example protobuf), to avoid find_program to find executables of host context.

But find_library() and find_path() still fail if host is iOS/tvOS/watchOS (and I guess it will be the same in conan v2).

opencv recipe in CCI is a good example. In some module files, it uses find_library() and find_path() for libwebp and openexr, and it can't find libs and headers if iOS/tvOS/watchOS.
If you add {deps.build_paths} in CONAN_CMAKE_FIND_ROOT_PATH, it can find libs and headers of libwebp and openexr, but find the wrong protobuf executable (host context instead of build context).
If you add rootpath of libwebp and openexr only to CONAN_CMAKE_FIND_ROOT_PATH, it succeeds.

@lasote lasote reopened this Aug 4, 2021
@lasote lasote modified the milestones: 1.39, 1.40 Aug 4, 2021
@SpaceIm
Copy link
Contributor Author

SpaceIm commented Aug 6, 2021

Another solution:

conanbuildinfo.cmake (or maybe CMake helper) could just force these variables to a consistent value:

set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) # for find_library()
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) # for find_file() and find_path()
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) # for find_package()
# maybe also CMAKE_FIND_ROOT_PATH_MODE_PROGRAM?

Problems appear when they are automatically set to ONLY by CMake (which seems to be the case when you cross-compile to iOS, but for example when I cross-compile from Macos x86-64 to Macos armv8, I don't have any issue, so I don't even know how CMake set the default values of these variables).

https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html#variables-that-change-behavior

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants