Skip to content

Commit

Permalink
Fix build with MinGW
Browse files Browse the repository at this point in the history
* Work around differences in Windows.h for __pfnDliNotifyHook2
* Work around misleading presence of some MinGW headers
* Specify the required Windows version for Windows.h (_WIN32_WINNT)
* Assume BFD ld when building with MinGW (this is incorrect for LLVM
  MinGW, but we don't support that toolchain yet)
* Tell MinGW to use wmain instead of main
  • Loading branch information
strager committed Apr 6, 2022
1 parent f96454e commit 12bd5b3
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 25 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ quick_lint_js_configure_rtti()
quick_lint_js_work_around_implicit_link_directories()
quick_lint_js_enable_dead_code_stripping()

if (WIN32)
add_definitions(-D_WIN32_WINNT=0x0602)
endif ()

# HACK(strager): Work around issues with CI. We should consider using
# find_package(Python3) instead.
find_package(PythonInterp 3.7)
Expand Down
7 changes: 7 additions & 0 deletions cmake/QuickLintJSCompiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,13 @@ function (quick_lint_js_enable_dead_code_stripping)
quick_lint_js_add_cxx_linker_flag_if_supported(-Wl,--gc-sections QUICK_LINT_JS_HAVE_GC_SECTIONS)
endfunction ()

function (quick_lint_js_enable_windows_unicode TARGET)
if (WIN32 AND MINGW)
target_compile_options("${TARGET}" PUBLIC -municode)
target_link_libraries("${TARGET}" PUBLIC -municode)
endif ()
endfunction ()

# quick-lint-js finds bugs in JavaScript programs.
# Copyright (C) 2020 Matthew "strager" Glazar
#
Expand Down
7 changes: 5 additions & 2 deletions cmake/QuickLintJSCopyright.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ function (quick_lint_js_collect_copyright NAME)
set(ERROR_MESSAGE_SEVERITY FATAL_ERROR)
endif ()

# TODO(strager): Detect the PE/COFF lld linker and set LICENSE_LINKMAP_TYPE to
# "coff-lld".
if (EMSCRIPTEN)
set(LICENSE_LINKMAP_TYPE emscripten)
elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
Expand All @@ -28,6 +26,11 @@ function (quick_lint_js_collect_copyright NAME)
set(LICENSE_LINKMAP_TYPE elf)
elseif (CMAKE_SYSTEM_NAME STREQUAL Windows AND MSVC)
set(LICENSE_LINKMAP_TYPE pe)
elseif (CMAKE_SYSTEM_NAME STREQUAL Windows AND MINGW)
# HACK(strager): Assume the linker is BFD ld.
# TODO(strager): Detect the PE/COFF lld linker and set LICENSE_LINKMAP_TYPE
# to "coff-lld". lld is used in LLVM MinGW.
set(LICENSE_LINKMAP_TYPE elf)
else ()
message("${ERROR_MESSAGE_SEVERITY}" "Unrecognized platform. Not generating copyright file.")
return ()
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ quick_lint_js_add_executable(
)
set_target_properties(quick-lint-js PROPERTIES RUNTIME_OUTPUT_DIRECTORY ..)
target_link_libraries(quick-lint-js PRIVATE quick-lint-js-lib)
quick_lint_js_enable_windows_unicode(quick-lint-js)

# TODO(strager): Use the default DESTINATION for CMake versions which have a
# default. (3.18.0 has a default; 3.12.4 doesn't have a default.)
Expand Down
6 changes: 3 additions & 3 deletions src/quick-lint-js/have.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

#if defined(QLJS_HAVE_FCNTL_H) && QLJS_HAVE_FCNTL_H
#elif defined(__has_include)
#if __has_include(<fcntl.h>)
#if __has_include(<fcntl.h>) && !defined(__MINGW32__)
#define QLJS_HAVE_FCNTL_H 1
#endif
#elif defined(__unix__)
Expand All @@ -35,7 +35,7 @@

#if defined(QLJS_HAVE_LIBGEN_H) && QLJS_HAVE_LIBGEN_H
#elif defined(__has_include)
#if __has_include(<libgen.h>)
#if __has_include(<libgen.h>) && !defined(__MINGW32__)
#define QLJS_HAVE_LIBGEN_H 1
#endif
#elif defined(__unix__)
Expand Down Expand Up @@ -83,7 +83,7 @@

#if defined(QLJS_HAVE_UNISTD_H) && QLJS_HAVE_UNISTD_H
#elif defined(__has_include)
#if __has_include(<unistd.h>) && !defined(__EMSCRIPTEN__)
#if __has_include(<unistd.h>) && !defined(__EMSCRIPTEN__) && !defined(__MINGW32__)
#define QLJS_HAVE_UNISTD_H 1
#endif
#elif defined(__unix__) && !defined(__EMSCRIPTEN__)
Expand Down
1 change: 1 addition & 0 deletions tools/collect-copyright
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ archive_to_project = {
"libsimdjson.a": VendorProject("simdjson"),
"simdjson.lib": VendorProject("simdjson"),
#
"libnode-hook.a": QLJSSubproject(),
"libquick-lint-js-lib.a": QLJSSubproject(),
"node-hook.lib": QLJSSubproject(),
"quick-lint-js-lib.lib": QLJSSubproject(),
Expand Down
11 changes: 10 additions & 1 deletion vendor/node-hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,16 @@ FARPROC WINAPI delay_load_notify_hook(unsigned dliNotify,
}
}

extern "C" const ::PfnDliHook __pfnDliNotifyHook2 = delay_load_notify_hook;
// HACK(strager): MinGW's headers need const. Window's headers need no const.
// Make both SDKs happy.
#if defined(__MINGW32__)
#define CONST_UNLESS_MINGW
#else
#define CONST_UNLESS_MINGW const
#endif

extern "C" CONST_UNLESS_MINGW ::PfnDliHook __pfnDliNotifyHook2;
CONST_UNLESS_MINGW ::PfnDliHook __pfnDliNotifyHook2 = delay_load_notify_hook;
#endif

// quick-lint-js finds bugs in JavaScript programs.
Expand Down
65 changes: 46 additions & 19 deletions vendor/node.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,51 @@ if (APPLE)
endif ()
if (WIN32)
# Create a .lib file for linking based on the symbol list in node.def.
set(DLLTOOL_MACHINE)
set(LIB_MACHINE)
# NOTE(strager): The order of these checks is important. If
# CMAKE_VS_PLATFORM_NAME is defined, it should take priority over
# CMAKE_SYSTEM_PROCESSOR.
if (CMAKE_VS_PLATFORM_NAME STREQUAL ARM)
set(DLLTOOL_MACHINE --machine arm)
set(LIB_MACHINE /MACHINE:ARM)
elseif (CMAKE_VS_PLATFORM_NAME STREQUAL ARM64)
set(DLLTOOL_MACHINE) # TODO(strager)
set(LIB_MACHINE /MACHINE:ARM64)
elseif (CMAKE_VS_PLATFORM_NAME STREQUAL Win32)
set(DLLTOOL_MACHINE --machine i386)
set(LIB_MACHINE /MACHINE:X86)
elseif (CMAKE_VS_PLATFORM_NAME STREQUAL x64)
set(DLLTOOL_MACHINE --machine i386:x86-64)
set(LIB_MACHINE /MACHINE:X64)
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL AMD64)
set(DLLTOOL_MACHINE --machine i386:x86-64)
set(LIB_MACHINE /MACHINE:X64)
endif ()
add_custom_command(
OUTPUT node-napi.lib node-napi.exp
COMMAND
lib
"/DEF:${CMAKE_CURRENT_LIST_DIR}/node.def"
/OUT:node-napi.lib
/WX
${LIB_MACHINE}
DEPENDS "${CMAKE_CURRENT_LIST_DIR}/node.def"
COMMENT "Generating node-napi implib"
)
if (MINGW)
add_custom_command(
OUTPUT node-napi.lib
COMMAND
dlltool
--input-def "${CMAKE_CURRENT_LIST_DIR}/node.def"
--output-delaylib node-napi.lib
${DLLTOOL_MACHINE}
DEPENDS "${CMAKE_CURRENT_LIST_DIR}/node.def"
COMMENT "Generating node-napi implib"
)
else ()
add_custom_command(
OUTPUT node-napi.lib node-napi.exp
COMMAND
lib
"/DEF:${CMAKE_CURRENT_LIST_DIR}/node.def"
/OUT:node-napi.lib
/WX
${LIB_MACHINE}
DEPENDS "${CMAKE_CURRENT_LIST_DIR}/node.def"
COMMENT "Generating node-napi implib"
)
endif ()
add_custom_target(
node-napi-implib
DEPENDS node-napi.lib
Expand All @@ -58,14 +77,22 @@ if (WIN32)
# Ensure symbols are found in the extension host (node.exe or code.exe or
# electron.exe or whatever), not in a separately-loaded DLL called "NODE.EXE".
add_library(node-hook STATIC "${CMAKE_CURRENT_LIST_DIR}/node-hook.cpp")
target_link_libraries(
node-napi
INTERFACE
-DELAY:nobind # Reduce binary size.
-DELAYLOAD:NODE.EXE
-WHOLEARCHIVE:$<TARGET_FILE:node-hook>
delayimp
)
if (MINGW)
target_link_libraries(
node-napi
INTERFACE
-Wl,--whole-archive node-hook -Wl,--no-whole-archive
)
else ()
target_link_libraries(
node-napi
INTERFACE
-DELAY:nobind # Reduce binary size.
-DELAYLOAD:NODE.EXE
-WHOLEARCHIVE:$<TARGET_FILE:node-hook>
delayimp
)
endif ()
add_dependencies(node-napi node-hook)
endif ()

Expand Down

0 comments on commit 12bd5b3

Please sign in to comment.