OSDN Git Service

Refactor the build process to allow anyone to create binary distributions, portable...
authorJames Teh <jamie@jantrid.net>
Fri, 5 Nov 2010 03:01:35 +0000 (13:01 +1000)
committerJames Teh <jamie@jantrid.net>
Fri, 5 Nov 2010 03:01:35 +0000 (13:01 +1000)
scons is used to facilitate this. All builds should now be done using scons at the top level of the source distribution.
See the updated instructions towards the bottom of the source readme for details on how to use this.
Note that you can no longer build an installer directly by using makensis.

.bzrignore
installer/nvda.nsi
readme.txt
sconstruct [new file with mode: 0755]
source/setup.py
source/versionInfo.py

index ab5c467..5ce2c27 100644 (file)
@@ -40,3 +40,4 @@ source/include/*
 .sconsign.dblite\r
 user_docs/*/*.html\r
 extras/controllerClient/x64\r
+source/_buildVersion.py\r
index 10c14cc..f500fd1 100644 (file)
 ;Settings\r
 \r
 ;defines for product info and paths\r
-!define VERSION "unknown"\r
 !define PRODUCT "NVDA" ; Don't change this for no reason, other instructions depend on this constant\r
-!define PUBLISHER "unknown"\r
 !define WEBSITE "www.nvda-project.org"\r
 !define NVDAWindowClass "wxWindowClassNR"\r
 !define NVDAWindowTitle "NVDA"\r
 !define NVDAApp "nvda.exe"\r
 !define NVDATempDir "_nvda_temp_"\r
-!define NVDASourceDir "..\source\dist"\r
 !define SNDLogo "nvda_logo.wav"\r
 !define INSTDIR_REG_ROOT "HKLM"\r
 !define INSTDIR_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT}"\r
@@ -42,7 +39,6 @@ RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
 !define MUI_UNINSTALLER ;We want an uninstaller to be generated\r
 \r
 ;product branding\r
-OutFile "${PRODUCT}_${VERSION}.exe"\r
 InstallDir "$PROGRAMFILES\${PRODUCT}"\r
 InstallDirRegKey ${INSTDIR_REG_ROOT} "${INSTDIR_REG_KEY}" "InstallDir"\r
 Name "NVDA"\r
index d046f41..3533195 100644 (file)
@@ -67,6 +67,10 @@ To use the MDV Lilli braille display driver:
 \r
 To build a binary version of NVDA:\r
        * Py2Exe (for Python 2.7), version 0.6.9 or later: http://www.sourceforge.net/projects/py2exe/\r
+       * SCons, version 2.0.0 or later: http://www.scons.org/\r
+\r
+To build a portable archive:\r
+       * 7-Zip: http://www.7-zip.org/\r
 \r
 To build an installer:\r
        * Nulsoft Install System, version 2.42 or later: http://nsis.sourceforge.net/\r
@@ -80,15 +84,27 @@ You should do this again whenever the version of comtypes changes or new languag
 == Running the Source Code ==\r
 To start NVDA from source code, run nvda.pyw located in the source directory.\r
 \r
-== Building a Standalone Binary Version of NVDA ==\r
-You can use py2exe to make a binary build of NVDA which can be run on a system without Python and all of NVDA's other dependencies installed (as we do for snapshots and releases).\r
+== Building NVDA ==\r
+A binary build of NVDA can be run on a system without Python and all of NVDA's other dependencies installed (as we do for snapshots and releases).\r
+\r
+Binary archives and bundles can be created using scons from the root of the NVDA source distribution/checkout. To build any of the following, open a command prompt and change to this directory.\r
+\r
+To make a non-archived binary build (equivalent to an extracted portable archive), type:\r
+scons dist\r
+The build will be created in the dist directory.\r
+\r
+To create a portable archive, type:\r
+scons portable\r
+The archive will be placed in the current directory.\r
 \r
-Assuming py2exe is installed, open a command prompt, change to the NVDA source directory and type:\r
-setup.py py2exe\r
+To build an installer, type:\r
+scons installer\r
+The installer will be placed in the current directory.\r
 \r
