From 4107b0c3fe980fabc5adf73c4ea893c120e5311e Mon Sep 17 00:00:00 2001 From: Takase <20792268+takase1121@users.noreply.github.com> Date: Wed, 16 Nov 2022 11:23:45 +0800 Subject: [PATCH] MSVC Support (#1199) * fix stdalign and min/max for MSVC * add missing ISREG and ISDIR for MSVC * use MAX_PATH instead of PATH_MAX * remove unecessary headers inclusion * add MSVC CI * add appropriate macros to platform detection * re-add msvc CI artifacts * upload the generated artifacts * patch lua for MSVC CI builds * update patch for MSVC compatibility --- .github/workflows/build.yml | 37 +++++++++++++++++ resources/windows/001-lua-unicode.diff | 56 +++++++++++++------------- src/api/dirmonitor.c | 2 - src/api/dirmonitor/win32.c | 4 +- src/api/system.c | 14 +++++++ src/main.c | 9 +++-- src/rencache.c | 34 ++++++++++------ 7 files changed, 108 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a9596150..8fb880ff 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -131,3 +131,40 @@ jobs: with: name: Windows Artifacts path: ${{ env.INSTALL_NAME }}.zip + + build_windows_msvc: + name: Windows (MSVC) + runs-on: windows-2019 + strategy: + matrix: + arch: [amd64, amd64_x86] + steps: + - uses: actions/checkout@v2 + - uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.arch }} + - uses: actions/setup-python@v1 + with: + python-version: '3.x' + - name: Install meson and ninja + run: pip install meson ninja + - name: Set up environment variables + run: | + "INSTALL_NAME=lite-xl-$($env:GITHUB_REF -replace ".*/")-windows-msvc-${{ matrix.arch }}" >> $env:GITHUB_ENV + "INSTALL_REF=$($env:GITHUB_REF -replace ".*/")" >> $env:GITHUB_ENV + "LUA_SUBPROJECT_PATH=subprojects/lua-5.4.4" >> $env:GITHUB_ENV + - name: Configure + run: | + meson setup --wrap-mode=forcefallback build + Get-Content -Path resources/windows/001-lua-unicode.diff -Raw | patch -d $env:LUA_SUBPROJECT_PATH -p1 --forward + - name: Build + run: meson install -C build --destdir="../lite-xl" + - name: Package + run: | + Remove-Item -Recurse -Force -Path "lite-xl/lib","lite-xl/include" + Compress-Archive -Path lite-xl -DestinationPath "$env:INSTALL_NAME.zip" + - name: Upload Artifacts + uses: actions/upload-artifact@v2 + with: + name: Windows Artifacts (MSVC) + path: ${{ env.INSTALL_NAME }}.zip diff --git a/resources/windows/001-lua-unicode.diff b/resources/windows/001-lua-unicode.diff index 8306d354..7785b8ea 100644 --- a/resources/windows/001-lua-unicode.diff +++ b/resources/windows/001-lua-unicode.diff @@ -1,22 +1,21 @@ -diff -ruN lua-5.4.3/meson.build newlua/meson.build ---- lua-5.4.3/meson.build 2022-05-29 21:04:17.850449500 +0800 -+++ newlua/meson.build 2022-06-10 19:23:55.685139800 +0800 -@@ -82,6 +82,7 @@ +diff -ruN lua-5.4.4/meson.build lua-5.4.4-mod/meson.build +--- lua-5.4.4/meson.build 2022-11-16 10:33:38.424383300 +0800 ++++ lua-5.4.4-mod/meson.build 2022-11-16 09:40:57.697918000 +0800 +@@ -85,6 +85,7 @@ 'src/lutf8lib.c', 'src/lvm.c', 'src/lzio.c', + 'src/utf8_wrappers.c', dependencies: lua_lib_deps, - override_options: project_options, - implicit_include_directories: false, -Binary files lua-5.4.3/src/lua54.dll and newlua/src/lua54.dll differ -diff -ruN lua-5.4.3/src/luaconf.h newlua/src/luaconf.h ---- lua-5.4.3/src/luaconf.h 2021-03-15 21:32:52.000000000 +0800 -+++ newlua/src/luaconf.h 2022-06-10 19:15:03.014745300 +0800 -@@ -786,5 +786,15 @@ - - - + version: meson.project_version(), + soversion: lua_versions[0] + '.' + lua_versions[1], +diff -ruN lua-5.4.4/src/luaconf.h lua-5.4.4-mod/src/luaconf.h +--- lua-5.4.4/src/luaconf.h 2022-01-13 19:24:43.000000000 +0800 ++++ lua-5.4.4-mod/src/luaconf.h 2022-11-16 09:40:57.703926000 +0800 +@@ -782,5 +782,15 @@ + + + +#if defined(lua_c) || defined(luac_c) || (defined(LUA_LIB) && \ + (defined(lauxlib_c) || defined(liolib_c) || \ + defined(loadlib_c) || defined(loslib_c))) @@ -28,23 +27,22 @@ diff -ruN lua-5.4.3/src/luaconf.h newlua/src/luaconf.h + + #endif - -diff -ruN lua-5.4.3/src/Makefile newlua/src/Makefile ---- lua-5.4.3/src/Makefile 2021-02-10 02:47:17.000000000 +0800 -+++ newlua/src/Makefile 2022-06-10 19:22:45.267931400 +0800 + +diff -ruN lua-5.4.4/src/Makefile lua-5.4.4-mod/src/Makefile +--- lua-5.4.4/src/Makefile 2021-07-15 22:01:52.000000000 +0800 ++++ lua-5.4.4-mod/src/Makefile 2022-11-16 09:40:57.708921800 +0800 @@ -33,7 +33,7 @@ PLATS= guess aix bsd c89 freebsd generic linux linux-readline macosx mingw posix solaris - + LUA_A= liblua.a -CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o +CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o utf8_wrappers.o LIB_O= lauxlib.o lbaselib.o lcorolib.o ldblib.o liolib.o lmathlib.o loadlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o linit.o BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) - - -diff -ruN lua-5.4.3/src/utf8_wrappers.c newlua/src/utf8_wrappers.c ---- lua-5.4.3/src/utf8_wrappers.c 1970-01-01 07:30:00.000000000 +0730 -+++ newlua/src/utf8_wrappers.c 2022-06-10 19:13:11.904613300 +0800 + +diff -ruN lua-5.4.4/src/utf8_wrappers.c lua-5.4.4-mod/src/utf8_wrappers.c +--- lua-5.4.4/src/utf8_wrappers.c 1970-01-01 07:30:00.000000000 +0730 ++++ lua-5.4.4-mod/src/utf8_wrappers.c 2022-11-16 10:09:04.583866600 +0800 @@ -0,0 +1,101 @@ +/** + * Wrappers to provide Unicode (UTF-8) support on Windows. @@ -147,10 +145,10 @@ diff -ruN lua-5.4.3/src/utf8_wrappers.c newlua/src/utf8_wrappers.c + return LoadLibraryExW(pathname_w, hFile, dwFlags); +} +#endif -diff -ruN lua-5.4.3/src/utf8_wrappers.h newlua/src/utf8_wrappers.h ---- lua-5.4.3/src/utf8_wrappers.h 1970-01-01 07:30:00.000000000 +0730 -+++ newlua/src/utf8_wrappers.h 2022-06-10 19:22:53.554879400 +0800 -@@ -0,0 +1,42 @@ +diff -ruN lua-5.4.4/src/utf8_wrappers.h lua-5.4.4-mod/src/utf8_wrappers.h +--- lua-5.4.4/src/utf8_wrappers.h 1970-01-01 07:30:00.000000000 +0730 ++++ lua-5.4.4-mod/src/utf8_wrappers.h 2022-11-16 10:29:46.044102000 +0800 +@@ -0,0 +1,44 @@ +/** + * Wrappers to provide Unicode (UTF-8) support on Windows. + * @@ -167,6 +165,7 @@ diff -ruN lua-5.4.3/src/utf8_wrappers.h newlua/src/utf8_wrappers.h +#endif + +#ifdef lauxlib_c ++#include +FILE *freopen_utf8(const char *pathname, const char *mode, FILE *stream); +#define freopen freopen_utf8 +#endif @@ -177,6 +176,7 @@ diff -ruN lua-5.4.3/src/utf8_wrappers.h newlua/src/utf8_wrappers.h +#endif + +#ifdef loslib_c ++#include +int remove_utf8(const char *pathname); +int rename_utf8(const char *oldpath, const char *newpath); +int system_utf8(const char *command); diff --git a/src/api/dirmonitor.c b/src/api/dirmonitor.c index fd92f4e9..1bccfd13 100644 --- a/src/api/dirmonitor.c +++ b/src/api/dirmonitor.c @@ -1,8 +1,6 @@ #include "api.h" #include #include -#include -#include #include #include diff --git a/src/api/dirmonitor/win32.c b/src/api/dirmonitor/win32.c index 1941ebaf..318fda30 100644 --- a/src/api/dirmonitor/win32.c +++ b/src/api/dirmonitor/win32.c @@ -40,8 +40,8 @@ void deinit_dirmonitor(struct dirmonitor_internal* monitor) { int translate_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int buffer_size, int (*change_callback)(int, const char*, void*), void* data) { for (FILE_NOTIFY_INFORMATION* info = (FILE_NOTIFY_INFORMATION*)buffer; (char*)info < buffer + buffer_size; info = (FILE_NOTIFY_INFORMATION*)(((char*)info) + info->NextEntryOffset)) { - char transform_buffer[PATH_MAX*4]; - int count = WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)info->FileName, info->FileNameLength, transform_buffer, PATH_MAX*4 - 1, NULL, NULL); + char transform_buffer[MAX_PATH*4]; + int count = WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)info->FileName, info->FileNameLength, transform_buffer, MAX_PATH*4 - 1, NULL, NULL); change_callback(count, transform_buffer, data); if (!info->NextEntryOffset) break; diff --git a/src/api/system.c b/src/api/system.c index 5b8a76f7..9362dcdf 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -12,6 +12,20 @@ #include #include #include "../utfconv.h" + + // Windows does not define the S_ISREG and S_ISDIR macros in stat.h, so we do. + // We have to define _CRT_INTERNAL_NONSTDC_NAMES 1 before #including sys/stat.h + // in order for Microsoft's stat.h to define names like S_IFMT, S_IFREG, and S_IFDIR, + // rather than just defining _S_IFMT, _S_IFREG, and _S_IFDIR as it normally does. + #define _CRT_INTERNAL_NONSTDC_NAMES 1 + #include + #include + #if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) + #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) + #endif + #if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) + #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) + #endif #else #include diff --git a/src/main.c b/src/main.c index 2350ed6b..03edef6b 100644 --- a/src/main.c +++ b/src/main.c @@ -90,13 +90,14 @@ void set_macos_bundle_resources(lua_State *L); #endif #ifndef LITE_ARCH_TUPLE - #if __x86_64__ || _WIN64 || __MINGW64__ + // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-140 + #if defined(__x86_64__) || defined(_M_AMD64) || defined(__MINGW64__) #define ARCH_PROCESSOR "x86_64" - #elif __i386__ + #elif defined(__i386__) || defined(_M_IX86) || defined(__MINGW32__) #define ARCH_PROCESSOR "x86" - #elif __aarch64__ + #elif defined(__aarch64__) || defined(_M_ARM64) || defined (_M_ARM64EC) #define ARCH_PROCESSOR "aarch64" - #elif __arm__ + #elif defined(__arm__) || defined(_M_ARM) #define ARCH_PROCESSOR "arm" #endif diff --git a/src/rencache.c b/src/rencache.c index c847ce34..aa882617 100644 --- a/src/rencache.c +++ b/src/rencache.c @@ -2,9 +2,19 @@ #include #include #include -#include #include +#ifdef _MSC_VER + #ifndef alignof + #define alignof _Alignof + #endif + /* max_align_t is a compiler defined type, but + ** MSVC doesn't provide it, so we'll have to improvise */ + typedef long double max_align_t; +#else + #include +#endif + #include #include "rencache.h" @@ -42,8 +52,8 @@ static int command_buf_idx; static RenRect screen_rect; static bool show_debug; -static inline int min(int a, int b) { return a < b ? a : b; } -static inline int max(int a, int b) { return a > b ? a : b; } +static inline int rencache_min(int a, int b) { return a < b ? a : b; } +static inline int rencache_max(int a, int b) { return a > b ? a : b; } /* 32bit fnv-1a hash */ @@ -69,19 +79,19 @@ static inline bool rects_overlap(RenRect a, RenRect b) { static RenRect intersect_rects(RenRect a, RenRect b) { - int x1 = max(a.x, b.x); - int y1 = max(a.y, b.y); - int x2 = min(a.x + a.width, b.x + b.width); - int y2 = min(a.y + a.height, b.y + b.height); - return (RenRect) { x1, y1, max(0, x2 - x1), max(0, y2 - y1) }; + int x1 = rencache_max(a.x, b.x); + int y1 = rencache_max(a.y, b.y); + int x2 = rencache_min(a.x + a.width, b.x + b.width); + int y2 = rencache_min(a.y + a.height, b.y + b.height); + return (RenRect) { x1, y1, rencache_max(0, x2 - x1), rencache_max(0, y2 - y1) }; } static RenRect merge_rects(RenRect a, RenRect b) { - int x1 = min(a.x, b.x); - int y1 = min(a.y, b.y); - int x2 = max(a.x + a.width, b.x + b.width); - int y2 = max(a.y + a.height, b.y + b.height); + int x1 = rencache_min(a.x, b.x); + int y1 = rencache_min(a.y, b.y); + int x2 = rencache_max(a.x + a.width, b.x + b.width); + int y2 = rencache_max(a.y + a.height, b.y + b.height); return (RenRect) { x1, y1, x2 - x1, y2 - y1 }; }