import argparse
import os
import shutil
import sys
from shutil import copy2from loguru import loggerclass GoBuild : """一个用于构建跨平台执行文件的类。初始化函数,设置构建的主文件、生成的执行文件名称以及目标平台。:param f: 需要构建的主文件(例如: main.go):param n: 生成的执行文件主名称(例如: install)""" def __init__ ( self, f, n= None ) : self. darwin = darwinself. go = "go" self. name = nself. arch_list = [ ] self. os_list = [ ] self. amd64 = False self. mips64 = False self. arm64 = False self. arm32 = False self. linux = False self. windows = False self. file = fself. basename = "" self. archs = "X86_64" self. os_type = "" self. exe = "" self. tmp = "" self. logger = loggerdef init ( self) : """初始化函数,根据不同的架构和操作系统生成相应的架构和操作系统列表,并设置可执行文件的基础名称。""" if self. arm64: self. arch_list. append( "arm64" ) if self. mips64: self. arch_list. append( "mips64le" ) if self. amd64: self. arch_list. append( "amd64" ) if self. arm32: self. arch_list. append( "arm" ) if self. linux: self. os_list. append( "linux" ) if self. windows: self. os_list. append( "windows" ) if self. darwin: self. os_list. append( "darwin" ) if self. name is None : self. basename = str ( os. path. basename( self. file ) ) . replace( ".go" , "" ) else : self. basename = self. namedef delete ( self) : """开始删除生成的临时文件:return: None""" tmp = os. path. join( os. getcwd( ) , self. tmp) try : os. remove( path= self. tmp) self. logger. debug( f"删除成功: { tmp} " ) except Exception as e: self. logger. error( f"删除出错 - [ { tmp} ] : { str ( e) } " ) def copy ( self) : """复制执行文件到目标目录,并根据当前环境调整文件路径。此方法首先构建目标文件路径,然后尝试从临时文件路径复制文件到目标路径,如果临时文件存在的话。如果复制成功,它将调用delete方法删除临时文件。如果临时文件不存在,它将记录一个警告消息。""" dst = os. path. join( "client" , self. exe) dst = os. path. join( os. getcwd( ) , dst) dst = str ( dst) . replace( "amd64" , "X86_64" ) self. logger. debug( f"开始复制: { dst} " ) if os. path. isfile( self. tmp) : try : copy2( src= self. tmp, dst= dst) self. delete( ) except Exception as e: self. logger. error( f"复制失败: { str ( e) } " ) else : self. logger. warning( f"文件不存在: { self. tmp} " ) def build ( self) : """构建指定的Go文件,根据操作系统类型和架构进行编译,并处理构建结果。1. 根据架构类型转换变量`self.archs`,确保其符合预期的架构命名规范。2. 记录构建系统的操作系统类型和架构,用于调试和追踪。3. 根据操作系统和架构生成可执行文件名`self.exe`,并调整Windows系统下的文件扩展名。4. 构建Go文件,如果构建成功则调用`self.copy()`方法处理构建结果,否则记录错误并退出程序。""" if self. archs == "amd64" : self. archs = "X86_64" self. logger. debug( f"构建系统: { self. os_type} " , ) self. logger. debug( f"构建架构: { self. archs} " ) self. exe = self. basename + "_" + self. os_type + "-" + self. archsself. tmp = str ( os. path. basename( self. file ) ) . replace( ".go" , "" ) if self. os_type == "windows" : self. exe = self. exe + ".exe" self. tmp = self. tmp + ".exe" c = f" { self. go} build { self. file } " if os. system( c) == 0 : self. logger. info( f"构建成功,正在生成: { self. exe} " ) self. copy( ) else : self. logger. error( f"构建失败: { self. exe} " ) print ( c) sys. exit( 2 ) def ost ( self, o) : """设置操作系统类型该方法主要用于设置GOOS环境变量,以模拟不同的操作系统环境这对于后续的编译过程特别重要,因为GOOS环境变量决定了编译输出的目标操作系统。参数:o (str): 要模拟的操作系统类型,例如"linux"、"windows"等。返回:无""" os. environ[ 'GOOS' ] = oself. os_type = odef arch ( self, arch) : """设置架构并触发构建过程该方法接收一个架构名称,根据特定规则转换后设置环境变量GOARCH,并将该架构名称保存以供后续使用。最后,调用build方法进行构建。参数:arch (str): 构架名称,可能需要转换以适配特定的命名约定。返回:无""" if arch == "X86_64" : arch = "amd64" os. environ[ 'GOARCH' ] = archself. archs = archself. build( ) def start ( self, save) : """启动初始化和操作系统处理流程在这个方法中,首先进行初始化操作,然后根据`save`参数检查目录是否存在,如果不存在则创建目录.随后,遍历操作系统列表,对每个操作系统进行处理.对于Linux操作系统,进一步遍历其架构列表并进行处理;对于其他操作系统,则默认使用X86_64架构进行处理.参数:save (str): 保存路径字符串,用于检查是否存在以及创建目录""" self. init( ) if not os. path. isdir( save) : os. mkdir( "./client" ) for i in self. os_list: self. ost( i) if i == "linux" : self. logger. debug( f"架构列表: { self. arch_list} " ) for a in self. arch_list: self. arch( arch= a) else : self. arch( arch= "X86_64" )
if __name__ == "__main__" : cwd = os. getcwd( ) parser = argparse. ArgumentParser( ) parser. add_argument( "-f" , "--file" , help = "源代码文件名" , type = str , default= "ssl.go" ) parser. add_argument( "-n" , "--name" , help = "项目名称" , type = str , default= "ssl" ) parser. add_argument( "-l" , "--linux" , help = "是否启用Linux平台" , action= 'store_true' , default= True ) parser. add_argument( "--no-linux" , help = "禁用Linux平台" , action= 'store_false' , dest= 'linux' ) parser. add_argument( "-d" , "--darwin" , help = "是否启用Darwin平台" , action= 'store_true' , default= True ) parser. add_argument( "--no-darwin" , help = "禁用Darwin平台" , action= 'store_false' , dest= 'darwin' ) parser. add_argument( "-w" , "--windows" , help = "是否启用Windows平台" , action= 'store_true' , default= True ) parser. add_argument( "--no-windows" , help = "禁用Windows平台" , action= 'store_false' , dest= 'windows' ) parser. add_argument( "-a" , "--arm64" , help = "是否启用arm64平台" , action= 'store_true' , default= True ) parser. add_argument( "--no-arm64" , help = "禁用arm64平台" , action= 'store_false' , dest= 'arm64' ) parser. add_argument( "-r32" , "--arm32" , help = "是否启用arm32平台" , action= 'store_true' , default= True ) parser. add_argument( "--no-arm32" , help = "禁用arm32平台" , action= 'store_false' , dest= 'arm32' ) parser. add_argument( "-m" , "--mips64" , help = "是否启用mips64平台" , action= 'store_true' , default= True ) parser. add_argument( "--no-mips64" , help = "禁用mips64平台" , action= 'store_false' , dest= 'mips64' ) parser. add_argument( "-x" , "--x86" , help = "是否启用amd64/x86平台" , action= 'store_true' , default= True ) parser. add_argument( "--no-x86" , help = "禁用amd64/x86平台" , action= 'store_false' , dest= 'x86' ) client_ = os. path. join( cwd, 'client' ) parser. add_argument( "-o" , "--output" , help = f"保存目录->默认: { client_} " , type = str , default= client_) parser. add_argument( "-v" , "--version" , action= 'version' , version= '%(prog)s 1.0' ) args = parser. parse_args( ) file = args. file name = args. namemips64 = args. mips64linux = args. linuxdarwin = args. darwinarm64 = args. arm64x86 = args. x86arm32 = args. arm32windows = args. windowsprint ( args) print ( f"文件名: { file } " ) print ( f"Linux: { args. linux} " ) print ( f"Darwin: { args. darwin} " ) print ( f"Windows: { args. windows} " ) print ( f"ARM64: { args. arm64} " ) print ( f"ARM32: { args. arm32} " ) print ( f"MIPS64: { args. mips64} " ) print ( f"X86: { args. x86} " ) up = GoBuild( f= file , n= name) up. arm32 = arm32up. windows = windowsup. arm64 = arm64up. mips64 = mips64up. x86 = x86up. linux = linuxup. darwin = darwinup. start( save= args. output)
效果