-== Building an NVDA Installer ==\r
-To build an NVDA installer:\r
-       1. First build a standalone binary version as described in the previous section.\r
-       2. Using Windows Explorer, locate nvda.nsi in the installer directory.\r
-       3. Press the applications key and choose "Compile NSIS Script".\r
-The installer will be built and placed in the installer directory.\r
+Optionally, the build can  be customised by providing variables on the command line:\r
+       * version: The version of this build.\r
+       * isRelease: Whether this is a release version.\r
+       * publisher: The publisher of this build.\r
+       * certFile: The certificate file with which to sign executables.\r
+For example, to build an installer with a specific version, you might type:\r
+scons installer version=test1\r
diff --git a/sconstruct b/sconstruct
new file mode 100755 (executable)
index 0000000..d20f2de
--- /dev/null
@@ -0,0 +1,169 @@
+###\r
+#This file is a part of the NVDA project.\r
+#URL: http://www.nvda-project.org/\r
+#Copyright 2010 James Teh <jamie@jantrid.net>.\r
+#This program is free software: you can redistribute it and/or modify\r
+#it under the terms of the GNU General Public License version 2.0, as published by\r
+#the Free Software Foundation.\r
+#This program is distributed in the hope that it will be useful,\r
+#but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
+#This license can be found at:\r
+#http://www.gnu.org/licenses/old-licenses/gpl-2.0.html\r
+###\r
+\r
+import sys\r
+import os\r
+import _winreg\r
+\r
+# Import NVDA's versionInfo module.\r
+import gettext\r
+gettext.install("nvda", unicode=True)\r
+sys.path.append("source")\r
+import versionInfo\r
+del sys.path[-1]\r
+\r
+# Get the path to signtool.\r
+try:\r
+       with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Microsoft SDKs\Windows") as sdksKey:\r
+               signtool = os.path.join(_winreg.QueryValueEx(sdksKey, "CurrentInstallFolder")[0], "Bin", "signtool.exe")\r
+except WindowsError:\r
+       signtool = "signtool"\r
+\r
+# Get the path to 7z.\r
+try:\r
+       szKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\7-Zip", 0, _winreg.KEY_READ)\r
+except WindowsError:\r
+       try:\r
+               szKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\7-Zip", 0, _winreg.KEY_WOW64_64KEY | _winreg.KEY_READ)\r
+       except WindowsError:\r
+               szKey = None\r
+if szKey:\r
+       with szKey:\r
+               sz = os.path.join(_winreg.QueryValueEx(szKey, "Path")[0], "7z.exe")\r
+else:\r
+       sz = "7z"\r
+\r
+# Get the path to makensis.\r
+try:\r
+       with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\NSIS") as nsisKey:\r
+               makensis = os.path.join(_winreg.QueryValueEx(nsisKey, None)[0], "makensis.exe")\r
+except WindowsError:\r
+       makensis = "makensis"\r
+\r
+# Get the path to pygettext.\r
+pygettext = os.path.join(sys.exec_prefix, "Tools", "i18n", "pygettext.py")\r
+\r
+vars = Variables()\r
+vars.Add("version", "The version of this build", versionInfo.version)\r
+vars.Add(BoolVariable("isRelease", "Whether this is a release version", False))\r
+vars.Add("publisher", "The publisher of this build", "unknown")\r
+vars.Add(PathVariable("certFile", "The certificate file with which to sign executables", "",\r
+       lambda key, val, env: not val or PathVariable.PathIsFile(key, val, env)))\r
+\r
+env = Environment(variables=vars, tools=["textfile", "default"])\r
+version = env["version"]\r
+isRelease = env["isRelease"]\r
+certFile = env["certFile"]\r
+sourceDir = Dir("source")\r
+buildDir = Dir("build")\r
+outFilePrefix = "nvda{type}_{version}".format(type="" if isRelease else "_snapshot", version=version)\r
+\r
+# A builder to generate an NVDA distribution.\r
+def NVDADistGenerator(target, source, env, for_signature):\r
+       buildCmd = ["cd", source[0].path, "&&",\r
+               sys.executable]\r
+       if isRelease:\r
+               buildCmd.append("-O")\r
+       buildCmd.extend(("setup.py", "build", "--build-base", buildDir.abspath,\r
+               "py2exe", "--dist-dir", target[0].abspath))\r
+       if isRelease:\r
+               buildCmd.append("-O1")\r
+       action = [buildCmd]\r
+       if env.get("uiAccess"):\r
+               buildCmd.append("--enable-uiAccess")\r
+               for prog in "nvda", "nvda_slave", "nvda_service":\r
+                       action.append(signExec[:-1] + [target[0].File("%s.exe" % prog)])\r
+       return action\r
+env["BUILDERS"]["NVDADist"] = Builder(generator=NVDADistGenerator, source_scanner=DirScanner, target_factory=Dir)\r
+\r
+# A builder to generate a 7-Zip self-extracting archive.\r
+def SzSfxGenerator(target, source, env, for_signature):\r
+       cmd = []\r
+       relativeToSourceDir = env.get("relativeToSourceDir", False)\r
+       if relativeToSourceDir:\r
+               cmd.extend(("cd", source[0], "&&"))\r
+       cmd.extend((sz, "a", "-mx=9", "-sfx7z.sfx", target[0].abspath, "." if relativeToSourceDir else "$SOURCES"))\r
+       return [cmd]\r
+env["BUILDERS"]["SzSfx"] = Builder(generator=SzSfxGenerator)\r
+\r
+# An action to sign an executable with certFile.\r
+signExec = [signtool, "sign", "/f", certFile, "$TARGET"]\r
+\r
+# Make the NVDA build use the specified version.\r
+buildVersionFile = env.Textfile(sourceDir.File("_buildVersion.py"), ['version = "$version"'])\r
+env.Depends(sourceDir, buildVersionFile)\r
+\r
+portableDist = env.NVDADist("dist", sourceDir, uiAccess=False)\r
+if certFile:\r
+       # If uiAccess is to be enabled, it must only be enabled on the installer.\r
+       # Therefore, a separate distribution is needed.\r
+       installerDist = env.NVDADist("dist_installer", sourceDir, uiAccess=True)\r
+else:\r
+       installerDist = portableDist\r
+# portableDist and installerDist don't get rebuilt even if sourceDir changes, so force them to always be built.\r
+#env.AlwaysBuild(portableDist, installerDist)\r
+# Dir node targets don't get cleaned, so cleaning of the dist nodes has to be explicitly specified.\r
+env.Clean(portableDist, portableDist)\r
+env.Clean(installerDist, installerDist)\r
+# Clean the intermediate build directory.\r
+env.Clean([portableDist, installerDist], buildDir)\r
+\r
+portableArchive = env.SzSfx("%s_portable.exe" % outFilePrefix, portableDist, relativeToSourceDir=True)\r
+if certFile:\r
+       env.AddPostAction(portableArchive, [signExec])\r
+env.Alias("portable", portableArchive)\r
+\r
+installer = env.Command("%s_installer.exe" % outFilePrefix, ["installer/nvda.nsi", installerDist],\r
+       [[makensis, "/V2",\r
+       "/DVERSION=$version", "/DPUBLISHER=$publisher",\r
+       "/DNVDASourceDir=${SOURCES[1].abspath}", "/XOutFile ${TARGET.abspath}",\r
+       "$SOURCE"]])\r
+if certFile:\r
+       env.AddPostAction(installer, [signExec])\r
+env.Alias("installer", installer)\r
+\r
+nvdaHelperArchive = env.SzSfx("%s_nvdaHelper.exe" % outFilePrefix,\r
+       env.Glob(r"source\lib\[nV]*.dll") + env.Glob(r"source\lib64\[nV]*.[de][lx][le]"))\r
+env.Alias("nvdaHelperArchive", nvdaHelperArchive)\r
+\r
+def makePot(target, source, env):\r
+       # Generate the pot.\r
+       if env.Execute([["cd", source[0], "&&",\r
+                       pygettext, "-o", target[0].abspath, "*.py", r"*\*.py", r"*\*\*.py"]]) != 0:\r
+               raise RuntimeError("pygettext failed")\r
+\r
+       # Tweak the headers.\r
+       potFn = str(target[0])\r
+       tmpFn = "%s.tmp" % potFn\r
+       with file(potFn, "rt") as inp, file(tmpFn, "wt") as out:\r
+               for lineNum, line in enumerate(inp):\r
+                       if lineNum == 1:\r
+                               line = line.replace("YEAR ORGANIZATION", "2006-2010 NVDA Contributors")\r
+                       elif lineNum == 2:\r
+                               # Delete line.\r
+                               continue\r
+                       elif lineNum == 6:\r
+                               line = line.replace("PACKAGE VERSION", version)\r
+                       elif lineNum == 12:\r
+                               line = line.replace("CHARSET", "UTF-8")\r
+                       elif lineNum == 13:\r
+                               line = line.replace("ENCODING", "8bit")\r
+                       out.write(line)\r
+       os.remove(potFn)\r
+       os.rename(tmpFn, potFn)\r
+\r
+pot = env.Command("%s.pot" % outFilePrefix, sourceDir, makePot)\r
+env.Alias("pot", pot)\r
+\r
+env.Default(portableDist)\r
index 41f6724..14fd200 100755 (executable)
@@ -148,8 +148,8 @@ setup(
                (".",glob("*.dll")+glob("*.manifest")+["builtin.dic"]),\r
                ("documentation", ['../copying.txt', '../contributors.txt']),\r
                ("appModules", glob("appModules/*.kbd")),\r
-               ("lib", glob("lib/*")),\r
-               ("lib64", glob("lib64/*")),\r
+               ("lib", glob("lib/*.dll") + glob("lib/*.pdb")),\r
+               ("lib64", glob("lib64/*.dll") + glob("lib64/*.exe") + glob("lib64/*.pdb")),\r
                ("waves", glob("waves/*.wav")),\r
                ("images", glob("images/*.ico")),\r
                ("louis/tables",glob("louis/tables/*"))\r
index c84c49e..29f665b 100644 (file)
@@ -23,7 +23,7 @@ def _updateVersionFromVCS():
 \r
 name="NVDA"\r
 longName=_("NonVisual Desktop Access")\r
-version="2010.2"\r
+version="2011.1dev"\r
 description=_("A free and open-source screen reader for MS Windows")\r
 url="http://www.nvda-project.org/"\r
 copyright=_("Copyright (C) 2006-2010 NVDA Contributors")\r
@@ -33,6 +33,9 @@ For further details, you can view the licence online at:
 http://www.gnu.org/licenses/old-licenses/gpl-2.0.html\r
 Or see the file Copying.txt that came with this software.""")%globals()\r
 \r
-_updateVersionFromVCS()\r
+try:\r
+       from _buildVersion import version\r
+except ImportError:\r
+       _updateVersionFromVCS()\r
 # A test version is anything other than a final or rc release.\r
 isTestVersion = not version[0].isdigit() or "alpha" in version or "beta" in version\r