From 66afe52032c85763ac3cc0ab03166879a2adb3ea Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Sat, 6 Jan 2024 11:41:41 -0300 Subject: buil Use NSIS to create Windows installer --- .gitignore | 1 + Rakefile | 53 ++++++++--------------- rake/linux.rake | 29 +++++++++++++ rake/windows.rake | 26 ++++++++++++ src/core.hpp | 8 ++-- src/vk/device.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++++---- windows_installer.nsi | 86 +++++++++++++++++++++++++++++++++++++ 7 files changed, 269 insertions(+), 48 deletions(-) create mode 100644 rake/linux.rake create mode 100644 rake/windows.rake create mode 100644 windows_installer.nsi diff --git a/.gitignore b/.gitignore index f1230bd..cc01af7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ pkg mruby-* mruby-*.zip +*.exe *.mrb *.o *.spv diff --git a/Rakefile b/Rakefile index 377a77b..eeab51a 100644 --- a/Rakefile +++ b/Rakefile @@ -15,10 +15,12 @@ require 'rake/clean' require 'rake/loaders/makefile' -OS = if RUBY_PLATFORM == "x64-mingw32" - :windows +if RUBY_PLATFORM.include? 'cygwin' then + load './rake/windows.rake' + OS = :windows else - :linux + load './rake/linux.rake' + OS = :linux end OBJ = 'candy_gear' @@ -54,19 +56,7 @@ LIBRARIES = [ 'SDL2_mixer', 'freetype', 'm' -] -case OS -when :windows - LIBRARIES.concat([ - 'SDL2main', - 'mingw32', - 'vulkan-1.dll' - ]) -when :linux - LIBRARIES.concat([ - 'vulkan' - ]) -end +] + OS_LIBRARIES PKG_CONFIG = [ 'freetype2' @@ -133,6 +123,17 @@ rule '.spv' => ['.glsl'] do |t| system("glslangValidator -V #{t.source} -o #{t.name}") end +task :lib do + destdir = ENV['DESTDIR'] || '' + + `install -d #{destdir}#{DATA_DIR}/lib` + RB_LIBS.each do |path| + subdir = /(\/[[:alnum:]]+)\//.match(path)&.captures&.at(0) + `install -d #{destdir}#{DATA_DIR}/lib#{subdir}` unless subdir.nil? + `install #{path} #{destdir}#{DATA_DIR}/lib#{subdir}` + end +end + task build: CPP_OBJS + SPV_FILES + [MRUBY_STATIC_LIB] do libs = LIBRARIES.inject('') {_1 + "-l#{_2} "} @@ -146,24 +147,4 @@ task build: CPP_OBJS + SPV_FILES + [MRUBY_STATIC_LIB] do system("g++ -o #{OBJ} #{CPP_OBJS} #{MRUBY_STATIC_LIB} #{flags} #{libs}") end -task install: :build do - destdir = ENV['DESTDIR'] || '' - - # Install engine - `install -d #{destdir}/usr/local/bin` - `install #{OBJ} #{destdir}/usr/local/bin` - - # Install shaders - `install -d #{destdir}#{DATA_DIR}/glsl` - SPV_FILES.each {`install #{_1} #{destdir}#{DATA_DIR}/glsl`} - - # Install libs - `install -d #{destdir}#{DATA_DIR}/lib` - RB_LIBS.each do |path| - subdir = /(\/[[:alnum:]]+)\//.match(path)&.captures&.at(0) - `install -d #{destdir}#{DATA_DIR}/lib#{subdir}` unless subdir.nil? - `install #{path} #{destdir}#{DATA_DIR}/lib#{subdir}` - end -end - task default: %[build] diff --git a/rake/linux.rake b/rake/linux.rake new file mode 100644 index 0000000..2102efa --- /dev/null +++ b/rake/linux.rake @@ -0,0 +1,29 @@ +# Copyright 2022-2024 Frederico de Oliveira Linhares +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License + +OS_LIBRARIES = [ + 'vulkan' +] + +task install: [:build, :lib] do + destdir = ENV['DESTDIR'] || '' + + # Install engine + `install -d #{destdir}/usr/local/bin` + `install #{OBJ} #{destdir}/usr/local/bin` + + # Install shaders + `install -d #{destdir}#{DATA_DIR}/glsl` + SPV_FILES.each {`install #{_1} #{destdir}#{DATA_DIR}/glsl`} +end diff --git a/rake/windows.rake b/rake/windows.rake new file mode 100644 index 0000000..c32e9a3 --- /dev/null +++ b/rake/windows.rake @@ -0,0 +1,26 @@ +# Copyright 2022-2024 Frederico de Oliveira Linhares +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License + +OS_LIBRARIES = [ + 'SDL2main', + 'mingw32', + 'vulkan-1.dll' +] + +task install: :build do + environment = `echo $MSYSTEM`.downcase.chomp + ENV['DLL_PATH'] = `cygpath -w /#{environment}/bin`.chomp + ENV['CANDY_GEAR_VERSION'] = VERSION + `makensis.exe windows_installer.nsi` +end diff --git a/src/core.hpp b/src/core.hpp index 7393b33..f9e1e80 100644 --- a/src/core.hpp +++ b/src/core.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 Frederico de Oliveira Linhares + * Copyright 2022-2024 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,6 @@ #define CANDY_GEAR_VERSION_MINOR 1 #define CANDY_GEAR_VERSION_PATCH 0 -#define DATA_DIR "/usr/local/share/candy_gear" - #include #include @@ -35,6 +33,10 @@ #define SDL_MAIN_HANDLED +#ifdef _WIN64 +#include +#endif + #include #include #include diff --git a/src/vk/device.cpp b/src/vk/device.cpp index 83bdf38..d0690d7 100644 --- a/src/vk/device.cpp +++ b/src/vk/device.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 Frederico de Oliveira Linhares + * Copyright 2022-2024 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -158,22 +158,118 @@ Device::Device(VkPhysicalDevice vk_physical_device, bool with_swapchain) // Load Shaders { + std::string data_dir{""}; +#ifdef _WIN64 + HKEY hKey; + LPCSTR lpSubKey = "SOFTWARE\\CandyGear"; + LPCSTR lpValueName = "InstallLocation"; + DWORD dwType = REG_SZ; + DWORD dwSize = 0; + LPBYTE lpData = NULL; + + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey) == + ERROR_SUCCESS) + { + if(RegQueryValueEx(hKey, lpValueName, NULL, &dwType, NULL, &dwSize) == + ERROR_SUCCESS) + { + lpData = new BYTE[dwSize]; + if(RegQueryValueEx( + hKey, lpValueName, NULL, &dwType, lpData, &dwSize) == + ERROR_SUCCESS) + { + data_dir = reinterpret_cast(lpData); + } + delete[] lpData; + } + RegCloseKey(hKey); + } + + if(data_dir == "") + throw std::runtime_error("Failed to read CandyGear registry."); + + std::string vert_sprite_3d_shader_module{data_dir}; + vert_sprite_3d_shader_module.append("\\glsl\\shader_sprite_3d.vert.spv"); + this->vert_sprite_3d_shader_module = create_shader_module( + this->device, vert_sprite_3d_shader_module.c_str()); + + std::string frag_sprite_3d_shader_module{data_dir}; + frag_sprite_3d_shader_module.append("\\glsl\\shader_sprite_3d.frag.spv"); + this->frag_sprite_3d_shader_module = create_shader_module( + this->device, frag_sprite_3d_shader_module.c_str()); + + std::string vert3d_shader_module{data_dir}; + vert3d_shader_module.append("\\glsl\\shader_3d.vert.spv"); + this->vert3d_shader_module = create_shader_module( + this->device, vert3d_shader_module.c_str()); + + std::string frag3d_shader_module{data_dir}; + frag3d_shader_module.append("\\glsl\\shader_3d.frag.spv"); + this->frag3d_shader_module = create_shader_module( + this->device, frag3d_shader_module.c_str()); + + std::string vert2d_solid_shader_module{data_dir}; + vert2d_solid_shader_module.append("\\glsl\\shader_2d_solid.vert.spv"); + this->vert2d_solid_shader_module = create_shader_module( + this->device, vert2d_solid_shader_module.c_str()); + + std::string frag2d_solid_shader_module{data_dir}; + frag2d_solid_shader_module.append("\\glsl\\shader_2d_solid.frag.spv"); + this->frag2d_solid_shader_module = create_shader_module( + this->device, frag2d_solid_shader_module.c_str()); + + std::string vert2d_wired_shader_module{data_dir}; + vert2d_wired_shader_module.append("\\glsl\\shader_2d_wired.vert.spv"); + this->vert2d_wired_shader_module = create_shader_module( + this->device, vert2d_wired_shader_module.c_str()); + + std::string frag2d_wired_shader_module{data_dir}; + frag2d_wired_shader_module.append("\\glsl\\shader_2d_wired.frag.spv"); + this->frag2d_wired_shader_module = create_shader_module( + this->device, frag2d_wired_shader_module.c_str()); +#else + data_dir = "/usr/local/share/candy_gear"; + + std::string vert_sprite_3d_shader_module{data_dir}; + vert_sprite_3d_shader_module.append("/glsl/shader_sprite_3d.vert.spv"); this->vert_sprite_3d_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_sprite_3d.vert.spv"); + this->device, vert_sprite_3d_shader_module.c_str()); + + std::string frag_sprite_3d_shader_module{data_dir}; + frag_sprite_3d_shader_module.append("/glsl/shader_sprite_3d.frag.spv"); this->frag_sprite_3d_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_sprite_3d.frag.spv"); + this->device, frag_sprite_3d_shader_module.c_str()); + + std::string vert3d_shader_module{data_dir}; + vert3d_shader_module.append("/glsl/shader_3d.vert.spv"); this->vert3d_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_3d.vert.spv"); + this->device, vert3d_shader_module.c_str()); + + std::string frag3d_shader_module{data_dir}; + frag3d_shader_module.append("/glsl/shader_3d.frag.spv"); this->frag3d_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_3d.frag.spv"); + this->device, frag3d_shader_module.c_str()); + + std::string vert2d_solid_shader_module{data_dir}; + vert2d_solid_shader_module.append("/glsl/shader_2d_solid.vert.spv"); this->vert2d_solid_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_2d_solid.vert.spv"); + this->device, vert2d_solid_shader_module.c_str()); + + std::string frag2d_solid_shader_module{data_dir}; + frag2d_solid_shader_module.append("/glsl/shader_2d_solid.frag.spv"); this->frag2d_solid_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_2d_solid.frag.spv"); + this->device, frag2d_solid_shader_module.c_str()); + + std::string vert2d_wired_shader_module{data_dir}; + vert2d_wired_shader_module.append("/glsl/shader_2d_wired.vert.spv"); this->vert2d_wired_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_2d_wired.vert.spv"); + this->device, vert2d_wired_shader_module.c_str()); + + std::string frag2d_wired_shader_module{data_dir}; + frag2d_wired_shader_module.append("/glsl/shader_2d_wired.frag.spv"); this->frag2d_wired_shader_module = create_shader_module( - this->device, DATA_DIR "/glsl/shader_2d_wired.frag.spv"); + this->device, frag2d_wired_shader_module.c_str()); +#endif } this->queue_families = static_cast( diff --git a/windows_installer.nsi b/windows_installer.nsi new file mode 100644 index 0000000..31a39c5 --- /dev/null +++ b/windows_installer.nsi @@ -0,0 +1,86 @@ +; Copyright 2022-2024 Frederico de Oliveira Linhares +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. + +!define UNINSTNAME "uninstall" +!define REGAPPKEY "CandyGear" +!define REGHKEY HKLM +!define REGPATH "Software" +!define REGPATH_WINUNINST "Software\Microsoft\Windows\CurrentVersion\Uninstall" + +Name "Candy Gear $%CANDY_GEAR_VERSION%" +InstallDir "$PROGRAMFILES64\CandyGear" +OutFile "CandyGear-$%CANDY_GEAR_VERSION%.exe" + +Page directory +Page instfiles + +UninstPage instfiles + +Section + WriteUninstaller $INSTDIR\${UNINSTNAME}.exe + + SetOutPath "$INSTDIR" + File candy_gear.exe + File "$%DLL_PATH%\\libbrotlicommon.dll" + File "$%DLL_PATH%\\libbrotlidec.dll" + File "$%DLL_PATH%\\libbz2-1.dll" + File "$%DLL_PATH%\\libfreetype-6.dll" + File "$%DLL_PATH%\\libgcc_s_seh-1.dll" + File "$%DLL_PATH%\\libglib-2.0-0.dll" + File "$%DLL_PATH%\\libgraphite2.dll" + File "$%DLL_PATH%\\libharfbuzz-0.dll" + File "$%DLL_PATH%\\libiconv-2.dll" + File "$%DLL_PATH%\\libintl-8.dll" + File "$%DLL_PATH%\\libmpg123-0.dll" + File "$%DLL_PATH%\\libogg-0.dll" + File "$%DLL_PATH%\\libopus-0.dll" + File "$%DLL_PATH%\\libopusfile-0.dll" + File "$%DLL_PATH%\\libpcre2-8-0.dll" + File "$%DLL_PATH%\\libpng16-16.dll" + File "$%DLL_PATH%\\libstdc++-6.dll" + File "$%DLL_PATH%\\libwinpthread-1.dll" + File "$%DLL_PATH%\\SDL2.dll" + File "$%DLL_PATH%\\SDL2_mixer.dll" + File "$%DLL_PATH%\\zlib1.dll" + + SetOutPath "$INSTDIR\glsl" + File glsl\*.spv + + SetOutPath "$INSTDIR\lib" + File /r lib\*.rb + + WriteRegStr ${REGHKEY} "${REGPATH}\${REGAPPKEY}" "InstallLocation" \ + "$INSTDIR" + + WriteRegStr ${REGHKEY} "${REGPATH_WINUNINST}\${REGAPPKEY}" "DisplayName" \ + "CandyGear" + WriteRegStr ${REGHKEY} "${REGPATH_WINUNINST}\${REGAPPKEY}" \ + "UninstallString" '"$INSTDIR\${UNINSTNAME}.exe"' + WriteRegStr ${REGHKEY} "${REGPATH_WINUNINST}\${REGAPPKEY}" \ + "InstallLocation" "$INSTDIR" +SectionEnd + +Section "Uninstall" + RMDir /REBOOTOK /r $INSTDIR\lib + + Delete /REBOOTOK $INSTDIR\glsl\*.spv + RMDir /REBOOTOK $INSTDIR\glsl + + Delete /REBOOTOK $INSTDIR\*.dll + Delete /REBOOTOK $INSTDIR\candy_gear.exe + Delete $INSTDIR\uninstall.exe + + DeleteRegKey ${REGHKEY} "${REGPATH}\${REGAPPKEY}" + DeleteRegKey ${REGHKEY} "${REGPATH_WINUNINST}\${REGAPPKEY}" +SectionEnd -- cgit v1.2.3