FreeFileSync 14.12 → Windows (MinGW UCRT64) 版本编译移植状态结论可以编译成 Windows 版本。截至 2025-06全部 87 个源文件通过 Windows (MinGW UCRT64 / GCC) 语法检查zen/平台层 21/21 ✅应用层FreeFileSync/Source libcurl wx xBRZ66/66 ✅TOTAL FAILED: 0代码地址https://gitee.com/tody_guo/free-file-sync_win.git检查环境MSYS2:build_env\msys64工具链 ucrt64PATH/ucrt64/bin:/usr/bin库: wxwidgets3.3-msw / curl / libssh2(1.11.1) / openssl / libidn2 / zlib / libxml2 / glib2Shell 是 cmd → 复杂命令写成build_env/*.sh脚本执行检查脚本:build_env/check_all_zen.shzen、build_env/check_ffs_all.sh应用层 66 文件应用层编译命令模板在 FreeFileSync/Source 下g -fsyntax-only -stdc23 -DNDEBUG -I../.. -I../../zenXml -include zen/i18n.h \ -DWXINTL_NO_GETTEXT_MACRO -DwxNO_IMPLICIT_WXSTRING_ENCODING -DHAVE_LIBSSH2 \ $(pkg-config --cflags openssl libcurl libidn2 libssh2 glib-2.0) \ $(wx-config --cxxflags --debugno) filezen 层:-I. -IzenXml $(pkg-config --cflags glib-2.0)关键移植决策已完成UTF-8 ACP 窄字符路线zen/zstring.h用charFILE_NAME_SEPARATORWin32 →\\glib2 全平台依赖zen/sys_error.h无条件glib.hformatGlibError ftp.cpp g_convert官方 Windows 版也链接 glib-DwxNO_IMPLICIT_WXSTRING_ENCODING必须wxString::c_str() 歧义wxColorHookstock wx 无此私有补丁 →wx/darkmode.h本地zen::ColorHook批量替换wxSystemSettings::GetColour(→getSystemColorHooked(FileIndexMinGW ino_t 仅 16 位 →zen/file_access.h#ifdef _WIN32 using FileIndex uint64_t真 64 位索引用GetFileInformationByHandle(nFileIndexHigh/Low)file_access.cpp copyNewFilesocket.h 全重写WinSock2 版SocketTypeSOCKET、closesocket、WSAPoll、EAI 缺常量 case 裁剪、THROW_LAST_SYS_ERROR_GAIWin32 分支无 EAI_SYSTEMpoll/accept4 shim 在 socket.h不在 win_posix.h因为依赖 SysError/SocketTypenative.cppWin32 目录遍历改用zen::traverseFolder替代 opendir/readdirst_mtim→timespec{.tv_sec st_mtime}秒精度sys/vfs.h条件化磁盘空间走 zen 层 GetDiskFreeSpaceExA shimftp.cppglib.h恢复g_convert LATIN1↔UTF8fcntl FD_CLOEXEC 块#ifndef _WIN32Windows 无 fork/execcurl_wrap.cpp同上 SOCKOPT/CLOEXEC 条件化version_check.cppgtk/gtk.h条件化os_name Win32 → “Windows”libssh2 1.11.1 缺常量兜底libssh2_wrap.h / sftp.cppLIBSSH2_ERROR_STORE_OVERFLOW-55、MAX_SFTP_READ_SIZE30000、MAX_SFTP_OUTGOING_SIZE30000sys_error.h/.cppformatGlibError全平台声明Win32 实现只走 g_quark_to_string 路径无 giowx 差异ShowScrollbars()wxScrollHelperBase、wxUSE_EXCEPTIONStry/catch 包装、dc.hDPI 宏双分支构建状态2025-09-25 更新exe 已产出并冒烟通过 ✅CMake 构建系统win_build/CMakeLists.txtFFS 主程序 RealTimeSync 两个 target镜像两个 Makefile 的全部 cppFiles产出FreeFileSync/Build/Bin/FreeFileSync.exe7.4MB、RealTimeSync.exe1.7MBGUI 启动、加载配置、中文界面均正常构建命令build_env\msys64\usr\bin\bash.exe --noprofile --norc build_env\cmake_build.sh内部win_build 下 cmake -G NinjaCMake 陷阱MSYS是 CMake 保留变量名project() 后被重置→ 用MSYS_PREFIXmanifest 改动不触发 RC 重编 →touch ffs.rc rts.rcwindres RCffs.rc/rts.rc版本信息 manifestCMAKE_RC_FLAGS--include-dirwin_build解析 app.manifestmanifest 关键项activeCodePageUTF-8PerMonitorV2DPI Microsoft.Windows.Common-Controls 6.0依赖必须缺 comctl32 v6 → wx core 静态导入GetWindowSubclass解析失败 → STATUS_ENTRYPOINT_NOT_FOUND(0xC0000139) → loader 弹框进程挂死0 窗口、2 线程、卡 LdrpSnapModule/LpcReply诊断路径minidumpbuild_env/minidump.py→ mcp_windbg open_cdb_dump → 线程栈LdrpSnapModule→LdrpReportError 栈上 UTF-16 函数名构建期唯一源码改动RealTimeSync/main_dlg.cppgtk.h 加#ifndef _WIN32包裹无 gtk 符号引用纯多余 includeversion_check.cpp 此前已条件化资源就绪FreeFileSync/Build/ResourcesIcons.zip/Languages.zip/cacert.pem/wav 全在运行目录即 Build/Bin配置在 %APPDATA%\FreeFileSync链接库清单CMakeLists COMMON_LIBSwx_mswu_{aui,richtext,xrc,html,qa,core,baseu_xml,baseu_net,baseu}-3.3 curl ssl crypto idn2 ssh2 glib-2.0 intl z ws2_32 ntdll shlwapi winmm gdi32 shell32 advapi32 ole32 oleaut32 uuid comctl32 rpcrt4运行依赖build_env/deploy_dlls.sh已把 41 个运行时 DLL 递归复制到Build\Binwx 全家桶/curl/ssl/crypto/idn2/ssh2/glib/intl/pcre2/iconv/unistring/brotli/nghttp2/nghttp3/ngtcp2/psl/zstd/lzma/jpeg/png/tiff/webp/expat/zlib1/gcc/stdc/winpthread 等Bin 目录已自包含48MB无需 ucrt64\bin 在 PATHapi-ms-win-crt-*是系统内置 API Set 虚拟 DLL无需部署运行时注意不阻塞编译UCRTrename()不覆盖已存在目标EEXIST≠ POSIX 原子覆盖语义 →zen/file_access.cppmoveFileOrDir 的 Win32 分支用MoveFileExA(MOVEFILE_REPLACE_EXISTING)ERROR_NOT_SAME_DEVICE→ErrorMoveUnsupported 对应 EXDEV症状是保存配置报错误代码 17: File exists [rename]Bugs.txt 的 wx 3.3.3 私有补丁framemanager/stattextcmn/bmpbndl/toplvcmn 等仅运行时行为按需移植sys_version.cpp已过编译但运行时逻辑仍 Linux-only需后续加 Win32 分支LPDDR 等无关记忆无