Skip to content

Commit c84f2a9

Browse files
committed
更新构建文档和 GitHub Actions 工作流,添加 Node.js 和 npm 依赖,优化 Windows 环境设置,确保构建过程的兼容性和可用性。
1 parent eb43509 commit c84f2a9

File tree

3 files changed

+183
-70
lines changed

3 files changed

+183
-70
lines changed

.github/workflows/build.yml

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -139,31 +139,51 @@ jobs:
139139
mingw-w64-x86_64-fftw
140140
mingw-w64-x86_64-boost
141141
mingw-w64-x86_64-gcc-fortran
142+
mingw-w64-x86_64-nodejs
142143
143-
# 4. 设置 Windows 环境变量和路径
144-
- name: Setup Windows environment
144+
# 3a. 验证 MSYS2 工具链 - Windows
145+
- name: Verify MSYS2 toolchain (Windows)
145146
if: runner.os == 'Windows'
146147
shell: msys2 {0}
147148
run: |
148-
# 确保系统 Node.js 和 npm 在 PATH 中
149-
export PATH="/c/Program Files/nodejs:$PATH"
150-
echo "PATH=/c/Program Files/nodejs:$PATH" >> $GITHUB_ENV
149+
echo "=== Verifying MSYS2 toolchain installation ==="
150+
echo "Checking essential tools..."
151+
which gcc && gcc --version || echo "❌ GCC not found"
152+
which g++ && g++ --version || echo "❌ G++ not found"
153+
which gfortran && gfortran --version || echo "❌ gfortran not found"
154+
which cmake && cmake --version || echo "❌ CMake not found"
155+
which pkg-config && pkg-config --version || echo "❌ pkg-config not found"
156+
which node && node --version || echo "❌ Node.js not found"
157+
which npm && npm --version || echo "❌ npm not found"
158+
which npx && npx --version || echo "❌ npx not found"
151159
152-
# 验证 Node.js 和 npm 是否可用
153-
echo "Checking Node.js and npm availability..."
154-
which node && node --version
155-
which npm && npm --version
156-
which npx && npx --version
160+
echo "Checking libraries..."
161+
pkg-config --exists fftw3f && echo "✅ FFTW3f available" || echo "❌ FFTW3f not found"
162+
163+
# Boost 在 MSYS2 中可能没有 pkg-config 文件,检查实际安装
164+
if [ -d "/mingw64/include/boost" ]; then
165+
echo "✅ Boost headers found"
166+
else
167+
echo "❌ Boost headers not found"
168+
fi
169+
170+
if ls /mingw64/lib/libboost* >/dev/null 2>&1; then
171+
echo "✅ Boost libraries found"
172+
else
173+
echo "❌ Boost libraries not found"
174+
fi
175+
176+
echo "=== Toolchain verification complete ==="
157177
158-
# 5. 安装 npm 依赖
178+
# 4. 安装 npm 依赖
159179
- name: Install npm dependencies
160180
run: npm ci --ignore-scripts
161181

162-
# 6. 构建 TypeScript
182+
# 5. 构建 TypeScript
163183
- name: Build TypeScript
164184
run: npm run build:ts
165185

