ano*_*aut 6 c++ cmake shared-libraries
我不知道该搜索什么.如果这很简单,请原谅.但是,让我概述一下这个场景,看看那里有什么答案.
假设我有一个库,它定义了这样的结构:
struct Example {
int a;
#if B_ENABLED
int b;
#endif
};
Run Code Online (Sandbox Code Playgroud)
此标头作为整个库安装的一部分安装.我的问题是,如果我的库定义了B_ENABLED,它将包含一个包含这两个变量的结构. 但是,如果我的应用程序也没有定义它.然后它会将标题解释为定义只有一个成员的结构.
处理这个问题的最佳方法是生成某种"选项"标题,其中包括库构建中指定的所有#defines吗?
我的库使用CMAKE构建.因此,针对此的CMAKE解决方案是额外的信用 = D.
小智 15
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_
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
输入文件config.hpp.in
使用特殊cmakedefine
指令:
#ifndef CONFIG_HPP_
#define CONFIG_HPP_
#cmakedefine FOO_DEBUG
#endif // CONFIG_HPP_
Run Code Online (Sandbox Code Playgroud)
请注意,在其他项目中使用已安装的库时:
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)
Run Code Online (Sandbox Code Playgroud)
安装这样的项目会产生文件(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
Run Code Online (Sandbox Code Playgroud)
包含FooTargets.cmake
将已安装的库导入项目的文件.例如使用find_package
命令(需要配置,请参阅configure_package_config_file):
add_executable(prog main.cpp)
find_package(Foo REQUIRED) # import Foo
target_link_libraries(prog Foo)
Run Code Online (Sandbox Code Playgroud)
注意:
include/Foo.hpp
自动添加到编译器选项的路径pthread
自动添加到prog
链接器选项FOO_DEBUG=0
添加到发布版本类型FOO_DEBUG=1
添加到Debug构建类型So excuse me if this is simple
Run Code Online (Sandbox Code Playgroud)
它不是 (:
问题的根源是ODR(C++ Standard 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
Run Code Online (Sandbox Code Playgroud)
恕我直言的一般解决方案仍然不存在.使用导入配置的CMake可以部分地帮助一点,但在某些情况下,您仍然会遇到链接器错误(例如,如果您使用编译的库gcc
,libstdcxx
默认情况下链接到,并尝试将其链接到带有clang
编译器的项目,to libcxx
).使用工具链文件可以解决一些问题(并非所有问题).见例子.
归档时间: |
|
查看次数: |
4404 次 |
最近记录: |