gpt4 book ai didi

c++ - 库标题和#define

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:08:26 24 4
gpt4 key购买 nike

我不确定该搜索什么。如果这很简单,请原谅。但让我概述一下场景,看看那里有什么答案。

假设我有一个定义如下结构的库:

struct Example {
int a;
#if B_ENABLED
int b;
#endif
};

此 header 作为整个库安装的一部分安装。我的问题是,如果我的库定义了 B_ENABLED,它将具有包含这两个变量的结构。 但是 如果我的应用程序也没有定义它。然后它会将 header 解释为定义一个只有一个成员的结构。

处理这个问题的最好方法是生成某种“选项” header ,其中包含库构建中指定的所有#defines 吗?

我的库使用 CMAKE 构建。因此,针对此问题的 CMAKE 解决方案是 extra credit =D。

最佳答案

解决方案 #1(配置 + 安装)

在头文件中包含 config.hpp 文件(即 foo.hpp):

#ifndef FOO_HPP_
#define FOO_HPP_

#include "config.hpp" // FOO_DEBUG

class Foo {
public:
int result() const;

private:
int a_;
#ifdef FOO_DEBUG
int b_;
#endif // FOO_DEBUG
};

#endif // FOO_HPP_

config.hppconfigure_file 的输出命令:

configure_file(config.hpp.in "${PROJECT_BINARY_DIR}/config/config.hpp")
include_directories("${PROJECT_BINARY_DIR}/config")
install(FILES Foo.hpp "${PROJECT_BINARY_DIR}/config/config.hpp" DESTINATION include)

输入文件 config.hpp.in 使用特殊的 cmakedefine 指令:

#ifndef CONFIG_HPP_
#define CONFIG_HPP_

#cmakedefine FOO_DEBUG

#endif // CONFIG_HPP_

请注意,当您在其他项目中使用已安装的库时:

  • 你还需要指定库的包含目录
  • 如果您的库有依赖项,您需要手动链接它们
  • 你不能有 2 个配置文件(调试/发布)

解决方案#2(导出/导入目标,推荐)

install(EXPORT ...)命令可以保存有关使用库的所有信息(又名使用要求:包括定义、链接库、配置等):

add_library(Foo Foo.cpp Foo.hpp)

# Target which used Foo will be compiled with this definitions
target_compile_definitions(Foo PUBLIC $<$<CONFIG:Release>:FOO_DEBUG=0>)
target_compile_definitions(Foo PUBLIC $<$<CONFIG:Debug>:FOO_DEBUG=1>)

# This directory will be used as include
target_include_directories(Foo INTERFACE "${CMAKE_INSTALL_PREFIX}/include")

# This library will be linked
target_link_libraries(Foo PUBLIC pthread)

# Regular install
install(FILES Foo.hpp DESTINATION include)

# Install with export set
install(TARGETS Foo DESTINATION lib EXPORT FooTargets)
install(EXPORT FooTargets DESTINATION lib/cmake/Foo)

安装这样的项目会产生文件(CMAKE_DEBUG_POSTFIX is d):

include/Foo.hpp
lib/libFoo.a
lib/libFood.a
lib/cmake/Foo/FooTargets-debug.cmake
lib/cmake/Foo/FooTargets-release.cmake
lib/cmake/Foo/FooTargets.cmake

包含 FooTargets.cmake 文件以将安装的库导入项目。例如使用 find_package 命令(需要配置,参见 configure_package_config_file ):

add_executable(prog main.cpp)
find_package(Foo REQUIRED) # import Foo
target_link_libraries(prog Foo)

注意:

  • include/Foo.hpp 的路径自动添加到编译器选项
  • 依赖库 pthread 自动添加到 prog 链接器选项
  • 定义 FOO_DEBUG=0 添加到 Release 构建类型
  • 定义 FOO_DEBUG=1 添加到调试构建类型

理由

So excuse me if this is simple

这不是(:

问题的根源是ODR (C++ 标准 2011,3.2 [basic.def.ord],第 3 页):

Every program shall contain exactly one definition of every non-inline function
or variable that is odr-used in that program; no diagnostic required. The
definition can appear explicitly in the program, it can be found in the
standard or a user-defined library

恕我直言,良好的通用解决方案仍然不存在。将 CMake 与导入的配置一起使用可以部分帮助一点点,但在某些情况下你仍然会遇到链接器错误(例如,如果您使用使用 gcc 编译的库,默认链接到 libstdcxx,并尝试使用 clang 编译器将其链接到项目,编译器链接到 libcxx)。其中一些问题(不是全部,仍然)可以使用 toolchain 解决。文件。参见 examples .

相关

关于c++ - 库标题和#define,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20833226/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com