C++ 错误包括;“私人”;带CMake的标题
在我的库中,我通过将公共标题放入C++ 错误包括;“私人”;带CMake的标题,c++,cmake,C++,Cmake,在我的库中,我通过将公共标题放入include和src中,将它们从源代码中分离出来。使用Cmake时,我的库中有以下内容: target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include/Thoth" "${CMAKE_CURRENT_SOURCE_DIR}/src" INTERFACE "${CMAKE_CURREN
include
和src
中,将它们从源代码中分离出来。使用Cmake时,我的库中有以下内容:
target_include_directories(${PROJECT_NAME}
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/include/Thoth"
"${CMAKE_CURRENT_SOURCE_DIR}/src"
INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include"
)
这背后的想法是,我希望最终用户(使用库)只拥有include
目录,这样他们就必须像这样包括:
#include <Thoth/file.h>
它很难看。当然,如果这是唯一的办法,那就这样吧。虽然我认为其他人会遇到这种情况,并希望找到解决方案 我可以想到的另一种方法是公开包含
src
文件夹,并信任用户不包含私有头,但这会污染包含路径,并且是不希望的
完整库CMake:
cmake_minimum_required(VERSION 3.13)
project(Thoth)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_library(${PROJECT_NAME}
src/IndentData.cpp
src/RenderComponent.cpp
src/RenderElement.cpp
src/RenderManager.cpp
)
target_include_directories(${PROJECT_NAME}
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/include/Thoth"
"${CMAKE_CURRENT_SOURCE_DIR}/src"
INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include"
)
完全可执行CMake:
cmake_minimum_required(VERSION 3.13)
project(myExe)
add_subdirectory(lib/Thoth)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC Thoth)
至于文件,显示起来有点困难,但问题是
RenderComponent.hpp
(在include/Thoth
中)包含IndentData.hpp
(在src
中)。因此,当exe包含#include
时,会发现库的src
目录不在包含路径中。库用户直接或通过传递包含的所有头都应在/include中
如果LibInterface.h
包含LibInternal.h
且用户包含LibInterface.h
,则LibInternal.h
也应包含在/include中,因为用户传递包含LibInternal.h
如果您可以避免将LibInternal.h
包含在LibInterface.h
中,请这样做。有时不能,因为LibInterface.h
可能依赖于LibInternal.h
中定义的内容
如果希望阻止用户直接包含LibInternal.h
,可以将其放在/include/detail或类似的内容中
在某些情况下,您可以使用来打破接口和实现之间的依赖关系,但这也有其缺点,因此这是一种折衷。库用户直接或通过传递包含的所有头都应该在/include中 如果
LibInterface.h
包含LibInternal.h
且用户包含LibInterface.h
,则LibInternal.h
也应包含在/include中,因为用户传递包含LibInternal.h
如果您可以避免将LibInternal.h
包含在LibInterface.h
中,请这样做。有时不能,因为LibInterface.h
可能依赖于LibInternal.h
中定义的内容
如果希望阻止用户直接包含LibInternal.h
,可以将其放在/include/detail或类似的内容中
在某些情况下,您可以使用来打破接口和实现之间的依赖关系,但这也有其缺点,因此这是一个折衷办法。@sparik给出了一个很好的答案。这里有更详细的说明 如果您的一个公共头依赖于一个私有头,那么该私有头将需要移动到公共位置,这是因为当您部署库(二进制+头)时,用户不应该依赖于访问您的源树 我可以想到的另一种方法是公开包含src文件夹,并信任用户不包含私有头,但这会污染包含路径,是不希望的 这是选项1。这是最简单也是最常见的。如果您查看一个大型库的public include目录,例如,您将看到私有的东西(即未记录,可能会受到api损坏)位于
或
选项2是减少公共头包含私有头的需要。这可以通过转发声明所有内容来实现。存储对这些私有类的引用而不是由这些私有类组成是一种帮助您做到这一点的方法。@sparik给出了一个很好的答案。这里有更详细的说明 如果您的一个公共头依赖于一个私有头,那么该私有头将需要移动到公共位置,这是因为当您部署库(二进制+头)时,用户不应该依赖于访问您的源树 我可以想到的另一种方法是公开包含src文件夹,并信任用户不包含私有头,但这会污染包含路径,是不希望的 这是选项1。这是最简单也是最常见的。如果您查看一个大型库的public include目录,例如,您将看到私有的东西(即未记录,可能会受到api损坏)位于
或
选项2是减少公共头包含私有头的需要。这可以通过转发声明所有内容来实现。存储对这些私有类的引用,而不是由这些私有类组成,是帮助您做到这一点的一种方法。请提供一个示例,如果不使其过大,很难显示大部分文件。希望我添加的内容能有所帮助。那么您有一个包含私有头的公共头?您将不得不更改
RenderComponent.hpp
以不包含IndentData.hpp
。请提供一个示例,如果不使其过大,很难显示大部分文件。希望我添加的内容能有所帮助。那么您有一个包含私有头的公共头?您必须将RenderComponent.hpp
更改为不包含IndentData.hpp
。这让我有点难过。不管怎样,我可能会去为我的内部资料创建一个详细信息。你会说一个纯粹用于内部的文件应该放在一个详细信息子文件夹中,还是干脆不放在里面呢
cmake_minimum_required(VERSION 3.13)
project(myExe)
add_subdirectory(lib/Thoth)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PUBLIC Thoth)