Made it work on linux

This commit is contained in:
rdb 2008-12-15 21:30:50 +00:00
parent 6132cec34e
commit cafd7c93f9

View File

@ -1,7 +1,8 @@
############################################################################# #############################################################################
# #
# packpanda - this is a tool that packages up a panda game into a # packpanda - this is a tool that packages up a panda game into a
# convenient, easily-downloaded windows executable. Packpanda relies on # convenient, easily-downloaded windows executable. Packpanda runs on linux
# and windows - on linux, it builds .debs and .rpms, on windows it relies on
# NSIS, the nullsoft scriptable install system, to do the hard work. # NSIS, the nullsoft scriptable install system, to do the hard work.
# #
# This is intentionally a very simplistic game-packer with very # This is intentionally a very simplistic game-packer with very
@ -12,7 +13,7 @@
# #
############################################################################## ##############################################################################
import sys, os, getopt, string, shutil, py_compile import sys, os, getopt, string, shutil, py_compile, subprocess
OPTIONLIST = [ OPTIONLIST = [
("dir", 1, "Name of directory containing game"), ("dir", 1, "Name of directory containing game"),
@ -76,12 +77,14 @@ if (PANDA is None):
sys.exit("Cannot locate the panda root directory in the python path (cannot locate directory containing direct and pandac).") sys.exit("Cannot locate the panda root directory in the python path (cannot locate directory containing direct and pandac).")
print "PANDA located at "+PANDA print "PANDA located at "+PANDA
if (os.path.exists(os.path.join(PANDA,"..","makepanda","makepanda.py"))) and (os.path.exists(os.path.join(PANDA,"..","thirdparty","win-nsis","makensis.exe"))): if (os.path.exists(os.path.join(PANDA,"..","makepanda","makepanda.py"))) and (sys.platform != "win32" or os.path.exists(os.path.join(PANDA,"..","thirdparty","win-nsis","makensis.exe"))):
PSOURCE=os.path.abspath(os.path.join(PANDA,"..")) PSOURCE=os.path.abspath(os.path.join(PANDA,".."))
NSIS=os.path.abspath(os.path.join(PANDA,"..","thirdparty","win-nsis")) if (sys.platform == "win32"):
NSIS=os.path.abspath(os.path.join(PANDA,"..","thirdparty","win-nsis"))
else: else:
PSOURCE=PANDA PSOURCE=PANDA
NSIS=os.path.join(PANDA,"nsis") if (sys.platform == "win32"):
NSIS=os.path.join(PANDA,"nsis")
############################################################################## ##############################################################################
# #
@ -95,21 +98,26 @@ if (DIR==""):
print "You must specify the --dir option." print "You must specify the --dir option."
ParseFailure() ParseFailure()
DIR=os.path.abspath(DIR) DIR=os.path.abspath(DIR)
NAME=os.path.basename(DIR) MYDIR=os.path.abspath(os.getcwd())
BASENAME=os.path.basename(DIR)
if (OPTIONS["name"] != ""): if (OPTIONS["name"] != ""):
NAME=OPTIONS["name"] NAME=OPTIONS["name"]
else:
NAME=BASENAME
SMDIRECTORY=NAME SMDIRECTORY=NAME
if (VER!=""): SMDIRECTORY=SMDIRECTORY+" "+VER if (VER!=""): SMDIRECTORY=SMDIRECTORY+" "+VER
ICON=os.path.join(DIR, "icon.ico") PYTHONV="python"+sys.version[:3]
BITMAP=os.path.join(DIR, "installer.bmp")
LICENSE=os.path.join(DIR, "license.txt") LICENSE=os.path.join(DIR, "license.txt")
OUTFILE=os.path.basename(DIR) OUTFILE=os.path.basename(DIR)
if (VER!=""): OUTFILE=OUTFILE+"-"+VER if (VER!=""): OUTFILE=OUTFILE+"-"+VER
OUTFILE=os.path.abspath(OUTFILE+".exe") if (sys.platform == "win32"):
INSTALLDIR='C:\\'+os.path.basename(DIR) ICON=os.path.join(DIR, "icon.ico")
if (VER!=""): INSTALLDIR=INSTALLDIR+"-"+VER BITMAP=os.path.join(DIR, "installer.bmp")
COMPRESS="lzma" OUTFILE=os.path.abspath(OUTFILE+".exe")
if (OPTIONS["fast"]): COMPRESS="zlib" INSTALLDIR='C:\\'+os.path.basename(DIR)
if (VER!=""): INSTALLDIR=INSTALLDIR+"-"+VER
COMPRESS="lzma"
if (OPTIONS["fast"]): COMPRESS="zlib"
if (OPTIONS["pyc"]): MAIN="main.pyc" if (OPTIONS["pyc"]): MAIN="main.pyc"
else: MAIN="main.py" else: MAIN="main.py"
@ -123,11 +131,13 @@ PrintFileStatus("Dir", DIR)
print "%-15s: %s"%("Name", NAME) print "%-15s: %s"%("Name", NAME)
print "%-15s: %s"%("Start Menu", SMDIRECTORY) print "%-15s: %s"%("Start Menu", SMDIRECTORY)
PrintFileStatus("Main", os.path.join(DIR, MAIN)) PrintFileStatus("Main", os.path.join(DIR, MAIN))
PrintFileStatus("Icon", ICON) if (sys.platform == "win32"):
PrintFileStatus("Bitmap", BITMAP) PrintFileStatus("Icon", ICON)
PrintFileStatus("Bitmap", BITMAP)
PrintFileStatus("License", LICENSE) PrintFileStatus("License", LICENSE)
print "%-15s: %s"%("Output", OUTFILE) print "%-15s: %s"%("Output", OUTFILE)
print "%-15s: %s"%("Install Dir", INSTALLDIR) if (sys.platform == "win32"):
print "%-15s: %s"%("Install Dir", INSTALLDIR)
if (os.path.isdir(DIR)==0): if (os.path.isdir(DIR)==0):
sys.exit("Difficulty reading "+DIR+". Cannot continue.") sys.exit("Difficulty reading "+DIR+". Cannot continue.")
@ -138,13 +148,14 @@ if (os.path.isfile(os.path.join(DIR, "main.py"))==0):
if (os.path.isfile(LICENSE)==0): if (os.path.isfile(LICENSE)==0):
LICENSE=os.path.join(PANDA,"LICENSE") LICENSE=os.path.join(PANDA,"LICENSE")
if (os.path.isfile(BITMAP)==0): if (sys.platform == "win32") and (os.path.isfile(BITMAP)==0):
BITMAP=os.path.join(NSIS,"Contrib","Graphics","Wizard","nsis.bmp") BITMAP=os.path.join(NSIS,"Contrib","Graphics","Wizard","nsis.bmp")
if (os.path.isfile(ICON)==0): if (sys.platform == "win32"):
PPICON="bin\\ppython.exe" if (os.path.isfile(ICON)==0):
else: PPICON="bin\\ppython.exe"
PPICON="game\\icon.ico" else:
PPICON="game\\icon.ico"
############################################################################## ##############################################################################
# #
@ -156,7 +167,7 @@ def limitedCopyTree(src, dst, rmdir):
if (os.path.isdir(src)): if (os.path.isdir(src)):
if (rmdir.has_key(os.path.basename(src))): if (rmdir.has_key(os.path.basename(src))):
return return
os.mkdir(dst) if (not os.path.isdir(dst)): os.mkdir(dst)
for x in os.listdir(src): for x in os.listdir(src):
limitedCopyTree(os.path.join(src,x), os.path.join(dst,x), rmdir) limitedCopyTree(os.path.join(src,x), os.path.join(dst,x), rmdir)
else: else:
@ -164,8 +175,12 @@ def limitedCopyTree(src, dst, rmdir):
TMPDIR=os.path.abspath("packpanda-TMP") TMPDIR=os.path.abspath("packpanda-TMP")
TMPGAME=os.path.join(TMPDIR,"game") if (sys.platform == "win32"):
TMPETC=os.path.join(TMPDIR,"etc") TMPGAME=os.path.join(TMPDIR,"game")
TMPETC=os.path.join(TMPDIR,"etc")
else:
TMPGAME=os.path.join(TMPDIR,"usr","share","games",BASENAME,"game")
TMPETC=os.path.join(TMPDIR,"usr","share","games",BASENAME,"etc")
print "" print ""
print "Copying the game to "+TMPDIR+"..." print "Copying the game to "+TMPDIR+"..."
if (os.path.exists(TMPDIR)): if (os.path.exists(TMPDIR)):
@ -176,12 +191,16 @@ try:
rmdir = {} rmdir = {}
for x in OPTIONS["rmdir"]: for x in OPTIONS["rmdir"]:
rmdir[x] = 1 rmdir[x] = 1
limitedCopyTree(DIR, TMPGAME, rmdir)
if not os.path.isdir( TMPGAME ): if not os.path.isdir( TMPGAME ):
os.mkdir(TMPGAME) os.makedirs(TMPGAME)
limitedCopyTree(os.path.join(PANDA, "etc"), TMPETC, {}) limitedCopyTree(DIR, TMPGAME, rmdir)
if not os.path.isdir( TMPETC ): if not os.path.isdir( TMPETC ):
os.mkdir(TMPETC) os.makedirs(TMPETC)
if sys.platform == "win32":
limitedCopyTree(os.path.join(PANDA, "etc"), TMPETC, {})
else:
shutil.copyfile("/etc/Config.prc", os.path.join(TMPETC, "Config.prc"))
shutil.copyfile("/etc/Confauto.prc", os.path.join(TMPETC, "Confauto.prc"))
except: sys.exit("Cannot copy game to "+TMPDIR) except: sys.exit("Cannot copy game to "+TMPDIR)
############################################################################## ##############################################################################
@ -219,14 +238,20 @@ if OPTIONS["bam"]:
# #
############################################################################## ##############################################################################
EGG2BAM=os.path.join(PANDA,"bin","egg2bam.exe") if (sys.platform == "win32"):
EGG2BAM=os.path.join(PANDA,"bin","egg2bam.exe")
else:
EGG2BAM=os.path.join(PANDA,"bin","egg2bam")
def egg2bam(file,bam): def egg2bam(file,bam):
present = os.path.exists(bam) present = os.path.exists(bam)
if (present): bam = "packpanda-TMP.bam"; if (present): bam = "packpanda-TMP.bam";
cmd = 'egg2bam -noabs -ps rel -pd . "'+file+'" -o "'+bam+'"' cmd = 'egg2bam -noabs -ps rel -pd . "'+file+'" -o "'+bam+'"'
print "Executing: "+cmd print "Executing: "+cmd
res = os.spawnl(os.P_WAIT, EGG2BAM, cmd) if (sys.platform == "win32"):
res = os.spawnl(os.P_WAIT, EGG2BAM, cmd)
else:
res = os.system(cmd)
if (res != 0): sys.exit("Problem in egg file: "+file) if (res != 0): sys.exit("Problem in egg file: "+file)
if (present) or (OPTIONS["bam"]==0): if (present) or (OPTIONS["bam"]==0):
os.unlink(bam) os.unlink(bam)
@ -283,32 +308,114 @@ DeleteFiles(".")
############################################################################## ##############################################################################
# #
# Run NSIS. Yay! # Now make the installer. Yay!
# #
############################################################################## ##############################################################################
CMD="\""+NSIS+"\\makensis.exe\" /V2 " INSTALLER_DEB_FILE="""
CMD=CMD+'/DCOMPRESSOR="'+COMPRESS+'" ' Package: BASENAME
CMD=CMD+'/DNAME="'+NAME+'" ' Version: VERSION
CMD=CMD+'/DSMDIRECTORY="'+SMDIRECTORY+'" ' Section: games
CMD=CMD+'/DINSTALLDIR="'+INSTALLDIR+'" ' Priority: optional
CMD=CMD+'/DOUTFILE="'+OUTFILE+'" ' Architecture: ARCH
CMD=CMD+'/DLICENSE="'+LICENSE+'" ' Essential: no
CMD=CMD+'/DLANGUAGE="English" ' Depends: PYTHONV
CMD=CMD+'/DRUNTEXT="Play '+NAME+'" ' Provides: BASENAME
CMD=CMD+'/DIBITMAP="'+BITMAP+'" ' Description: NAME
CMD=CMD+'/DUBITMAP="'+BITMAP+'" ' Maintainer: Unknown
CMD=CMD+'/DPANDA="'+PANDA+'" ' """
CMD=CMD+'/DPANDACONF="'+TMPETC+'" '
CMD=CMD+'/DPSOURCE="'+PSOURCE+'" '
CMD=CMD+'/DPPGAME="'+TMPGAME+'" '
CMD=CMD+'/DPPMAIN="'+MAIN+'" '
CMD=CMD+'/DPPICON="'+PPICON+'" '
CMD=CMD+'"'+PSOURCE+'\\direct\\src\\directscripts\\packpanda.nsi"'
print "" INSTALLER_SPEC_FILE="""
print CMD Summary: NAME
print "packing..." Name: BASENAME
os.system(CMD) Version: VERSION
Release: 1
Group: Amusement/Games
License: See license file
BuildRoot: TMPDIR
BuildRequires: PYTHONV
%description
NAME
%files
%defattr(-,root,root)
/usr/bin/BASENAME
/usr/lib/games/BASENAME
/usr/share/games/BASENAME
"""
RUN_SCRIPT="""
#!/bin/sh
cd /usr/share/games/BASENAME/game
PYTHONPATH=/usr/lib/games/BASENAME:/usr/share/games/BASENAME
LD_LIBRARY_PATH=/usr/lib/games/BASENAME
PYTHONV MAIN
"""
if (sys.platform == "win32"):
CMD="\""+NSIS+"\\makensis.exe\" /V2 "
CMD=CMD+'/DCOMPRESSOR="'+COMPRESS+'" '
CMD=CMD+'/DNAME="'+NAME+'" '
CMD=CMD+'/DSMDIRECTORY="'+SMDIRECTORY+'" '
CMD=CMD+'/DINSTALLDIR="'+INSTALLDIR+'" '
CMD=CMD+'/DOUTFILE="'+OUTFILE+'" '
CMD=CMD+'/DLICENSE="'+LICENSE+'" '
CMD=CMD+'/DLANGUAGE="English" '
CMD=CMD+'/DRUNTEXT="Play '+NAME+'" '
CMD=CMD+'/DIBITMAP="'+BITMAP+'" '
CMD=CMD+'/DUBITMAP="'+BITMAP+'" '
CMD=CMD+'/DPANDA="'+PANDA+'" '
CMD=CMD+'/DPANDACONF="'+TMPETC+'" '
CMD=CMD+'/DPSOURCE="'+PSOURCE+'" '
CMD=CMD+'/DPPGAME="'+TMPGAME+'" '
CMD=CMD+'/DPPMAIN="'+MAIN+'" '
CMD=CMD+'/DPPICON="'+PPICON+'" '
CMD=CMD+'"'+PSOURCE+'\\direct\\src\\directscripts\\packpanda.nsi"'
print ""
print CMD
print "packing..."
subprocess.call(CMD)
else:
os.chdir(MYDIR)
os.system("mkdir -p %s/usr/bin" % TMPDIR)
os.system("mkdir -p %s/usr/share/games/%s" % (TMPDIR, BASENAME))
os.system("mkdir -p %s/usr/lib/games/%s" % (TMPDIR, BASENAME))
os.system("cp --recursive %s/direct %s/usr/share/games/%s/direct" % (PANDA, TMPDIR, BASENAME))
os.system("cp --recursive %s/pandac %s/usr/share/games/%s/pandac" % (PANDA, TMPDIR, BASENAME))
os.system("cp --recursive %s/models %s/usr/share/games/%s/models" % (PANDA, TMPDIR, BASENAME))
os.system("cp --recursive %s/Pmw %s/usr/share/games/%s/Pmw" % (PANDA, TMPDIR, BASENAME))
os.system("cp %s %s/usr/share/games/%s/LICENSE" % (LICENSE, TMPDIR, BASENAME))
os.system("cp --recursive /usr/lib/panda3d/* %s/usr/lib/games/%s/" % (TMPDIR, BASENAME))
# Make the script to run the game
txt = RUN_SCRIPT[1:].replace("BASENAME",BASENAME).replace("PYTHONV",PYTHONV).replace("MAIN",MAIN)
WriteFile(TMPDIR+"/usr/bin/"+BASENAME, txt)
os.system("chmod +x "+TMPDIR+"/usr/bin/"+BASENAME)
if (os.path.exists("/usr/bin/rpmbuild")):
os.system("rm -rf %s/DEBIAN" % TMPDIR)
os.system("rpm -E '%_target_cpu' > packpanda-TMP.txt")
ARCH=ReadFile("packpanda-TMP.txt").strip()
os.remove("packpanda-TMP.txt")
txt = INSTALLER_SPEC_FILE[1:].replace("VERSION",VER).replace("TMPDIR",TMPDIR)
txt = txt.replace("BASENAME",BASENAME).replace("NAME",NAME).replace("PYTHONV",PYTHONV)
WriteFile("packpanda-TMP.spec", txt)
os.system("rpmbuild --define '_rpmdir "+TMPDIR+"' -bb packpanda-TMP.spec")
os.system("mv "+ARCH+"/"+BASENAME+"-"+VER+"-1."+ARCH+".rpm .")
os.rmdir(ARCH)
os.remove("packpanda-TMP.spec")
if (os.path.exists("/usr/bin/dpkg-deb")):
os.system("dpkg --print-architecture > packpanda-TMP.txt")
ARCH=ReadFile("packpanda-TMP.txt").strip()
os.remove("packpanda-TMP.txt")
txt = INSTALLER_DEB_FILE[1:].replace("VERSION",str(VER)).replace("PYTHONV",PYTHONV)
txt = txt.replace("BASENAME",BASENAME).replace("NAME",NAME).replace("ARCH",ARCH)
os.system("mkdir -p %s/DEBIAN" % TMPDIR)
os.system("cd %s ; (find usr -type f -exec md5sum {} \;) > DEBIAN/md5sums" % TMPDIR)
WriteFile(TMPDIR+"/DEBIAN/control",txt)
os.system("dpkg-deb -b "+TMPDIR+" "+BASENAME+"_"+VER+"_"+ARCH+".deb")
if not(os.path.exists("/usr/bin/rpmbuild") or os.path.exists("/usr/bin/dpkg-deb")):
exit("To build an installer, either rpmbuild or dpkg-deb must be present on your system!")