我不知道该搜索什么。如果这很简单,请原谅。但让我概述一下场景,看看有什么答案。
假设我有一个库,它定义了这样的结构:
struct Example { int a; #if B_ENABLED int b; #endif };
这个头文件作为整个库安装的一部分安装。我的问题是,如果我的库定义了 B_ENABLED ,它将具有包含这两个变量的结构。 但是,如果我的应用程序也没有定义这个。然后它将标头解释为定义一个只有一个成员的结构。
处理这个问题的最佳方法是生成某种“选项”标头,其中包括库构建中指定的所有#defines?
我的库是用 CMAKE 构建的。因此,对此的 CMAKE 解决方案是额外的功劳=D。
在头文件中包含config.hpp文件(即foo.hpp):
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.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指令:
config.hpp.in
cmakedefine
#ifndef CONFIG_HPP_ #define CONFIG_HPP_ #cmakedefine FOO_DEBUG #endif // CONFIG_HPP_
请注意,当您在其他项目中使用已安装的库时:
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_POSTFIXis d):
CMAKE_DEBUG_POSTFIX
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):
FooTargets.cmake
find_package
add_executable(prog main.cpp) find_package(Foo REQUIRED) # import Foo target_link_libraries(prog Foo)
注意:
include/Foo.hpp
pthread
prog
FOO_DEBUG=0
FOO_DEBUG=1
So excuse me if this is simple
它不是 (:
问题的根源是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
恕我直言,良好的通用解决方案仍然不存在。将 CMake 与导入的配置一起使用可能会有所帮助,但在某些情况下,您仍然会遇到链接器错误(例如,如果您使用使用 编译的库gcc,默认链接到libstdcxx,并尝试使用clang编译器将其链接到项目,链接到libcxx)。其中一些问题(不是全部,仍然)可以使用工具链文件来解决。请参阅示例。
gcc
libstdcxx
clang
libcxx