diff --git a/scripts/installer.nsi b/scripts/installer.nsi index 184ed73..e3b8f06 100644 --- a/scripts/installer.nsi +++ b/scripts/installer.nsi @@ -1,8 +1,7 @@ -; L Language 编译器 Windows 安装包 +Unicode true +; L Language 编译器 Windows 安装包 ; 构建: makensis -DVERSION=x.y.z installer.nsi -Unicode true - !ifndef VERSION !define VERSION "0.6.0" !endif @@ -12,7 +11,7 @@ Unicode true !define EXE "l_lang.exe" Name "${PRODUCT} ${VERSION}" -OutFile "..\build\L-Language-${VERSION}-setup.exe" +OutFile "..\release\L-Language-${VERSION}-setup.exe" InstallDir "$PROGRAMFILES\L Language" RequestExecutionLevel admin SetCompressor /SOLID lzma @@ -39,12 +38,29 @@ Section "Install" File "..\build\${EXE}" ; LLVM 运行时 (编译必须) File "D:\settings\Language\LLVM\bin\LLVM-C.dll" - ; 链接器 (.o -> .exe) - File "D:\settings\Language\LLVM\bin\clang.exe" + ; lld 链接器 (.o -> .exe) File "D:\settings\Language\LLVM\bin\ld.lld.exe" - ; MinGW 线程运行时 + ; MinGW 线程运行时 DLL File "D:\settings\Language\C\mingw64\bin\libmcfgthread-2.dll" + ; MinGW 链接库 (自包含,无需用户安装 MinGW) + SetOutPath "$INSTDIR\mingw_lib" + File "..\mingw_lib\crt2.o" + File "..\mingw_lib\crtbegin.o" + File "..\mingw_lib\crtend.o" + File "..\mingw_lib\libmingw32.a" + File "..\mingw_lib\libmcfgthread.a" + File "..\mingw_lib\libgcc.a" + File "..\mingw_lib\libgcc_eh.a" + File "..\mingw_lib\libmoldname.a" + File "..\mingw_lib\libmingwex.a" + File "..\mingw_lib\libmsvcrt.a" + File "..\mingw_lib\libadvapi32.a" + File "..\mingw_lib\libshell32.a" + File "..\mingw_lib\libuser32.a" + File "..\mingw_lib\libkernel32.a" + File "..\mingw_lib\libntdll.a" + ; 示例程序 SetOutPath "$INSTDIR\examples" File "..\test\programs\01_arithmetic.l" @@ -124,11 +140,11 @@ SectionEnd Section "Uninstall" Delete "$INSTDIR\${EXE}" Delete "$INSTDIR\LLVM-C.dll" - Delete "$INSTDIR\clang.exe" Delete "$INSTDIR\ld.lld.exe" Delete "$INSTDIR\libmcfgthread-2.dll" Delete "$INSTDIR\快速入门.bat" Delete "$INSTDIR\uninstall.exe" + RMDir /r "$INSTDIR\mingw_lib" RMDir /r "$INSTDIR\examples" RMDir "$INSTDIR" diff --git a/src/driver/main.c b/src/driver/main.c index abe6568..e67a1da 100644 --- a/src/driver/main.c +++ b/src/driver/main.c @@ -12,6 +12,21 @@ #include #include +#ifdef _WIN32 +#include +#endif + +// 获取 exe 所在目录(用于定位打包的 MinGW 库) +static void get_exe_dir(char* buf, size_t size) { +#ifdef _WIN32 + GetModuleFileNameA(NULL, buf, (DWORD)size); + char* last = strrchr(buf, '\\'); + if (last) *last = '\0'; +#else + buf[0] = '.'; buf[1] = '\0'; +#endif +} + // 读取整个文件到内存 static char* read_file(const char* path, size_t* size) { FILE* f = fopen(path, "rb"); @@ -137,34 +152,32 @@ int main(int argc, char** argv) { return 1; } - // 链接:优先 clang + lld(LLVM 自带),fallback gcc - char cmd[1024]; + // 链接:优先安装包自带的 ld.lld + MinGW 库,fallback clang/gcc + char cmd[2048]; int ret = -1; + char exe_dir[512]; + get_exe_dir(exe_dir, sizeof(exe_dir)); - // 构造 LLVM bin 路径(从 LLVM-C.dll 的位置推断) - char llvm_clang[512]; - snprintf(llvm_clang, sizeof(llvm_clang), - "D:/settings/Language/LLVM/bin/clang.exe"); - - // 1) 优先: clang + lld(零新依赖,已随 LLVM 安装) + // 1) 优先: 安装包自带的 ld.lld + 自带 MinGW 库(完全自包含) snprintf(cmd, sizeof(cmd), - "\"%s\" -target x86_64-w64-windows-gnu -fuse-ld=lld \"%s\" -o \"%s\"", - llvm_clang, obj_path, output); + "\"%s/ld.lld.exe\" -m i386pep " + "\"%s/mingw_lib/crt2.o\" \"%s/mingw_lib/crtbegin.o\" " + "\"%s\" " + "-L \"%s/mingw_lib\" " + "-lmingw32 -lmcfgthread -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt " + "-ladvapi32 -lshell32 -luser32 -lkernel32 -lntdll " + "\"%s/mingw_lib/crtend.o\" " + "-o \"%s\"", + exe_dir, exe_dir, exe_dir, + obj_path, exe_dir, + exe_dir, output); ret = system(cmd); - // 2) 备选: 系统 PATH 中的 clang + // 2) 最后 fallback: gcc(开发机有 MinGW 时) if (ret != 0) { snprintf(cmd, sizeof(cmd), - "clang -target x86_64-w64-windows-gnu -fuse-ld=lld \"%s\" -o \"%s\"", - obj_path, output); - ret = system(cmd); - } - - // 3) 最后 fallback: gcc - if (ret != 0) { - snprintf(cmd, sizeof(cmd), - "gcc \"%s\" -o \"%s\"", - obj_path, output); + "gcc \"%s\" -o \"%s\"", + obj_path, output); ret = system(cmd); }