c++ - 创建柯南 test_package 配方

标签 c++ cmake conan

我目前正在玩柯南。所以我创建了两个小项目: 第一个项目是一个小型库“fcdk”:https://github.com/lmarzull/fcdk/tree/devel

第二个是一个包含 conan 和 circle-ci 的项目(还不知道我是否应该将 library/conan/circle-ci 分组在一个项目中,但这不是重点)。 第二个项目叫做“fcdk-conan”

我决定将库的单元测试放在“test_package”目录下的 fcdk-conan 项目中。我这样做是为了避免在我的“fcdk”库中依赖谷歌测试,而是在 fcdk-conan 项目中有这种依赖(不知道这是否是个好主意)

我创建了一个非常小的测试程序:

#include <iostream>

int
main()
{
  std::cout << "Hello, world!" << std::endl;
}

一切都很好。

但是现在,我想为我的库添加一些单元测试。所以我需要找到/编译/链接“fcdk”库。所以我将 main.cc 文件更改为这个:

#include <iostream>
#include <fcdk/CommandLineOptionFlag.h>

int
main()
{
  FCDK::CommandLineOptionFlag show_help('h', "help", "show this help message");
  std::cout << "Hello, world!" << std::endl;
}

这里是test_package目录下的CMakeLists.txt:

cmake_minimum_required(VERSION 3.2)
project(FcdkTest CXX)


include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)


add_executable(
  test-fcdk
  main.cc
)
target_include_directories(test-fcdk PUBLIC ${CONAN_INCLUDE_DIRS_FCDK})
target_link_libraries(test-fcdk PUBLIC ${CONAN_LIBS_FCDK})
target_link_libraries(test-fcdk PUBLIC CONAN_PKG::fcdk)

enable_testing()
add_test(NAME test-fcdk
         WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
         COMMAND test-fcdk)

还有柯南食谱:

import os
from conans import ConanFile, CMake, tools


class FcdkTestConan(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "cmake"
    requires = "fcdk/1.0.0"

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def test(self):
        if not tools.cross_building(self.settings):
            os.chdir("bin")
            self.run(".%stest-fcdk" % os.sep)

我无法实现 test_package 以正确链接。

CMakeFiles/test-fcdk.dir/main.cc.o: In function `FCDK::CommandLineOptionFlag::accept(FCDK::VisitorBase&)':
main.cc:(.text._ZN4FCDK21CommandLineOptionFlag6acceptERNS_11VisitorBaseE[_ZN4FCDK21CommandLineOptionFlag6acceptERNS_11VisitorBaseE]+0xa1): undefined reference to `FCDK::demangleTypename(char const*)'
main.cc:(.text._ZN4FCDK21CommandLineOptionFlag6acceptERNS_11VisitorBaseE[_ZN4FCDK21CommandLineOptionFlag6acceptERNS_11VisitorBaseE]+0xdd): undefined reference to `FCDK::demangleTypename(char const*)'
CMakeFiles/test-fcdk.dir/main.cc.o: In function `main':
main.cc:(.text.startup+0x5e): undefined reference to `FCDK::CommandLineOptionFlag::CommandLineOptionFlag(char, std::string, std::string)'

所有上一步:

conan source 
conan install
conan build
conan package
conan export-pkg

很好,对我来说似乎是正确的。我把conan包命令的内容放在这里:

package/
package/conaninfo.txt
package/include
package/include/fcdk
package/include/fcdk/Exception.h
package/include/fcdk/CommandLineOption.h
package/include/fcdk/CommandLineOptionWithValue.h
package/include/fcdk/Visitor.h
package/include/fcdk/ABI.h
package/include/fcdk/CommandLineParser.h
package/include/fcdk/CommandLineOptionFlag.h
package/conanmanifest.txt
package/lib
package/lib/libfcdk.a
package/share
package/share/cmake
package/share/cmake/fcdk
package/share/cmake/fcdk/fcdkTargets.cmake
package/share/cmake/fcdk/fcdkTargets-release.cmake

我还查看了 libfcdk.a 中丢失的符号 例如:

                 U FCDK::demangleTypename[abi:cxx11](char const*)
                 U FCDK::demangleTypename[abi:cxx11](char const*)
0000000000000000 t _GLOBAL__sub_I__ZN4FCDK16demangleTypenameB5cxx11EPKc
0000000000000000 T FCDK::demangleTypename[abi:cxx11](char const*)

当我使用 VERBOSE=1 运行 make 时,我没有在链接命令上看到 fcdk 库信息

/usr/bin/cmake -E cmake_link_script CMakeFiles/test-fcdk.dir/link.txt --verbose=1
/usr/bin/c++   -m64 -O3 -DNDEBUG  -rdynamic CMakeFiles/test-fcdk.dir/main.cc.o  -o bin/test-fcdk 
CMakeFiles/test-fcdk.dir/main.cc.o: In function `FCDK::CommandLineOptionFlag::accept(FCDK::VisitorBase&)':

有人能帮我弄清楚为什么 test_pacakge 配方没有链接到我的 fcdk/1.0.0 包吗?

非常感谢

编辑:更新了 test_pacakge 的柯南存储库 https://github.com/lmarzull/fcdk-conan/tree/devel

最佳答案

test_package 文件夹的要点是,如果它包含一个带有 test() 函数的 conanfile.py,Conan 会自动包完全创建后处理它。


从以下基本项目结构开始,让我们构建一个具有单一依赖项的简单库:

.
├── CMakeLists.txt
├── conanfile.py
├── src
│   ├── mylib.cpp
│   └── mylib.hpp
└── test_package
    ├── CMakeLists.txt
    ├── conanfile.py
    └── main.cpp

顶级CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(mylib)

find_package(fmt REQUIRED) // Version is handled by Conan

add_library(${PROJECT_NAME} src/mylib.cpp src/mylib.hpp)
target_link_library(${PROJECT_NAME} PRIVATE fmt::fmt)

// This will automatically install at the right place depending on the platform
// e.g. a .DLL file goes to bin while .SO/.A/.LIB files go to lib
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME})
install(DIRECTORY src/
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
        FILES_MATCHING PATTERN "*.hpp")

