【问题标题】:How to Handle Resources in a C++ library如何处理 C++ 库中的资源
【发布时间】:2013-08-04 23:23:10
【问题描述】:

我正在为 OpenGL 构建一个非常轻量级的库/包装器,但遇到了一个小问题。假设我有一个看起来像这样的目录结构:

GraphicsProject
|GraphicsApp
||main.cpp
|GraphicsLib
||include
|||fileA.h
|||fileB.h
||library
|||fileA.cpp
|||fileB.cpp
||shaders
|||shader1.txt
|||shader2.txt
|| build
||| bunch of build stuff

在运行时获取 shader1.txt 路径的最佳方法是什么?或者,不管是谁在使用这个项目,或者它位于用户机器上的什么位置,路径都不会改变?

我考虑过的一些选项: 1)获取当前的工作目录并使用该路径来达到我需要的位置。我对这个解决方案的主要担心是,我不确定当前目录会根据用户构建项目的方式或我无法控制的其他因素而改变多少。也感觉不是很优雅。 2) 将着色器的源代码作为字符数组/字符串存储在包含目录中的 .h 文件中。这似乎是一个更好的解决方案,只是它会使编写着色器稍微麻烦一些。

有这样做的标准方法吗?我正在使用 CMake 来构建项目,如果这有任何改变的话。

【问题讨论】:

  • 将着色器文件复制到构建树作为构建后命令是否有效?
  • 它可能......但我需要你解释一下这意味着什么以及我将如何处理它。

标签: cmake organization include-path


【解决方案1】:

我假设您正在谈论让其他正在构建您的项目的开发人员可以使用“shaders”文件夹,因为如果您指的是最终用户(这将涉及installing 组件),您不会正在谈论构建文件夹。

我认为在运行时为着色器文件夹提供固定位置的最简单方法是将其从源代码树复制到构建树。这样,其他开发人员可以将他们的根构建文件夹放置在您项目之外的任何位置(如果他们愿意,甚至可以放置在内部),并且应用程序在访问复制的着色器文件夹时仍然有一个固定的相对路径来处理。

还有其他选项以防您不想复制(例如,您可以让 CMake 将配置文件写入构建树;配置文件可以指定着色器文件夹的路径)但我认为它们更复杂,可能更脆弱。无论如何,我认为关键是在配置时(当 CMake 执行时)将信息从源树复制到构建树,以便运行时代码不涉及对可能非常遥远的源树的困难搜索。

一个示例根 CMakeLists.txt 将是:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(example)

add_executable(GraphicsApp GraphicsApp/main.cpp)
add_library(GraphicsLib
    GraphicsLib/library/fileA.cpp
    GraphicsLib/library/fileB.cpp
    GraphicsLib/include/fileA.h
    GraphicsLib/include/fileB.h
    GraphicsLib/shaders/shader1.txt
    GraphicsLib/shaders/shader2.txt
    )
include_directories(GraphicsLib/include)
target_link_libraries(GraphicsApp GraphicsLib)

add_custom_command(TARGET GraphicsApp POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory
        ${CMAKE_SOURCE_DIR}/GraphicsLib/shaders
        $<TARGET_FILE_DIR:GraphicsApp>/shaders)

为了扩展add_custom_command 调用,这基本上会导致“shaders”子目录被复制到GraphicsApp 将被构建到的文件夹中。该命令在 GraphicsApp 构建时随时执行。如果 GraphicsApp 已构建并且是最新的,并且您尝试重新构建它,则自定义命令将不会执行。

自定义命令实际执行

cmake -E copy_directory <path to shaders source> <path to shaders copy>

利用CMake的-E跨平台命令模式。

命令的“目标”部分(“复制到”位置)使用生成器表达式推断GraphicsApp 将被构建到的位置:$&lt;TARGET_FILE_DIR:GraphicsApp&gt;。这可能是实现这一目标的最稳健的方式;无论配置类型如何,它都是正确的(例如,MSVC 在构建路径中插入“Debug/”或“Release/”文件夹)。

因此,希望这可以帮助您实现目标。我想您仍然需要get the full path to the running exe 才能推断出复制的着色器文件夹的完整路径。但是,这应该比从当前工作目录中搜索更简单、更健壮。即使calculating the current working dir 也很重要。

【讨论】:

  • 谢谢,自定义命令帮助了我。我想知道你为什么要添加 shader1.txt 和 shader2.txt 作为库?
  • 它们不必添加到包含 GraphicsLib 的文件列表中(实际上也没有 .h 文件),但由于它们已添加,因此它们显示为属于该文件某些 IDE(例如 Visual Studio 和 Xcode)中的库。
  • 如果我需要将库的定义放在单独的文件中(我会使用 add_subdirectory 添加库)怎么办?我应该将 add_custom_command 放在可执行文件或库的 CMake 文件中吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 2011-05-05
  • 2019-10-02
  • 1970-01-01
  • 2011-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多