pdeploy.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #! /usr/bin/env python
  2. usageText = """
  3. This command will help you to distribute your Panda application,
  4. consisting of a .p3d package, into a standalone executable, graphical
  5. installer or an HTML webpage. It will attempt to create packages
  6. for every platform, if possible.
  7. Note that pdeploy requires an internet connection to run.
  8. Usage:
  9. %(prog)s [opts] app.p3d standalone|installer|html
  10. Modes:
  11. standalone
  12. A standalone executable will be created that embeds the given
  13. p3d file. The resulting executable will require an
  14. internet connection in order to run properly.
  15. installer
  16. In this mode, installable packages will be created for as many
  17. platforms as possible. To create Windows installers on
  18. non-Windows platforms, you need to have the "makensis" utility
  19. on your system PATH environment variable.
  20. html
  21. An HTML webpage will be generated that can be used to view
  22. the provided p3d file in a browser.
  23. Options:
  24. -n your_app
  25. Short, lowercase name of the application or game. May only
  26. contain alphanumeric characters, underscore or dash. This
  27. name will also define the output file(s) of the process.
  28. If omitted, the basename of the p3d file is used.
  29. -N "Your Application"
  30. Full name of the application or game. This value will
  31. be used to display to the end-user.
  32. If omitted, the short name is used.
  33. -v version_number
  34. This should define the version number of your application
  35. or game. In some deploy modes, this argument is required.
  36. This should only contain alphanumeric characters, dots and
  37. dashes, as otherwise the result of the deployment may be
  38. invalid on some platforms.
  39. -o output_dir
  40. Indicates the directory where the output will be stored.
  41. Within this directory, subdirectories will be created
  42. for every platform, unless -t is provided.
  43. If omitted, the current working directory is assumed.
  44. -t token=value
  45. Defines a web token or parameter to pass to the application.
  46. Use this to configure how the application will be run.
  47. You can pass as many -t options as you need. Examples of
  48. tokens are width, height, log_basename, auto_start, hidden.
  49. -P platform
  50. If this option is provided, it should specify a comma-
  51. separated list of platforms that the p3d package will be
  52. deployed for. If omitted, it will be built for all platforms.
  53. This option may be specified multiple times.
  54. Examples of valid platforms are win32, linux_amd64 and osx_ppc.
  55. -c
  56. If this option is provided, any -P options are ignored and
  57. the p3d package is only deployed for the current platform.
  58. Furthermore, no per-platform subdirectories will be created
  59. inside the output dirctory.
  60. -s
  61. This option only has effect in 'installer' mode. If it is
  62. provided, the resulting installers will be fully self-contained,
  63. will not require an internet connection to run, and start up
  64. much faster. Note that pdeploy will also take a very long time
  65. to finish when -s is provided.
  66. If it is omitted, pdeploy will finish much quicker, and the
  67. resulting installers will be smaller, but they will require
  68. an internet connection for the first run, and the load time
  69. will be considerably longer.
  70. -l "License Name"
  71. Specifies the name of the software license that the game
  72. or application is licensed under.
  73. Only relevant when generating a graphical installer.
  74. -L licensefile.txt
  75. This should point to a file that contains the full text
  76. describing the software license that the game or application
  77. is licensed under.
  78. Only relevant when generating a graphical installer.
  79. -a com.your_company
  80. Short identifier of the author of the application. The default
  81. is "org.panda3d", but you will most likely want to change
  82. it to your own name or that of your organization or company.
  83. -A "Your Company"
  84. Full name of the author of the application.
  85. -h
  86. Display this help
  87. """
  88. DEPLOY_MODES = ["standalone", "installer", "html"]
  89. import sys
  90. import os
  91. import getopt
  92. from direct.p3d.DeploymentTools import Standalone, Installer
  93. from pandac.PandaModules import Filename, PandaSystem
  94. def usage(code, msg = ''):
  95. print >> sys.stderr, usageText % {'prog' : os.path.split(sys.argv[0])[1]}
  96. print >> sys.stderr, msg
  97. sys.exit(code)
  98. shortname = ""
  99. fullname = ""
  100. version = ""
  101. outputDir = Filename("./")
  102. tokens = {}
  103. platforms = []
  104. currentPlatform = False
  105. licensename = ""
  106. licensefile = Filename()
  107. authorid = ""
  108. authorname = ""
  109. includeRequires = False
  110. try:
  111. opts, args = getopt.getopt(sys.argv[1:], 'n:N:v:o:t:P:csl:L:a:A:h')
  112. except getopt.error, msg:
  113. usage(1, msg)
  114. for opt, arg in opts:
  115. if opt == '-n':
  116. shortname = arg.strip()
  117. elif opt == '-N':
  118. fullname = arg.strip()
  119. elif opt == '-v':
  120. version = arg.strip()
  121. elif opt == '-o':
  122. outputDir = Filename.fromOsSpecific(arg)
  123. elif opt == '-t':
  124. token = arg.strip().split("=", 1)
  125. tokens[token[0]] = token[1]
  126. elif opt == '-P':
  127. platforms.append(arg)
  128. elif opt == '-c':
  129. currentPlatform = True
  130. elif opt == '-s':
  131. includeRequires = True
  132. elif opt == '-l':
  133. licensename = arg.strip()
  134. elif opt == '-L':
  135. licensefile = Filename.fromOsSpecific(arg)
  136. elif opt == '-a':
  137. authorid = arg.strip()
  138. elif opt == '-A':
  139. authorname = arg.strip()
  140. elif opt == '-h':
  141. usage(0)
  142. else:
  143. print 'illegal option: ' + flag
  144. sys.exit(1)
  145. if not args or len(args) != 2:
  146. usage(1)
  147. appFilename = Filename.fromOsSpecific(args[0])
  148. if appFilename.getExtension().lower() != 'p3d':
  149. print 'Application filename must end in ".p3d".'
  150. sys.exit(1)
  151. deploy_mode = args[1].lower()
  152. if not appFilename.exists():
  153. print 'Application filename does not exist!'
  154. sys.exit(1)
  155. if shortname.lower() != shortname or ' ' in shortname:
  156. print '\nProvided short name should be lowercase, and may not contain spaces!\n'
  157. if shortname == '':
  158. shortname = appFilename.getBasenameWoExtension()
  159. if fullname == '':
  160. fullname = shortname
  161. if version == '' and deploy_mode == 'installer':
  162. print '\nA version number is required in "installer" mode.\n'
  163. sys.exit(1)
  164. if not outputDir:
  165. print '\nYou must name the output directory with the -o parameter.\n'
  166. sys.exit(1)
  167. if deploy_mode == 'standalone':
  168. s = Standalone(appFilename, tokens)
  169. s.basename = shortname
  170. if currentPlatform:
  171. platform = PandaSystem.getPlatform()
  172. if platform.startswith("win"):
  173. s.build(Filename(outputDir, shortname + ".exe"), platform)
  174. else:
  175. s.build(Filename(outputDir, shortname), platform)
  176. elif len(platforms) == 0:
  177. s.buildAll(outputDir)
  178. else:
  179. for platform in platforms:
  180. if platform.startswith("win"):
  181. s.build(Filename(outputDir, platform + "/" + shortname + ".exe"), platform)
  182. else:
  183. s.build(Filename(outputDir, platform + "/" + shortname), platform)
  184. elif deploy_mode == 'installer':
  185. i = Installer(shortname, fullname, appFilename, version, tokens = tokens)
  186. i.licensename = licensename
  187. i.licensefile = licensefile
  188. i.authorid = authorid
  189. i.authorname = authorname
  190. i.includeRequires = includeRequires
  191. if currentPlatform:
  192. platform = PandaSystem.getPlatform()
  193. if platform.startswith("win"):
  194. i.build(outputDir, platform)
  195. else:
  196. i.build(outputDir, platform)
  197. elif len(platforms) == 0:
  198. i.buildAll(outputDir)
  199. else:
  200. for platform in platforms:
  201. output = Filename(outputDir, platform + "/")
  202. output.makeDir()
  203. i.build(output, platform)
  204. elif deploy_mode == 'html':
  205. print "Creating %s.html..." % shortname
  206. html = open(shortname + ".html", "w")
  207. html.write("<html>\n")
  208. html.write(" <head>\n")
  209. html.write(" <title>%s</title>\n" % fullname)
  210. html.write(" </head>\n")
  211. html.write(" <body>\n")
  212. html.write(" <object data=\"%s\" type=\"application/x-panda3d\"></object>\n" % appFilename.getBasename())
  213. html.write(" </body>\n")
  214. html.write("</html>\n")
  215. html.close()
  216. else:
  217. usage(1, 'Invalid deployment mode!')
  218. # An explicit call to exit() is required to exit the program, when
  219. # this module is packaged in a p3d file.
  220. sys.exit(0)