顶级conanfile.py:

from conan             import ConanFile
from conan.tools.cmake import CMake, cmake_layout


class MylibConan(ConanFile):
    name            = "mylib"
    version         = "1.0.0"
    settings        = "os", "compiler", "build_type", "arch"
    requires        = "fmt/9.1.0"
    options         = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}
    generators      = "CMakeToolchain", "CMakeDeps"
    exports_sources = "CMakeLists.txt", "src/*"

    def layout(self):
        cmake_layout(self)

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        CMake(self).install()

    def package_info(self):
        self.cpp_info.libs = [self.name]

test_package/main.cpp:

#include <mylib/mylib.hpp>

int main()
{
    mylib();
}

test_package/CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)
project(test_package)

find_package(mylib QUIET)
if(NOT mylib_FOUND)
    message(FATAL_ERROR "This project can only be built with a 'conan create' command in the parent directory!")
endif()

add_executable(${PROJECT_NAME} main.cpp)
// Put the exe in the same place for both Single- and Multi-Config generators
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY bin/$<0:>)
target_link_libraries(${PROJECT_NAME} mylib::mylib)

test_package/conanfile.py:

from conan             import ConanFile
from conan.tools.cmake import CMake, cmake_layout
from os.path           import join


class MylibTestConan(ConanFile):
    settings   = "os", "compiler", "build_type", "arch"
    generators = "CMakeToolchain", "CMakeDeps"

    def requirements(self):
        self.requires(self.tested_reference_str)

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def test(self):
        self.run(join(self.build_folder, "bin", "test_package"))

现在您可以调用 conan create. 并且您的 test_package 将自动构建并在您的本地目录中运行。

关于c++ - 创建柯南 test_package 配方,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58881833/

相关文章:

c++ - 如何修复此错误(将 wchar_t 转换为 BSTR)?

linux - 尽管使用了正确的工具链文件,但为什么 CMake 在交叉编译 Net-SNMP 代理时明显引用主机系统文件?

c++ - 为什么我的共享库在使用 CMake 时链接不正确?

artifactory - Artifactory OSS 中是否提供 Conan 存储库?

c++ - DirectX 11 和 FreeType

c++ - 我怎样才能部分特化所有枚举的类模板?

linux - 如何通过命令行编辑和保存Python文件

c++ - 将 yaml-cpp 与 conan 链接

c++ - 如果数组很大,使用指针作为 C++ 类成员是否是一种更有效的方法?

c++ - 使用 CMAKE 和 RPATH 捆绑 FFMPEG