2013-08-03 2 views
3

Я создаю очень легкую библиотеку/оболочку для OpenGL, и у меня возникла небольшая проблема. Скажем, у меня есть структура каталогов, которая выглядит вроде этого:Как обрабатывать ресурсы в библиотеке C++

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) Сохраните исходный код для шейдеров в виде массивов/строк char в файле .h, который находится в каталоге include. Это похоже на лучшее решение, за исключением того, что это сделает запись шейдеров немного более громоздкой.

Есть ли стандартный способ сделать это? Я использую CMake для создания проекта, если это что-то меняет.

+0

Скопировал бы файлы шейдера в дерево сборки в качестве работы после сборки? – Fraser

+1

Это могло бы ... но я бы хотел, чтобы вы объяснили, что это значит и как я буду с ним. – williamg

ответ

5

Я предполагаю, что вы говорите о том, чтобы сделать папку «шейдеров» доступной для других разработчиков, которые строят ваш проект, поскольку, если вы имели в виду конечных пользователей (которые включали бы install компонентов), вы не были бы говоря о сборке папок.

Я думаю, что самый простой способ обеспечить фиксированное местоположение в шейдерной папке во время выполнения - это скопировать его из исходного дерева в дерево сборки. Таким образом, другие разработчики могут размещать свою корневую папку в любом месте вне вашего проекта (или даже внутри, если захотят), и приложение будет по-прежнему иметь один фиксированный относительный путь для доступа к папке скопированных шейдеров.

Есть другие варианты, если вы не хотите копировать (например, вы могли бы написать CMake файл конфигурации в дереве сборки, в файле конфигурации можно указать путь к папке шейдеров), но я думаю, что они 'более сложный и, вероятно, более хрупкий. Несмотря на это, я считаю, что основной задачей является копирование информации из исходного дерева в дерево сборки в момент configure (когда выполняется 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 вызова, это в основном вызывает подкаталог «шейдеры», которые будут скопированы в папку, где GraphicsApp будет построен. Команда выполняется в любое время, когда построено GraphicsApp. Если GraphicsApp построен и обновлен, и вы пытаетесь его перестроить, пользовательская команда не будет выполнена.

Обычай команда фактически выполняет

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

делает использование режима командной -E кросс-платформенной CMake в.

Пункт назначения «назначения» (расположение «копировать в») использует выражение генератора для вывода местоположения, в котором GraphicsApp будет построено по адресу: $<TARGET_FILE_DIR:GraphicsApp>. Это, вероятно, самый надежный способ достижения этой цели; он будет правильным независимо от типа конфигурации (где, например, MSVC добавляет папку «Отладка /» или «Отпустить /» в путь сборки).

Так что это, надеюсь, доставит вам большую часть пути к вашей цели. Я предполагаю, что вам все равно придется get the full path to the running exe, чтобы затем вывести полный путь к папке скопированных шейдеров. Однако это должно быть намного проще и надежнее, чем поиск из текущего рабочего каталога. Даже calculating the current working dir нетривиально.

+1

Спасибо, пользовательская команда мне помогла. Интересно, почему вы добавляете файлы shader1.txt и shader2.txt в качестве библиотек? – Siamaster

+2

Их не нужно добавлять в список файлов, содержащих «GraphicsLib» (ни на самом деле файлы .h), но так как они добавлены, они отображаются как принадлежащие этой библиотеке в определенных IDE (например, Visual Studio и Xcode). – Fraser

+0

Что делать, если мне нужно иметь определение библиотеки в отдельном файле (я бы добавил библиотеку с add_subdirectory)? Должен ли я помещать add_custom_command в файл CMake исполняемого файла или библиотеки? – user1754322

Смежные вопросы