From 53be5a9f3d11fa8214a36ed5b3cad2ff928eff7b Mon Sep 17 00:00:00 2001 From: Cyano Hao Date: Mon, 19 Feb 2024 18:24:29 +0800 Subject: [PATCH] Add MinGW support to deb amd64 (#187) * update git attributes * add mingw support to debian package * fix build deps --- .gitattributes | 4 + addon/compiler_hint/debian.tl | 246 ++++++++++++++++++++++++++++++ addon/gen.sh | 1 + packages/debian/01-in-docker.sh | 3 +- packages/debian/builddeb.sh | 1 + packages/debian/compiler_hint.lua | 246 ++++++++++++++++++++++++++++++ packages/debian/control | 10 +- packages/debian/rules | 29 ++++ 8 files changed, 538 insertions(+), 2 deletions(-) create mode 100644 addon/compiler_hint/debian.tl create mode 100644 packages/debian/compiler_hint.lua diff --git a/.gitattributes b/.gitattributes index e7898d5a..a44d14b3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -27,3 +27,7 @@ /platform/linux/templates/*/*.template eol=lf /platform/linux/templates/*/*.fs eol=lf /platform/linux/templates/*/*.vs eol=lf + +# generated files +compiler_hint.lua eol=lf +/RedPandaIDE/themes/*.lua eol=lf diff --git a/addon/compiler_hint/debian.tl b/addon/compiler_hint/debian.tl new file mode 100644 index 00000000..75bf7bd1 --- /dev/null +++ b/addon/compiler_hint/debian.tl @@ -0,0 +1,246 @@ +global function apiVersion(): ApiVersion + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end + +local nameMap: {string:{string:string}} = { + systemGcc = { + en_US = "System GCC", + pt_BR = "GCC do sistema", + zh_CN = "系统 GCC", + zh_TW = "系統 GCC", + }, + systemClang = { + en_US = "System Clang", + pt_BR = "Clang do sistema", + zh_CN = "系统 Clang", + zh_TW = "系統 Clang", + }, + multilibGcc = { + en_US = "Multilib GCC", + pt_BR = "GCC multilib", + zh_CN = "Multilib GCC", + zh_TW = "Multilib GCC", + }, + multilibClang = { + en_US = "Multilib Clang", + pt_BR = "Clang multilib", + zh_CN = "Multilib Clang", + zh_TW = "Multilib Clang", + }, + mingwGcc = { + en_US = "MinGW GCC", + pt_BR = "GCC MinGW", + zh_CN = "MinGW GCC", + zh_TW = "MinGW GCC", + }, + release = { + en_US = ", release", + pt_BR = ", lançamento", + zh_CN = ",发布", + zh_TW = ",發佈", + }, + debug = { + en_US = ", debug", + pt_BR = ", depuração", + zh_CN = ",调试", + zh_TW = ",偵錯", + }, + debugWithAsan = { + en_US = ", debug with ASan", + pt_BR = ", depuração com ASan", + zh_CN = ",ASan 调试", + zh_TW = ",ASan 偵錯", + }, +} + +local function mergeCompilerSet(compilerSet: CompilerHint.CompilerSet, other: CompilerHint.CompilerSet) + local c = compilerSet as {string:any} + local o = other as {string:any} + for k, v in pairs(o) do + c[k] = v + end +end + +local record Config + isMultilib: boolean | nil + isMingw: boolean | nil + isClang: boolean | nil + customCompileParams: {string} | nil + customLinkParams: {string} | nil + triplet: string | nil +end + +local function generateConfig( + name: string, lang: string, + cCompiler: string, cxxCompiler: string, + config: Config +): CompilerHint.CompilerSet, CompilerHint.CompilerSet, CompilerHint.CompilerSet + local commonOptions: CompilerHint.CompilerSet = { + cCompiler = cCompiler, + cxxCompiler = cxxCompiler, + debugger = "/usr/bin/gdb", + debugServer = "/usr/bin/gdbserver", + make = "/usr/bin/make", + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = config.isMingw and ".exe" or "", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + binDirs = {"/usr/bin"}, + } + if config.isMultilib then + commonOptions.ccCmdOptPointerSize = "32" + end + if config.isMingw then + commonOptions.resourceCompiler = "/usr/bin/" .. config.triplet .. "-windres" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release = { + name = name .. (nameMap.release[lang] or nameMap.release.en_US), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_ = { + name = name .. (nameMap.debug[lang] or nameMap.debug.en_US), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan = { + name = name .. (nameMap.debugWithAsan[lang] or nameMap.debugWithAsan.en_US), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan +end + +global function main(): CompilerHint + local arch = C_System.osArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() + + local compilerList = {} + + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemGcc[lang] or nameMap.systemGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemClang[lang] or nameMap.systemClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + {isClang = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + -- TODO: better to check 32-bit libstdc++.a (lib32stdc++-dev), but its path is not fixed + if arch == "x86_64" and C_FileSystem.exists("/usr/lib32/libc.a") then + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibGcc[lang] or nameMap.multilibGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {isMultilib = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibClang[lang] or nameMap.multilibClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + {isClang = true, isMultilib = true} + ) + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + end + + -- with wine or WSL init registered in binfmt_misc, Windows binaries can run seamlessly + if ( + arch == "x86_64" and ( + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/DOSWin") or + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/WSLInterop") + ) + ) then + if C_FileSystem.isExecutable("/usr/bin/x86_64-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/x86_64-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/x86_64-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " x86_64", lang, + "/usr/bin/x86_64-w64-mingw32-gcc", "/usr/bin/x86_64-w64-mingw32-g++", + { + isMingw = true, + triplet = "x86_64-w64-mingw32", + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + } + ) + table.insert(compilerList, release) + end + end + + if C_FileSystem.isExecutable("/usr/bin/i686-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/i686-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/i686-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " i686", lang, + "/usr/bin/i686-w64-mingw32-gcc", "/usr/bin/i686-w64-mingw32-g++", + { + isMingw = true, + triplet = "i686-w64-mingw32", + customLinkParams = {extraObjects.utf8init, extraObjects.utf8manifest}, + } + ) + table.insert(compilerList, release) + end + end + end + + local result = { + compilerList = compilerList, + noSearch = { + "/usr/bin", + "/usr/lib/ccache", + }, + preferCompiler = 3, -- System GCC Debug with ASan + } + + return result + +end diff --git a/addon/gen.sh b/addon/gen.sh index 2e19e91b..04d7a556 100755 --- a/addon/gen.sh +++ b/addon/gen.sh @@ -27,3 +27,4 @@ function gen-compiler-hint() { gen-compiler-hint addon/compiler_hint/windows_domain.tl packages/msys/domain/compiler_hint.lua gen-compiler-hint addon/compiler_hint/archlinux.tl packages/archlinux/compiler_hint.lua +gen-compiler-hint addon/compiler_hint/debian.tl packages/debian/compiler_hint.lua diff --git a/packages/debian/01-in-docker.sh b/packages/debian/01-in-docker.sh index 08c1b7d0..13fa054a 100755 --- a/packages/debian/01-in-docker.sh +++ b/packages/debian/01-in-docker.sh @@ -32,7 +32,7 @@ fi export DEBIAN_FRONTEND=noninteractive apt update apt install -y --no-install-recommends \ - build-essential debhelper \ + build-essential debhelper g++-mingw-w64 \ libqt5svg5-dev qtbase5-dev qtbase5-dev-tools qttools5-dev-tools # prepare source @@ -51,6 +51,7 @@ cp Red_Panda_CPP.pro $TMP_FOLDER # build cd $TMP_FOLDER +sed -i '/CONFIG += ENABLE_LUA_ADDON/ { s/^#\s*// }' RedPandaIDE/RedPandaIDE.pro dpkg-buildpackage -us -uc -j$JOBS # copy back to host diff --git a/packages/debian/builddeb.sh b/packages/debian/builddeb.sh index 3e29a2c1..4f862b6b 100755 --- a/packages/debian/builddeb.sh +++ b/packages/debian/builddeb.sh @@ -18,4 +18,5 @@ cp -r platform $TMP_FOLDER cp Red_Panda_CPP.pro $TMP_FOLDER cd $TMP_FOLDER +sed -i '/CONFIG += ENABLE_LUA_ADDON/ { s/^#\s*// }' RedPandaIDE/RedPandaIDE.pro dpkg-buildpackage -us -uc diff --git a/packages/debian/compiler_hint.lua b/packages/debian/compiler_hint.lua new file mode 100644 index 00000000..e8c7f13a --- /dev/null +++ b/packages/debian/compiler_hint.lua @@ -0,0 +1,246 @@ +function apiVersion() + return { + kind = "compiler_hint", + major = 0, + minor = 1, + } +end + +local nameMap = { + systemGcc = { + en_US = "System GCC", + pt_BR = "GCC do sistema", + zh_CN = "系统 GCC", + zh_TW = "系統 GCC", + }, + systemClang = { + en_US = "System Clang", + pt_BR = "Clang do sistema", + zh_CN = "系统 Clang", + zh_TW = "系統 Clang", + }, + multilibGcc = { + en_US = "Multilib GCC", + pt_BR = "GCC multilib", + zh_CN = "Multilib GCC", + zh_TW = "Multilib GCC", + }, + multilibClang = { + en_US = "Multilib Clang", + pt_BR = "Clang multilib", + zh_CN = "Multilib Clang", + zh_TW = "Multilib Clang", + }, + mingwGcc = { + en_US = "MinGW GCC", + pt_BR = "GCC MinGW", + zh_CN = "MinGW GCC", + zh_TW = "MinGW GCC", + }, + release = { + en_US = ", release", + pt_BR = ", lançamento", + zh_CN = ",发布", + zh_TW = ",發佈", + }, + debug = { + en_US = ", debug", + pt_BR = ", depuração", + zh_CN = ",调试", + zh_TW = ",偵錯", + }, + debugWithAsan = { + en_US = ", debug with ASan", + pt_BR = ", depuração com ASan", + zh_CN = ",ASan 调试", + zh_TW = ",ASan 偵錯", + }, +} + +local function mergeCompilerSet(compilerSet, other) + local c = compilerSet + local o = other + for k, v in pairs(o) do + c[k] = v + end +end + + + + + + + + + + +local function generateConfig( + name, lang, + cCompiler, cxxCompiler, + config) + + local commonOptions = { + cCompiler = cCompiler, + cxxCompiler = cxxCompiler, + debugger = "/usr/bin/gdb", + debugServer = "/usr/bin/gdbserver", + make = "/usr/bin/make", + compilerType = config.isClang and "Clang" or "GCC_UTF8", + preprocessingSuffix = ".i", + compilationProperSuffix = ".s", + assemblingSuffix = ".o", + executableSuffix = config.isMingw and ".exe" or "", + compilationStage = 3, + ccCmdOptUsePipe = "on", + ccCmdOptWarningAll = "on", + ccCmdOptWarningExtra = "on", + ccCmdOptCheckIsoConformance = "on", + binDirs = { "/usr/bin" }, + } + if config.isMultilib then + commonOptions.ccCmdOptPointerSize = "32" + end + if config.isMingw then + commonOptions.resourceCompiler = "/usr/bin/" .. config.triplet .. "-windres" + end + if config.customCompileParams then + commonOptions.customCompileParams = config.customCompileParams + end + if config.customLinkParams then + commonOptions.customLinkParams = config.customLinkParams + end + local release = { + name = name .. (nameMap.release[lang] or nameMap.release.en_US), + staticLink = true, + linkCmdOptStripExe = "on", + ccCmdOptOptimize = "2", + } + local debug_ = { + name = name .. (nameMap.debug[lang] or nameMap.debug.en_US), + ccCmdOptDebugInfo = "on", + } + local debugWithAsan = { + name = name .. (nameMap.debugWithAsan[lang] or nameMap.debugWithAsan.en_US), + ccCmdOptDebugInfo = "on", + ccCmdOptAddressSanitizer = "address", + } + mergeCompilerSet(release, commonOptions) + mergeCompilerSet(debug_, commonOptions) + mergeCompilerSet(debugWithAsan, commonOptions) + return release, debug_, debugWithAsan +end + +function main() + local arch = C_System.osArch() + local libexecDir = C_System.appLibexecDir() + local lang = C_Desktop.language() + + local compilerList = {} + + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemGcc[lang] or nameMap.systemGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + {}) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.systemClang[lang] or nameMap.systemClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + { isClang = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + + if arch == "x86_64" and C_FileSystem.exists("/usr/lib32/libc.a") then + do + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibGcc[lang] or nameMap.multilibGcc.en_US, lang, + "/usr/bin/gcc", "/usr/bin/g++", + { isMultilib = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + + if C_FileSystem.isExecutable("/usr/bin/clang") then + local release, debug_, debugWithAsan = generateConfig( + nameMap.multilibClang[lang] or nameMap.multilibClang.en_US, lang, + "/usr/bin/clang", "/usr/bin/clang++", + { isClang = true, isMultilib = true }) + + table.insert(compilerList, release) + table.insert(compilerList, debug_) + table.insert(compilerList, debugWithAsan) + end + end + + + if ( + arch == "x86_64" and ( + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/DOSWin") or + C_FileSystem.exists("/proc/sys/fs/binfmt_misc/WSLInterop"))) then + + + if C_FileSystem.isExecutable("/usr/bin/x86_64-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/x86_64-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/x86_64-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " x86_64", lang, + "/usr/bin/x86_64-w64-mingw32-gcc", "/usr/bin/x86_64-w64-mingw32-g++", + { + isMingw = true, + triplet = "x86_64-w64-mingw32", + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + }) + + table.insert(compilerList, release) + end + end + + if C_FileSystem.isExecutable("/usr/bin/i686-w64-mingw32-gcc") then + local extraObjects = { + utf8init = libexecDir .. "/i686-w64-mingw32/utf8init.o", + utf8manifest = libexecDir .. "/i686-w64-mingw32/utf8manifest.o", + } + + do + local release, _, _ = generateConfig( + (nameMap.mingwGcc[lang] or nameMap.mingwGcc.en_US) .. " i686", lang, + "/usr/bin/i686-w64-mingw32-gcc", "/usr/bin/i686-w64-mingw32-g++", + { + isMingw = true, + triplet = "i686-w64-mingw32", + customLinkParams = { extraObjects.utf8init, extraObjects.utf8manifest }, + }) + + table.insert(compilerList, release) + end + end + end + + local result = { + compilerList = compilerList, + noSearch = { + "/usr/bin", + "/usr/lib/ccache", + }, + preferCompiler = 3, + } + + return result + +end diff --git a/packages/debian/control b/packages/debian/control index 38d117a3..b742463e 100644 --- a/packages/debian/control +++ b/packages/debian/control @@ -6,7 +6,8 @@ Build-Depends: debhelper (>= 12~), qtbase5-dev, qtbase5-dev-tools, qttools5-dev-tools, - libqt5svg5-dev + libqt5svg5-dev, + g++-mingw-w64 [amd64] Standards-Version: 4.3.0 Homepage: https://github.com/royqh1979/RedPanda-CPP @@ -19,6 +20,13 @@ Depends: ${shlibs:Depends}, make, gdb, gdbserver +Recommends: qterminal | deepin-terminal | konsole | gnome-terminal | terminator | lxterminal | mate-terminal | terminology | xfce4-terminal | alacritty | cool-retro-term | kitty | sakura | termit | tilix +Suggests: clang, + gcc-multilib [amd64], + g++-multilib [amd64], + gcc-mingw-w64 [amd64], + g++-mingw-w64 [amd64], + wine [amd64] Description: A lightweight but powerful C/C++ IDE Red Panda C++ (Old name Red Panda Dev-C++ 7) is a full featured C/C++ IDE. It's the succesor of Red Panda Dev-C++ 6, which is developed by Delphi 7 and diff --git a/packages/debian/rules b/packages/debian/rules index d292cde0..acc5757b 100755 --- a/packages/debian/rules +++ b/packages/debian/rules @@ -6,3 +6,32 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all %: dh ${@} --buildsystem qmake + +ifeq ($(DEB_HOST_ARCH), amd64) + +MINGW_UTF8_OBJS = x86_64-w64-mingw32/utf8init.o i686-w64-mingw32/utf8init.o x86_64-w64-mingw32/utf8manifest.o i686-w64-mingw32/utf8manifest.o + +execute_after_dh_auto_build: $(MINGW_UTF8_OBJS) + +x86_64-w64-mingw32/utf8init.o: platform/windows/utf8/utf8init.cpp + mkdir -p $(dir $@) + x86_64-w64-mingw32-g++ -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o $@ $< + +x86_64-w64-mingw32/utf8manifest.o: platform/windows/utf8/utf8manifest.rc + mkdir -p $(dir $@) + x86_64-w64-mingw32-windres -O coff -o $@ $< + +i686-w64-mingw32/utf8init.o: platform/windows/utf8/utf8init.cpp + mkdir -p $(dir $@) + i686-w64-mingw32-g++ -Os -fno-exceptions -nodefaultlibs -nostdlib -c -o $@ $< + +i686-w64-mingw32/utf8manifest.o: platform/windows/utf8/utf8manifest.rc + mkdir -p $(dir $@) + i686-w64-mingw32-windres -O coff -o $@ $< + +execute_after_dh_install: + dh_install debian/compiler_hint.lua usr/libexec/RedPandaCPP + dh_install x86_64-w64-mingw32/* usr/libexec/RedPandaCPP/x86_64-w64-mingw32 + dh_install i686-w64-mingw32/* usr/libexec/RedPandaCPP/i686-w64-mingw32 + +endif