diff --git a/.github/workflows/releaseDeploy.yml b/.github/workflows/releaseDeploy.yml index d823012b6..83ae754b4 100644 --- a/.github/workflows/releaseDeploy.yml +++ b/.github/workflows/releaseDeploy.yml @@ -48,7 +48,7 @@ jobs: if: matrix.os == 'ubuntu-latest' run: | sudo apt update --yes - sudo apt install --yes xorg-dev cmake libgtk-3-dev libdbus-1-dev + sudo apt install --yes xorg-dev cmake libgtk-3-dev libdbus-1-dev libhdf5-dev - name: Configure CMake run: cmake -B ${{github.workspace}}/build -DWERROR=YES -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} diff --git a/Intern/rayx-core/CMakeLists.txt b/Intern/rayx-core/CMakeLists.txt index 01a2dac59..652b63130 100644 --- a/Intern/rayx-core/CMakeLists.txt +++ b/Intern/rayx-core/CMakeLists.txt @@ -119,34 +119,45 @@ target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC # ---- Compile Shaders ---- if(Vulkan_FOUND) - # The following code is used to always compile the shader. - # This is most likely not an optimal solution, but it will work - # until we find a better one. add_dependencies(${PROJECT_NAME} RAYX_CORE_COMPILE_SHADER) - set(RAYX_CORE_SHADER ${CMAKE_BINARY_DIR}/bin/shaders/comp.spv) - set(RAYX_CORE_SHADER_FAKE ${CMAKE_BINARY_DIR}/bin/___comp.spv) # this exists so file cannot be found -> always execute command - + set(RAYX_CORE_SHADER ${CMAKE_BINARY_DIR}/bin/Shaders/comp.spv) + file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/Shaders) add_custom_command( OUTPUT ${RAYX_CORE_SHADER} - ${RAYX_CORE_SHADER_FAKE} COMMAND glslangValidator ARGS -V ${PROJECT_SOURCE_DIR}/src/Shader/main-glsl.comp -o ${RAYX_CORE_SHADER} ) - add_custom_target(RAYX_CORE_COMPILE_SHADER ALL DEPENDS ${RAYX_CORE_SHADER}) endif() # ------------------------ -# ---- CPack ---- +# ---- Data ---- +# Define the source and destination paths +set(DATA_SRC_DIR "${CMAKE_SOURCE_DIR}/Data") +# Set the destination directory for the Data directory based on the build type +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(DATA_DST_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/Data") +else() + set(DATA_DST_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/Data") +endif() -include(InstallRequiredSystemLibraries) +# Copy the Data directory to the binary output directory after building +message(STATUS "Copying Data directory from ${DATA_SRC_DIR} to ${DATA_DST_DIR}") +add_custom_command( + TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${DATA_SRC_DIR} ${DATA_DST_DIR} + COMMENT "Copying Data directory to build output directory..." +) +# ----------------- -set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../../LICENSE") +# ---- CPack ---- +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_CONTACT "Your Name <your.email@example.com>") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Your Project Description") +install(DIRECTORY ${DATA_SRC_DIR} DESTINATION ${CMAKE_INSTALL_PREFIX}) include(CPack) diff --git a/Intern/rayx-core/src/CanonicalizePath.cpp b/Intern/rayx-core/src/CanonicalizePath.cpp index bc3f0b8fd..0f0d860c9 100644 --- a/Intern/rayx-core/src/CanonicalizePath.cpp +++ b/Intern/rayx-core/src/CanonicalizePath.cpp @@ -1,9 +1,52 @@ #include "CanonicalizePath.h" #include "Debug/Debug.h" +#include <cstring> +#include <stdexcept> +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +#include <windows.h> +#elif defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION) +#include <unistd.h> +#include <limits.h> +#elif defined(__APPLE__) +#include <mach-o/dyld.h> +#endif namespace RAYX { +std::filesystem::path getExecutablePath() { + char buffer[1024]; + std::size_t length = sizeof(buffer); + memset(buffer, 0, length); + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + // Windows implementation + DWORD ret = GetModuleFileNameA(NULL, buffer, length); + if (ret == 0 || ret == length) { + // Handle error + throw std::runtime_error("Failed to get executable path."); + } +#elif defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION) + // Linux and Unix implementation + ssize_t ret = readlink("/proc/self/exe", buffer, length - 1); + if (ret == -1) { + // Handle error + throw std::runtime_error("Failed to get executable path."); + } + buffer[ret] = '\0'; // Ensure null-terminated string +#elif defined(__APPLE__) + // macOS implementation + if (_NSGetExecutablePath(buffer, &length) != 0) { + // Handle error + throw std::runtime_error("Buffer too small; should not happen."); + } +#else +#error "Platform not supported." +#endif + + return std::filesystem::path(buffer).parent_path(); +} + /// this function assumes that `base` is already an absolute path std::filesystem::path canonicalize(const std::filesystem::path& relPath, const std::filesystem::path& base) { if (!base.is_absolute()) { @@ -23,5 +66,4 @@ std::filesystem::path canonicalizeRepositoryPath(const std::filesystem::path& re std::filesystem::path canonicalizeUserPath(const std::filesystem::path& relPath) { return canonicalize(relPath, std::filesystem::current_path()); } - } // namespace RAYX diff --git a/Intern/rayx-core/src/CanonicalizePath.h b/Intern/rayx-core/src/CanonicalizePath.h index 1ca83048c..9a9dc083b 100644 --- a/Intern/rayx-core/src/CanonicalizePath.h +++ b/Intern/rayx-core/src/CanonicalizePath.h @@ -9,6 +9,9 @@ namespace RAYX { +/// Returns the path to the directory containing the executable. +std::filesystem::path RAYX_API getExecutablePath(); + /// `relPath` is a path relative to the root of the RAY-X git repository (i.e. /// where .git lies). canonicalizeRepositoryPath(relPath) yields an absolute /// path representing the same path. Examples: diff --git a/Intern/rayx-core/src/Material/NffTable.cpp b/Intern/rayx-core/src/Material/NffTable.cpp index f8d6e2f62..25261deab 100644 --- a/Intern/rayx-core/src/Material/NffTable.cpp +++ b/Intern/rayx-core/src/Material/NffTable.cpp @@ -14,8 +14,9 @@ bool NffTable::load(const char* element, NffTable* out) { std::transform(elementString.begin(), elementString.end(), elementString.begin(), [](unsigned char c) { return std::tolower(c); }); - std::string f = "Data/nff/" + elementString + ".nff"; - std::ifstream s(canonicalizeRepositoryPath(f)); + std::string f = getExecutablePath().string() + "/Data/nff/" + elementString + ".nff"; + RAYX_VERB << "Loading NffTable from " << f; + std::ifstream s(f); if (s.fail()) { return false; diff --git a/Intern/rayx-core/src/Material/PalikTable.cpp b/Intern/rayx-core/src/Material/PalikTable.cpp index 12881cfe2..ac4501028 100644 --- a/Intern/rayx-core/src/Material/PalikTable.cpp +++ b/Intern/rayx-core/src/Material/PalikTable.cpp @@ -12,8 +12,9 @@ bool PalikTable::load(const char* element, PalikTable* out) { std::string elementString = element; std::transform(elementString.begin(), elementString.end(), elementString.begin(), [](unsigned char c) { return std::toupper(c); }); - std::string f = "Data/PALIK/" + elementString + ".NKP"; - std::ifstream s(canonicalizeRepositoryPath(f)); + std::string f = getExecutablePath().string() + "/Data/PALIK/" + elementString + ".NKP"; + RAYX_VERB << "Loading PalikTable from " << f; + std::ifstream s(f); if (s.fail()) { return false; diff --git a/Intern/rayx-core/src/VulkanEngine/Init/ShaderModule.cpp b/Intern/rayx-core/src/VulkanEngine/Init/ShaderModule.cpp index e93d53641..230c925f0 100644 --- a/Intern/rayx-core/src/VulkanEngine/Init/ShaderModule.cpp +++ b/Intern/rayx-core/src/VulkanEngine/Init/ShaderModule.cpp @@ -18,7 +18,8 @@ void VulkanEngine::createShaderModule() { // the code in comp.spv was created by running the command: // glslangValidator.exe -V shader.comp - std::string path = canonicalizeRepositoryPath(m_shaderFile).string(); + std::string path = getExecutablePath().string() + "/Shaders/comp.spv"; + RAYX_VERB << "Loading compute shader from: " << path; std::vector<uint32_t> compShaderCode; if (auto d = readFileAlign32(path)) { compShaderCode = d.value(); diff --git a/Intern/rayx-ui/CMakeLists.txt b/Intern/rayx-ui/CMakeLists.txt index c5f4eba20..7ad636c3c 100644 --- a/Intern/rayx-ui/CMakeLists.txt +++ b/Intern/rayx-ui/CMakeLists.txt @@ -37,11 +37,11 @@ if(Vulkan_FOUND) # ---- CPack ---- install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) - install(DIRECTORY ${CMAKE_BINARY_DIR}/bin/shaders - DESTINATION ./ + install(DIRECTORY ${CMAKE_BINARY_DIR}/bin/Shaders + DESTINATION ./bin FILES_MATCHING PATTERN "*_*.spv") include(InstallRequiredSystemLibraries) - set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../../LICENSE") + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "rayx-ui - RAYX GUI Application") include(CPack) @@ -85,7 +85,7 @@ if(Vulkan_FOUND) string(SUBSTRING ${SHADER_EXT} 1 -1 SHADER_STAGE) # Remove the leading '.' from the extension # Set output file name - set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/bin/shaders/${SHADER_NAME}_${SHADER_STAGE}.spv") + set(OUTPUT_FILE "${CMAKE_BINARY_DIR}/bin/Shaders/${SHADER_NAME}_${SHADER_STAGE}.spv") # Create a custom command for each shader file add_custom_command( diff --git a/Intern/rayx-ui/src/RenderSystem/GridRenderSystem.cpp b/Intern/rayx-ui/src/RenderSystem/GridRenderSystem.cpp index 8ed9f0d8a..782ae7cf0 100644 --- a/Intern/rayx-ui/src/RenderSystem/GridRenderSystem.cpp +++ b/Intern/rayx-ui/src/RenderSystem/GridRenderSystem.cpp @@ -49,7 +49,7 @@ void GridRenderSystem::createPipeline(VkRenderPass renderPass) { pipelineConfig.depthStencilInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; // Use the grid-specific shaders - const std::string vertexShader = RAYX::canonicalizeRepositoryPath("build/bin/shaders/grid_shader_vert.spv").string(); - const std::string fragmentShader = RAYX::canonicalizeRepositoryPath("build/bin/shaders/grid_shader_frag.spv").string(); + const std::string vertexShader = RAYX::getExecutablePath().string() + "/Shaders/grid_shader_vert.spv"; + const std::string fragmentShader = RAYX::getExecutablePath().string() + "/Shaders/grid_shader_frag.spv"; m_Pipeline = std::make_unique<GraphicsPipeline>(m_Device, vertexShader, fragmentShader, pipelineConfig); } diff --git a/Intern/rayx-ui/src/RenderSystem/ObjectRenderSystem.cpp b/Intern/rayx-ui/src/RenderSystem/ObjectRenderSystem.cpp index 97e150e1c..f4311eb20 100644 --- a/Intern/rayx-ui/src/RenderSystem/ObjectRenderSystem.cpp +++ b/Intern/rayx-ui/src/RenderSystem/ObjectRenderSystem.cpp @@ -47,8 +47,8 @@ void ObjectRenderSystem::createPipeline(VkRenderPass renderPass) { GraphicsPipeline::defaultPipelineConfigInfo(pipelineConfig, GraphicsPipeline::VertexMode::TEXTURED); pipelineConfig.renderPass = renderPass; pipelineConfig.pipelineLayout = m_PipelineLayout; - const std::string vertexShader = RAYX::canonicalizeRepositoryPath("build/bin/shaders/shader_vert.spv").string(); - const std::string fragmentShader = RAYX::canonicalizeRepositoryPath("build/bin/shaders/shader_frag.spv").string(); + const std::string vertexShader = RAYX::getExecutablePath().string() + "/Shaders/shader_vert.spv"; + const std::string fragmentShader = RAYX::getExecutablePath().string() + "/Shaders/shader_frag.spv"; m_Pipeline = std::make_unique<GraphicsPipeline>(m_Device, vertexShader, fragmentShader, pipelineConfig); } diff --git a/Intern/rayx-ui/src/RenderSystem/RayRenderSystem.cpp b/Intern/rayx-ui/src/RenderSystem/RayRenderSystem.cpp index e1002204e..dfb7b3449 100644 --- a/Intern/rayx-ui/src/RenderSystem/RayRenderSystem.cpp +++ b/Intern/rayx-ui/src/RenderSystem/RayRenderSystem.cpp @@ -46,7 +46,7 @@ void RayRenderSystem::createPipeline(VkRenderPass renderPass) { pipelineConfig.renderPass = renderPass; pipelineConfig.pipelineLayout = m_PipelineLayout; - const std::string vertexShader = RAYX::canonicalizeRepositoryPath("build/bin/shaders/ray_shader_vert.spv").string(); - const std::string fragmentShader = RAYX::canonicalizeRepositoryPath("build/bin/shaders/ray_shader_frag.spv").string(); + const std::string vertexShader = RAYX::getExecutablePath().string() + "/Shaders/ray_shader_vert.spv"; + const std::string fragmentShader = RAYX::getExecutablePath().string() + "/Shaders/ray_shader_frag.spv"; m_Pipeline = std::make_unique<GraphicsPipeline>(m_Device, vertexShader, fragmentShader, pipelineConfig); } \ No newline at end of file diff --git a/Intern/rayx/CMakeLists.txt b/Intern/rayx/CMakeLists.txt index a531534c4..450783fe5 100644 --- a/Intern/rayx/CMakeLists.txt +++ b/Intern/rayx/CMakeLists.txt @@ -41,15 +41,15 @@ target_include_directories(${PROJECT_NAME} PRIVATE ${PROJECT_BINARY_DIR}) # ---------------------- # ---- CPack ---- -install(DIRECTORY ${CMAKE_BINARY_DIR}/bin/shaders - DESTINATION ./ +install(DIRECTORY ${CMAKE_BINARY_DIR}/bin/Shaders + DESTINATION ./bin FILES_MATCHING PATTERN "comp.spv") -install(DIRECTORY ${CMAKE_BINARY_DIR}/../Data - DESTINATION ./) +install(DIRECTORY ${CMAKE_SOURCE_DIR}/Data + DESTINATION ./bin) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "rayx - A RAYX Beamline Simulation Tool") set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_PACKAGE_INSTALL_DIRECTORY "rayx") -set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../../LICENSE") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE") set(CPACK_PACKAGE_EXECUTABLES ${PROJECT_NAME}) include(CPack) # -------------- \ No newline at end of file