166-
# 7. 构建原生模块 - Linux/macOS
186+
# 6. 构建原生模块 - Linux/macOS
167187
- name: Build native module (Linux/macOS)
168188
if: runner.os != 'Windows'
169189
run: |
@@ -186,30 +206,54 @@ jobs:
186206
# 7. 构建原生模块 - Windows MSYS2/MinGW-w64
187207
- name: Build native module (Windows MSYS2)
188208
if: runner.os == 'Windows'
189-
shell: cmd
209+
shell: msys2 {0}
190210
run: |
191211
echo "=== Building with MSYS2/MinGW-w64 toolchain ==="
192-
echo "Using system Node.js with MSYS2 MinGW-w64 toolchain"
212+
echo "Using improved CMakeLists.txt with MinGW-specific MSVC flag clearing"
193213
194-
rem 清理构建目录
195-
if exist build rmdir /s /q build
214+
# 验证工具是否可用
215+
echo "Verifying tools availability..."
216+
which cmake && cmake --version || echo "CMake not found"
217+
which gcc && gcc --version || echo "GCC not found"
218+
which gfortran && gfortran --version || echo "gfortran not found"
219+
which pkg-config && pkg-config --version || echo "pkg-config not found"
220+
which node && node --version || echo "Node.js not found"
221+
which npm && npm --version || echo "npm not found"
222+
which npx && npx --version || echo "npx not found"
196223
197-
echo "Starting cmake-js compilation with MinGW Makefiles..."
224+
# 设置环境变量强制使用 MinGW 工具链
225+
export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig"
226+
export CMAKE_PREFIX_PATH="/mingw64"
227+
export CC="gcc"
228+
export CXX="g++"
229+
export FC="gfortran"
230+
231+
# 强制 cmake-js 使用 MinGW 而不是 Visual Studio
232+
export CMAKE_GENERATOR="MinGW Makefiles"
233+
export CMAKE_MAKE_PROGRAM="mingw32-make"
234+
235+
# 禁用 Visual Studio 检测
236+
unset VSINSTALLDIR
237+
unset VCINSTALLDIR
238+
unset WindowsSDKDir
239+
240+
# 验证 Boost 安装
241+
echo "Checking Boost installation..."
242+
find /mingw64 -name "*boost*" -type f | head -5
243+
ls -la /mingw64/include/boost/ || echo "Boost headers not found"
244+
ls -la /mingw64/lib/libboost* | head -3 || echo "Boost libraries not found"
198245
199-
rem 设置环境变量
200-
set "CC=C:/msys64/mingw64/bin/gcc.exe"
201-
set "CXX=C:/msys64/mingw64/bin/g++.exe"
202-
set "FC=C:/msys64/mingw64/bin/gfortran.exe"
246+
# 清理构建目录
247+
rm -rf build/
248+
249+
echo "Starting cmake-js compilation with MinGW Makefiles..."
250+
echo "CMakeLists.txt now handles MSVC flag clearing automatically"
203251
204-
rem 使用 MinGW Makefiles 生成器构建
205-
npx cmake-js compile --arch=${{ matrix.cmake_arch }} ^
206-
-- -G "MinGW Makefiles" ^
207-
-DCMAKE_C_COMPILER=C:/msys64/mingw64/bin/gcc.exe ^
208-
-DCMAKE_CXX_COMPILER=C:/msys64/mingw64/bin/g++.exe ^
209-
-DCMAKE_Fortran_COMPILER=C:/msys64/mingw64/bin/gfortran.exe ^
210-
-DCMAKE_MAKE_PROGRAM=C:/msys64/mingw64/bin/mingw32-make.exe ^
211-
-DPKG_CONFIG_EXECUTABLE=C:/msys64/mingw64/bin/pkg-config.exe ^
212-
--verbose
252+
# 使用 cmake-js,依赖 CMakeLists.txt 中的修复
253+
npx cmake-js compile --arch=${{ matrix.cmake_arch }} \
254+
--generator="MinGW Makefiles" \
255+
--verbose \
256+
-DCMAKE_SHARED_LINKER_FLAGS=\"\"
213257
214258
# 8. 运行测试
215259
- name: Run tests

