如何使conan生成FindXXX.cmake

How do I make conan generate a FindXXX.cmake?

本文关键字:FindXXX cmake 生成 conan 何使      更新时间:2023-10-16

我一直在用conan为我工作的一个项目使用的所有库创建包。我为每个人创建了一个conanfile.py,一切都很好。我已经为一个伪代码创建了一个conanfile.txt,以确保一切都如预期的那样工作。我运行过

conan安装--build=缺少

这已经编译了所有的程序包。我可以在CMake文件中使用${CONN_INCLUDE_DIRS}和${CONN_LIBS}。然而,我希望将conan作为一种可选的方式,使用Find_package(…)作为获取库位置、链接和包含详细信息的一种方式。

所以我很想看看

柯南0.6新增!现在,conan为CMake find_package提供了自动支持,而无需为每个包创建自定义的FindXXX.CMake文件(conan 0.5)

所以我认为它应该起作用。但是没有生成FindXXX.cmake文件。

以下是我的一个conanfile.py作为OpenMPI:的示例

from conans import ConanFile
import os
from conans.tools import download
from conans.tools import unzip
from conans import CMake
from conans import ConfigureEnvironment
class OpenMPIConan(ConanFile):
    name = "OpenMPI"
    version = "2.0.0"
    generators = "cmake"
    settings = "os", "arch", "compiler", "build_type"
    url="https://www.open-mpi.org/software/ompi/v2.0/"
    license="https://www.open-mpi.org/community/license.php"
    source_url = "https://www.open-mpi.org/software/ompi/v2.0/downloads/openmpi-2.0.0.tar.bz2"
    unzipped_path = "openmpi-2.0.0/"

    def source(self):
        self.zip_name = os.path.basename(self.source_url)
        download(self.source_url, self.zip_name)
        unzip(self.zip_name)
        os.unlink(self.zip_name)
    def build(self):
        self.run("%s/%s/configure --enable-mpi-thread-multiple --enable-mpi-cxx --prefix=%s CC=clang CXX=clang++" % (self.conanfile_directory, self.unzipped_path, self.package_folder))
        self.run("%s make -j 8 install" % env.command_line)
    def package(self):
        self.copy("*.h", dst="include", src="install/include")
        self.copy("*.lib", dst="lib", src="install/lib")
        self.copy("*.a", dst="lib", src="install/lib")
    def package_info(self):
        self.cpp_info.libs = ["mpi", "mpi_cxx"]

为什么没有创建FineOpenMPI.cmake文件?我如何确保它被创建?

附言:如果我理解正确的话,就没有必要使用包装方法。

EDIT:自Conan 1.14以来,有一个cmake_find_package_multi生成器,它实际上会为您生成具有可传递目标的XXXCMake.cmake,以满足您的需求。参见此处


柯南没有自动创建FindXXX.cmake。"0.6中的new"消息意味着,对于常见的包,cmake安装(工具包)提供的FindXXX.cmake应该可以工作。

这是因为从conan 0.6开始,我们将conan_CMAKE_MODULE_PATHCMAKE_PREFIX_PATH变量设置为包的根文件夹,因此CMAKE find_library函数应该能够在那里找到库。

但遗憾的是,它并不总是有效的,我们没有正确地记录这个过程。我很快就会更新文档。它只在有"官方"findXXX的情况下自动工作,而不是在所有情况下,因为有时官方的findXXX.cmake文件会搜索与构建系统创建的文件名不同的库(不准备搜索conan可以处理的所有设置的文件名或库不同名称的包库,或者有时findXXX会在c:\OpenSSL等固定路径中搜索)。

因此,在OpenMPI的特定情况下,cmake安装没有提供官方的FindOpenMPI.cmake文件,因此您需要创建它并将其添加到您的conan包中。让我们看一个ZLIB库conan包的例子:

  1. 创建一个名为FindOpenMPI.cmake的文件,并将其保存在您的conan包根文件夹中。我通常建议从提供的工具包(文件夹Modules/Find***.cmake)中复制原始的FindXXX.cmake文件。并对其进行一些修改,以帮助查找我们的库文件。如果没有提供(您的案例),这不是问题,请查看以下示例:
find_path(ZLIB_INCLUDE_DIR NAMES zlib.h PATHS ${CONAN_INCLUDE_DIRS_ZLIB})
find_library(ZLIB_LIBRARY NAMES ${CONAN_LIBS_ZLIB} PATHS ${CONAN_LIB_DIRS_ZLIB})
set(ZLIB_FOUND TRUE)  
set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
mark_as_advanced(ZLIB_LIBRARY ZLIB_INCLUDE_DIR)

在第一行中,我们向CMake指示应该找到标头的路径CONAN_INCLUDE_DIRS_XXX,然后对于具有CONAN_LIBS_XXX的库名称和库为CONAN_LIB_DIRS_XXX的路径也是如此。

  1. conanfile.py文件中,将FindOpenMPI.cmake添加到导出中:

    exports = ["FindOpenMPI.cmake"]

  2. 在package方法中,将FindOpenMPI.cmake文件复制到根目录:

    self.copy("FindOpenMPI.cmake", ".", ".")

我建议创建一个干净的FindOpenMP-cmake文件,非常类似于我们上面看到的ZLIB示例,并尝试它是否有效。

您的CMakeLists.txt可能如下所示:

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
CONAN_BASIC_SETUP()
find_package("OpenMPI")
IF(OpenMPI_FOUND)
    ADD_EXECUTABLE(xxxxxx source1.c)
    include_directories(${OpenMPI_INCLUDE_DIRS})
    TARGET_LINK_LIBRARIES(xxxxxx ${OpenMPI_LIBRARIES})
ELSE()
    MESSAGE(FATAL_ERROR "OpenMPI not found")
ENDIF()