微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Conan.io 和仅标头库

如何解决Conan.io 和仅标头库

我正在尝试从现有的仅头文件库创建一个 conan 包。这不是带有 include 文件夹的教科书示例 - 结构如下所示:

public/SomeHeader.hpp
public/CHeader.h
public/anotherFolder/AnotherHeader.hpp

这是我基于 Documentation 和其他一些 thingsconanfile.py

from conans import ConanFile

class MyLibConan(ConanFile):
    name = "MyLib"
    version = "1.0"

def package_info(self):
    self.cpp_info.includedirs = ["public","public/anotherFolder"]

def package(self):
    self.copy("*.hpp",dst="public",src="public",keep_path=False)
    self.copy("*.h",keep_path=False)

我应该在 package() 方法或 cpp_info.includedirs 中使用 self.copy 吗?有什么区别?

我这样导出包,目前没有错误

 export . demo/test

然后在我的主项目中,我有 conanfile.txt 如下:

 [requires]
 MyLib/1.0@demo/test

 [generators]
 cmake

我的 CMakeLists.txt 以前只是将 exec 链接到 MyLib(接口库)

include_directories(MyLibFolder)
add_executable(soMetarget ...)
target_link_libraries(soMetarget MyLib)

现在看起来像这样:

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
...
target_link_libraries(soMetarget ${CONAN_LIBS})

编译后的项目

mkdir build && cd build
conan install ..
cmake .. -G Ninja
cmake --build .

我收到错误... :(

Fatal error: anotherFolder/AnotherHeader.hpp: No such file or directory
#include <anotherFolder/AnotherHeader.hpp>

我对柯南非常新鲜,我无法理解如何构建 conanfile.py。我尝试了很多不同的组合,但都没有成功

提前致谢,

干杯

解决方法

以下是针对您的案例的一些答案:

我应该在 package() 方法或 cpp_info.includedirs 中使用 self.copy 吗?有什么区别?

就您而言,self.copy 是更好的选择。默认情况下,includedirs 定义为 ["include"],我们通常仅在软件包安装未按照预期遵循正确的文件夹结构时才附加其他文件夹。

这是我基于文档和其他一些东西的 conanfile.py。

您的示例缺少一个非常重要的属性:exports_sources,没有它,Conan 在运行 conan export 命令时将不会复制您的头文件。因此,您的食谱应如下所示:

from conans import ConanFile

class MyLibConan(ConanFile):
    name = "MyLib"
    version = "1.0"
    exports_sources = ["public/*"]
    no_copy_sources = True

    def package(self):
        self.copy("*.hpp",dst="include",src="public")
        self.copy("*.h",src="public")

您的柯南导出将包含列出的文件:

$ conan export . demo/test
Exporting package recipe
MyLib/1.0@demo/test exports_sources: Copied 1 '.h' file: CHeader.h
MyLib/1.0@demo/test exports_sources: Copied 2 '.hpp' files: Someheader.hpp,AnotherHeader.hpp
MyLib/1.0@demo/test: A new conanfile.py version was exported
MyLib/1.0@demo/test: Folder: /home/uilian/.conan/data/MyLib/1.0/demo/test/export
MyLib/1.0@demo/test: Using the exported files summary hash as the recipe revision: f367d0a701a867835b7ac612b90b3d1c 
MyLib/1.0@demo/test: Exported revision: f367d0a701a867835b7ac612b90b3d1c

但是您仍然没有柯南包,您需要运行conan install MyLib/1.0@demo/test --build=MyLib。您可以使用更好的命令来创建包,而不是运行 2 步,conan create:

$ conan create . demo/test
Exporting package recipe
MyLib/1.0@demo/test exports_sources: Copied 1 '.h' file: CHeader.h
MyLib/1.0@demo/test exports_sources: Copied 2 '.hpp' files: Someheader.hpp,AnotherHeader.hpp
MyLib/1.0@demo/test: A new conanfile.py version was exported
MyLib/1.0@demo/test: Folder: /home/conan/.conan/data/MyLib/1.0/demo/test/export
MyLib/1.0@demo/test: Exported revision: f367d0a701a867835b7ac612b90b3d1c
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++
compiler.version=9
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

MyLib/1.0@demo/test: Forced build from source
Installing package: MyLib/1.0@demo/test
Requirements
    MyLib/1.0@demo/test from local cache - Cache
Packages
    MyLib/1.0@demo/test:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Build

Installing (downloading,building) binaries...
MyLib/1.0@demo/test: Configuring sources in /home/conan/.conan/data/MyLib/1.0/demo/test/source
MyLib/1.0@demo/test: Copying sources to build folder
MyLib/1.0@demo/test: Building your package in /home/conan/.conan/data/MyLib/1.0/demo/test/build/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9
MyLib/1.0@demo/test: Generator txt created conanbuildinfo.txt
MyLib/1.0@demo/test: Calling build()
MyLib/1.0@demo/test: WARN: This conanfile has no build step
MyLib/1.0@demo/test: Package '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' built
MyLib/1.0@demo/test: Build folder /home/conan/.conan/data/MyLib/1.0/demo/test/build/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9
MyLib/1.0@demo/test: Generated conaninfo.txt
MyLib/1.0@demo/test: Generated conanbuildinfo.txt
MyLib/1.0@demo/test: Generating the package
MyLib/1.0@demo/test: Package folder /home/conan/.conan/data/MyLib/1.0/demo/test/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9
MyLib/1.0@demo/test: Calling package()
MyLib/1.0@demo/test package(): Packaged 2 '.hpp' files: Someheader.hpp,AnotherHeader.hpp
MyLib/1.0@demo/test package(): Packaged 1 '.h' file: CHeader.h
MyLib/1.0@demo/test: Package '5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9' created
MyLib/1.0@demo/test: Created package revision d1a54d50f9ded97d33be080f4a1ef606

现在您有更多的输出,因为柯南不仅要导出,还要构建和打包您的包。构建部分实际上是谎言,因为我们省略了 build()

我收到错误... :(

致命错误:anotherFolder/AnotherHeader.hpp:没有那个文件或目录 #include

因为这一行:

self.copy("*.hpp",dst="public",src="public",keep_path=False)

你的包裹里会有它:

$ ls -R public/
public/:
AnotherHeader.hpp  CHeader.h  Someheader.hpp

设置 keep_path=False 时,您告诉柯南复制所有 *.h 文件并保存到 public/ 文件夹中,但不要保留原始路径 AnotherFolder/

但是,让我们看看新的实现:

self.copy("*.hpp",src="public")
self.copy("*.h",src="public")

现在保留路径,使用 include/ 作为文件夹。为什么? include/ 是用于头文件的通用名称,就像 src/ 用于 .c 和 .cpp 等源文件一样。尽量保持这种模式。

$ ls -R include/
include/:
CHeader.h  Someheader.hpp  anotherFolder

include/anotherFolder:
AnotherHeader.hpp

现在我们可以看到标题文件夹仍然存在,您的错误不会再次发生。

问候。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。