BUILD.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,11 @@ pacman -S --needed \
4040
mingw-w64-x86_64-pkg-config \
4141
mingw-w64-x86_64-fftw \
4242
mingw-w64-x86_64-boost \
43-
mingw-w64-x86_64-gcc-fortran
43+
mingw-w64-x86_64-gcc-fortran \
44+
mingw-w64-x86_64-nodejs
4445
```
4546

46-
**注意**:在 GitHub Actions 中,我们使用系统安装的 Node.js 配合 MSYS2 的编译工具链。如果在本地开发,你可以选择:
47-
1. 在 MSYS2 中安装 Node.js:`pacman -S mingw-w64-x86_64-nodejs`
48-
2. 或者使用系统 Node.js 配合 MSYS2 编译工具
47+
**注意**:npm 随 Node.js 一起安装,无需单独安装。为了确保最佳兼容性,建议使用 MSYS2 版本的 Node.js。
4948

5049
## 构建步骤
5150

@@ -103,19 +102,24 @@ npm run test:full
103102
- 检查环境变量 PATH 中没有 Visual Studio 的路径干扰
104103
- 使用 `cmake-js compile -- -G "MinGW Makefiles"` 显式指定生成器
105104

106-
2. **找不到 gfortran**
105+
2. **链接错误:`cannot find /DELAYLOAD:NODE.EXE`**
106+
- 这是 cmake-js 的已知问题,它会为 MinGW 注入 MSVC 专用的链接器标志
107+
- 本项目的 CMakeLists.txt 已自动处理此问题,使用 `CACHE FORCE` 清空相关标志
108+
- 如果仍有问题,确保使用的是最新版本的项目代码
109+
110+
3. **找不到 gfortran**
107111
- 确保安装了 `mingw-w64-x86_64-gcc-fortran`
108112
- 运行 `which gfortran` 验证编译器路径
109113

110-
3. **Node.js 头文件找不到**
114+
4. **Node.js 头文件找不到**
111115
- 使用 MSYS2 安装的 Node.js:`pacman -S mingw-w64-x86_64-nodejs`
112116
- 或确保系统 Node.js 安装正确
113117

114-
4. **pkg-config 找不到库**
118+
5. **pkg-config 找不到库**
115119
- 确保 PKG_CONFIG_PATH 包含 MSYS2 路径:`export PKG_CONFIG_PATH="/mingw64/lib/pkgconfig"`
116120
- 验证库是否正确安装:`pkg-config --list-all | grep fftw`
117121

118-
5. **npx 命令找不到**
122+
6. **npx 命令找不到**
119123
- 如果使用系统 Node.js,确保 npm 全局安装目录在 PATH 中
120124
- 或在 MSYS2 中安装 Node.js:`pacman -S mingw-w64-x86_64-nodejs`
121125

CMakeLists.txt

Lines changed: 96 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,55 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
1717
# Enable position independent code for all targets (including subprojects)
1818
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
1919

20-
# Force avoid MSVC detection on Windows when using MinGW
21-
if(WIN32 AND MSVC)
22-
message(FATAL_ERROR "MSVC compiler detected. This project requires MinGW-w64. Please use MSYS2/MinGW-w64 environment and specify -G \"MinGW Makefiles\"")
20+
# Include cmake-js - this must come first to get CMAKE_JS_* variables
21+
if(CMAKE_JS_INC)
22+
include_directories(${CMAKE_JS_INC})
23+
endif()
24+
25+
# **关键修复**: 强制清空 cmake-js 通过命令行注入的 MSVC 缓存标志
26+
# cmake-js 会通过 -DCMAKE_SHARED_LINKER_FLAGS="/DELAYLOAD:NODE.EXE" 注入缓存
27+
# 必须使用 CACHE FORCE 来覆盖命令行传入的缓存值
28+
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
29+
message(STATUS "Detected MinGW-w64 on Windows; FORCE-clear CMAKE_SHARED_LINKER_FLAGS from cache")
30+
set(CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "Cleared MSVC-specific linker flags for MinGW compatibility" FORCE)
2331
endif()
2432

25-
# Windows MinGW-w64 specific setup
26-
if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
33+
# Add Node.js include path for node_api.h
34+
execute_process(
35+
COMMAND node -p "require('path').dirname(process.execPath) + '/../include/node'"
36+
OUTPUT_VARIABLE NODE_INCLUDE_DIR
37+
OUTPUT_STRIP_TRAILING_WHITESPACE
38+
)
39+
include_directories(${NODE_INCLUDE_DIR})
40+
41+
# **关键修复**: Windows + MinGW 环境检测并清除 MSVC 特定标志
42+
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
2743
message(STATUS "Detected MinGW-w64 environment on Windows")
2844

29-
# Set PKG_CONFIG_PATH for MSYS2
45+
# 设置 PKG_CONFIG_PATH 以便查找 MSYS2
3046
if(EXISTS "C:/msys64/mingw64/lib/pkgconfig")
3147
set(ENV{PKG_CONFIG_PATH} "C:/msys64/mingw64/lib/pkgconfig")
3248
message(STATUS "Set PKG_CONFIG_PATH to C:/msys64/mingw64/lib/pkgconfig")
3349
endif()
3450

35-
# Add MSYS2 library and include paths
51+
# 添加 MSYS2 include 和 library 路径
3652
if(EXISTS "C:/msys64/mingw64")
3753
include_directories("C:/msys64/mingw64/include")
3854
link_directories("C:/msys64/mingw64/lib")
3955
message(STATUS "Added MSYS2 include and library paths")
4056
endif()
4157
endif()
4258

59+
# Force avoid MSVC detection on Windows when using MinGW
60+
if(WIN32 AND MSVC)
61+
message(FATAL_ERROR "MSVC compiler detected. This project requires MinGW-w64. Please use MSYS2/MinGW-w64 environment and specify -G \"MinGW Makefiles\"")
62+
endif()
63+
64+
# Additional check for cmake-js on Windows - prevent Visual Studio generator
65+
if(WIN32 AND CMAKE_GENERATOR MATCHES "Visual Studio")
66+
message(FATAL_ERROR "Visual Studio generator detected. This project requires MinGW-w64. Please set CMAKE_GENERATOR=MinGW Makefiles")
67+
endif()
68+
4369
# Set compiler flags for better compatibility
4470
if(UNIX AND NOT APPLE)
4571
# Linux specific flags
@@ -78,19 +104,6 @@ elseif(WIN32)
78104
endif()
79105
endif()
80106

81-
# Include cmake-js
82-
if(CMAKE_JS_INC)
83-
include_directories(${CMAKE_JS_INC})
84-
endif()
85-
86-
# Add Node.js include path for node_api.h
87-
execute_process(
88-
COMMAND node -p "require('path').dirname(process.execPath) + '/../include/node'"
89-
OUTPUT_VARIABLE NODE_INCLUDE_DIR
90-
OUTPUT_STRIP_TRAILING_WHITESPACE
91-
)
92-
include_directories(${NODE_INCLUDE_DIR})
93-
94107
# Use pkg-config for all platforms (including Windows with MSYS2)
95108
find_package(PkgConfig REQUIRED)
96109

@@ -99,9 +112,39 @@ if(POLICY CMP0167)
99112
cmake_policy(SET CMP0167 NEW)
100113
endif()
101114

102-
# Find Boost
103-
find_package(Boost REQUIRED)
104-
set(BOOST_LIBRARIES ${Boost_LIBRARIES})
115+
# Find Boost - use different methods based on platform
116+
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
117+
# Windows with MinGW-w64: try both find_package and manual detection
118+
find_package(Boost QUIET)
119+
if(NOT Boost_FOUND)
120+
# Manual detection for MSYS2 Boost
121+
message(STATUS "Boost not found via find_package, trying manual detection...")
122+
123+
# Look for Boost in MSYS2 locations
124+
find_path(Boost_INCLUDE_DIRS
125+
NAMES boost/version.hpp
126+
PATHS /mingw64/include C:/msys64/mingw64/include
127+
NO_DEFAULT_PATH
128+
)
129+
130+
if(Boost_INCLUDE_DIRS)
131+
message(STATUS "Found Boost headers at: ${Boost_INCLUDE_DIRS}")
132+
set(Boost_FOUND TRUE)
133+
# For header-only libraries, we don't need to link anything
134+
set(BOOST_LIBRARIES "")
135+
else()
136+
message(WARNING "Boost headers not found")
137+
set(BOOST_LIBRARIES "")
138+
endif()
139+
else()
140+
message(STATUS "Boost found via find_package: ${Boost_VERSION}")
141+
set(BOOST_LIBRARIES ${Boost_LIBRARIES})
142+
endif()
143+
else()
144+
# Other platforms: use standard find_package
145+
find_package(Boost REQUIRED)
146+
set(BOOST_LIBRARIES ${Boost_LIBRARIES})
147+
endif()
105148

106149
# Find FFTW3 using pkg-config
107150
pkg_check_modules(FFTW3F REQUIRED fftw3f)
@@ -270,11 +313,27 @@ link_directories(${FFTW3F_LIBRARY_DIRS})
270313
# Source files for the Node.js addon
271314
file(GLOB_RECURSE NATIVE_SOURCES "native/*.cpp" "native/*.h")
272315

273-
# Create the Node.js addon
274-
add_library(${PROJECT_NAME} SHARED
275-
${NATIVE_SOURCES}
276-
${CMAKE_JS_SRC}
277-
)
316+
# Create the Node.js addon with MinGW-specific handling
317+
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
318+
# MinGW build: exclude Windows delay load hook
319+
add_library(${PROJECT_NAME} SHARED
320+
${NATIVE_SOURCES}
321+
)
322+
message(STATUS "MinGW build: excluding CMAKE_JS_SRC (Windows delay load hook)")
323+
else()
324+
# Other platforms: include CMAKE_JS_SRC if available
325+
if(CMAKE_JS_SRC)
326+
add_library(${PROJECT_NAME} SHARED
327+
${NATIVE_SOURCES}
328+
${CMAKE_JS_SRC}
329+
)
330+
message(STATUS "Non-MinGW build: including CMAKE_JS_SRC for delay-load hook")
331+
else()
332+
add_library(${PROJECT_NAME} SHARED
333+
${NATIVE_SOURCES}
334+
)
335+
endif()
336+
endif()
278337

279338
# Set properties for Node.js addon
280339
set_target_properties(${PROJECT_NAME} PROPERTIES
@@ -298,9 +357,15 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE
298357
# Add compile flags
299358
target_compile_options(${PROJECT_NAME} PRIVATE ${FFTW3F_CFLAGS_OTHER})
300359

301-
# Link libraries
302-
if(CMAKE_JS_LIB)
303-
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_JS_LIB})
360+
# Link libraries with MinGW-specific handling
361+
if(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
362+
# MinGW: don't link CMAKE_JS_LIB as it may cause issues
363+
message(STATUS "MinGW build: skipping CMAKE_JS_LIB linking")
364+
else()
365+
# Other platforms: link CMAKE_JS_LIB if available
366+
if(CMAKE_JS_LIB)
367+
target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_JS_LIB})
368+
endif()
304369
endif()
305370

306371
target_link_libraries(${PROJECT_NAME} PRIVATE

0 commit comments

Comments
 (0)