我有一个既可以用作仅标头库也可以用作传统库的库。要启用此仅可选标头功能,.cpp
如果以仅标头模式编译,该库将包含源文件。例子:
// Vector.hpp
// (Module file), intended to be included manually by the user
#ifndef LIBRARY_MODULE_VECTOR
#define LIBRARY_MODULE_VECTOR
#include "Library/Vector/Inc/Vector2.hpp"
#include "Library/Vector/Inc/Vector3.hpp"
#include "Library/Vector/Inc/VectorUtils.hpp"
#if defined(LIBRARY_HEADERONLY)
#include "Library/Vector/Src/Vector2.cpp"
#include "Library/Vector/Src/Vector3.cpp"
#include "Library/Vector/Src/VectorUtils.cpp"
#endif
#endif
当用户Vector.hpp
在他/她的一个项目中包含时,如果LIBRARY_HEADERONLY
定义了,实现源文件将被包含在头文件之后。谨慎使用inline
关键字以避免多重定义。
如果LIBRARY_HEADERONLY
未定义,.cpp
则将编译文件并且必须链接库。
我选择的构建系统是CMake。
使用 CMake 标志,用户可以定义或取消定义LIBRARY_HEADERONLY
.
该CMakeLists.txt
文件类似于:
# (not shown) set flag and cache variables...
# Include library directory
include_directories("./${INCLUDE_DIRECTORY}")
# Glob all library header/source files
file(GLOB_RECURSE SRC_LIST "${INC_DIR}/*" "${SRC_DIR}/*")
# (Not shown) Check if header-only mode is enabled
# (from now on we assume header-only mode is enabled and that
# LIBRARY_HEADERONLY is defined)
# Use all source/header files as a library target
add_library(HEADER_ONLY_TARGET STATIC ${SRC_LIST})
set_target_properties(HEADER_ONLY_TARGET PROPERTIES LINKER_LANGUAGE CXX)
install(DIRECTORY ${INC_DIR} DESTINATION .)
不幸的是,CMake 生成的 makefile总是编译.cpp
文件,即使启用了仅标头模式并且目标是HEADER_ONLY_TARGET
.
如何防止 CMake 生成的 makefile 在仅标头模式下编译源文件?
请注意,依赖于 CMake 生成的输出的 IDE(例如 Qt Creator)应将头文件和源文件都显示为项目的一部分。
如果我没有 glob 任何源文件,而只有.hpp
头文件,CMake 将抱怨没有为库目标选择源文件,并且依赖于 CMake 文件的 IDE 将不会显示任何项目。