库头文件和#define [英] Library headers and #define

查看:157
本文介绍了库头文件和#define的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道该搜索什么。所以请原谅我,如果这是简单的。

I wasn't sure what to search for for this one. So excuse me if this is simple. But let me outline the scenario and see what answers are out there.

让我们假设我有一个库,它定义了一个这样的结构:

Let's say I have a library which defines a structure like this:

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

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

This header gets installed as a part of the library's installation as a whole. My question here is that if my library defines B_ENABLED it will have a structure with these two variables included. However if my application does not define this as well. Then it will interpret the header as defining a struct with only one member.

是处理这个只是为了生成某种选项头,这将包括所有在库构建中指定的#define?

Is the best way to handle this just to generate some kind of "options" header which would include all of the #defines that were specified in the library build?

我的库用CMAKE构建。所以这个CMAKE解决方案是额外信用 = D。

My library builds with CMAKE. So a CMAKE solution for this is extra credit =D.

推荐答案

安装)



在头文件中包含 config.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_

hpp configure_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 指令: / p>

input file config.hpp.in use special cmakedefine directive:

#ifndef CONFIG_HPP_
#define CONFIG_HPP_

#cmakedefine FOO_DEBUG

#endif // CONFIG_HPP_

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

Note that when you use installed library in other project:


  • 如果您的库需要手动链接,您还需要为库指定include目录


  • 您不能拥有2个配置文件(调试/发布)

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

install(EXPORT ...) command can hold all information about using library (aka usage requirements: including definitions, linked library, configuration etc):

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 d ):

Installing such project will produce files (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 ):

Include FooTargets.cmake file to import installed library to project. For example using find_package command (need config, see configure_package_config_file):

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

请注意:


  • 的路径include / Foo.hpp 自动添加到编译器选项

  • dependend library pthread 会自动添加到 prog 链接器选项

  • 定义 FOO_DEBUG = 0 添加到发布版本类型

  • 定义 FOO_DEBUG = 1 to Debug build type

  • path to include/Foo.hpp automatically added to compiler options
  • dependend library pthread is automatically added to prog linker option
  • definition FOO_DEBUG=0 added to Release build type
  • definition FOO_DEBUG=1 added to Debug build type
So excuse me if this is simple

不是(:

问题的根源是 ODR (C ++ Standard 2011,3.2 [basic.def。 ord],p.3):

The root of the problem is ODR (C++ Standard 2011, 3.2 [basic.def.ord], p.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

IMHO好的一般解决方案仍然不存在。使用CMake导入配置
可以部分地帮助一点,但在某些情况下,你仍然会得到链接器错误
(例如,如果你使用库编译的 gcc ,它链接到 libstdcxx 默认情况下,
并尝试链接到项目与 clang 编译器,它链接到 libcxx )。
其中一些问题(不是全部,仍然)可以使用工具链文件解决。
请参见示例

IMHO good general solution still not exists. Using CMake with imported configuration can partially helps a little bit, but in some cases you still will get linker errors (for example if you use library compiled with gcc, which linked to libstdcxx by default, and try to link it to project with clang compiler, which linked to libcxx). Some of this problems (not all, still) can be solved using toolchain files. See examples.

  • CMake tutorial
  • Exporting/importing targets
  • Modern CMake with Qt and Boost

这篇关于库头文件和#define的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