• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            buildpkg.py 的使用說明

            Posted on 2011-05-07 07:11 RTY 閱讀(892) 評論(0)  編輯 收藏 引用 所屬分類: PythonMac os

            源文件下載地址:http://python.net/~gherman/projects/buildpkg/

            當前記錄版本號為: 0.3

            Readme
            ############################################################################################################

            Readme
            buildpkg.py -- A Python tool to build OS X packages for Apple's Installer.app.
            Purpose
            This is a Python tool for building packages to be installed with the Mac OS X Installer.app application. It is much inspired by Apple's GUI tool called PackageMaker.app, which is part of the OS X developer tools installed in /Developer/Applications. There are other free GUI tools to do the same thing (1), (2). This tool has no GUI which is a feature and not a bug.
            Version
            The current version is 0.3.
            License
            The current license for this version is the "BSD License" as described by the Open Source Initiative (7).
            About Apples's Installer.app
            Apple has defined its own format for software packages to be installed on an OS X system. This format stems originally from the Mach/NeXTSTEP operating system of which OS X is a direct successor. The shape of such a package is basically a set of nested directories with the top-level one having the extension .pkg (or .mpkg). It contains one archive compressed with "pax", plus a set of further files describing the package content, plus additional optional scripts to be run during installation. Unfortunately, Apple does not fully document all features of its Installer or announces changes in the package layout.
            Features of buildpkg.py
            The essential work performed by buildpkg.py for a new package named <PACKAGE> is to:
            - create a package directory <PACKAGE>.pkg/ plus its entire layout (subdirectories)
            - add a file <PACKAGE>.pkg/<PACKAGE>.info containing the installation options
            - add "bill of materials" file <PACKAGE>.pkg/<PACKAGE>.bom (using "mkbom")
            - add the source root directory as <PACKAGE>.pkg/<PACKAGE>.pax.gz
            - add optional resources to <PACKAGE>.pkg/Contents/Resources
            - add a file <PACKAGE>.pkg/<PACKAGE>.sizes indicating the total size of the installed package
            Among the optional resource files there are the Welcome, ReadMe and License files (either in .txt, .rtf, .rtfd/ or .html format) shown during installation. These can also be inside localization bundles, like English.lproj/ or German.lproj/). Other resources will mostly be installation scripts (e.g. preflight, <PACKAGE>.{pre,post}-{upgrade,install}, postflight, and probably others as well) called by the installer at the appropriate moment.
            buildpkg.py does not try to be smart enough to filter only the relevant files from the resources you indicate. It simply copies them into the package.
            Command-line usage
            The intended use of the buildpkg.py script is both, as a command-line tool and as a Python module which can be imported in other Python programs (with "distutils" being the most obvious Python candidate package).
            - Call the program without any options/arguments
            darwin% python buildpkg.py
            No argument given!
            Usage: buildpkg.py <opts1> [<opts2>] <root> [<resources>]
            with arguments:
            (mandatory) root:         the package root folder
            (optional)  resources:    the package resources folder
            and options:
            (mandatory) opts1:
            --Title
            --Version
            --Description
            (optional) opts2: (with default values)
            --Application:        'NO'
            --DefaultLocation:    '/'
            --DeleteWarning:      ''
            --DisableStop:        'NO'
            --Diskname:           '(null)'
            --InstallFat:         'NO'
            --InstallOnly:        'NO'
            --NeedsAuthorization: 'NO'
            --Relocatable:        'YES'
            --Required:           'NO'
            --RequiresReboot:     'NO'
            --UseUserMask:        'YES'
            - Call the program with only the mandatory options and arguments
            darwin% python buildpkg.py --Title=readline-4.3 --Version=4.3\
            --Description="GNU Readline Library" /my/space/readline-4.3
            - As above but with additional option --RequiresReboot YES
            darwin% python buildpkg.py --Title=readline-4.3 --Version=4.3\
            --Description="GNU Readline Library" --RequiresReboot YES\
            /my/space/readline-4.3
            - As above but with additional resources directory argument (will copy its content into /my/space/readline-4.3/pkg/Contents/Resources/)
            darwin% python buildpkg.py --Title=readline-4.3 --Version=4.3\
            --Description="GNU Readline Library" --RequiresReboot YES\
            /my/space/readline-4.3 /my/space/resources/readline/
            Usage as a Python module
            - Create a readline-4.3.pkg from a folder containing the GNU Readline library sources:
            pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library")
            pm.build("/my/space/readline-4.3")
            - As above but with additional option --RequiresReboot YES
            pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library")
            pm.build("/my/space/readline-4.3", RequiresReboot="YES")
            - As above but with additional resources directory argument (will copy its content into /my/space/readline-4.3/pkg/Contents/Resources/)
            pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library")
            pm.build("/my/space/readline-4.3", "/my/space/resources/readline/")
            - As above but with additional single resource file
            pm = PackageMaker("readline-4.3", "4.3", "GNU Readline Library")
            pm.build("/my/space/readline-4.3", "/my/space/resources/readline/")
            pm.addResource("/my/space/resources/scripts/postflight")
            Notes
            Although the package layout is adopted from pre-10.2 versions of OS X, the Installer.app on 10.2 should have no problems in dealing with the resulting packages. For the time being this layout seems sufficient enough, so there is no point in dealing with creating packages that can be installed only by the new Installer.app!
            Given that such packages have a directory "shape", they are not suited for downloading over the internet. Hence, they need to be flattened somehow into a single binary file. This could be a .tar.gz, which is possible but unusual on OS X (for reasons not described here). On OS X there is a dedicated format named "Disk Image" with extension .dmg which represents an archive that can be directly mounted into the filesystem. Creating such disk images without GUI tools is somewhat of a black art (6).
            For now you should be able to run buildpkg.py even on a non-OS X system and get something similar to a package, but without the real archive (needs pax) and bom files (needs mkbom) inside! This is only for providing a chance for testing to folks without OS X.
            Beware of the multi-package features of Installer.app (which are not yet supported here) that can potentially screw-up your installation and are discussed in two articles on Stepwise (4). At least for versions of OS X prior to 10.2 this seemed to be a concern.
            Todo
            - test pre-process and post-process scripts
            - handle meta-packages (extension .mpkg)
            - integrate into distutils
            - use alternatives for "pax" (2)
            Links
            (1) Brian Hill's PackageMaker:
            http://personalpages.tds.net/~brian_hill/packagemaker.html
            (2) Chris Roberts's OSXPM:
            http://www.osxgnu.org/
            (3) BSD License:
            http://opensource.org/licenses/bsd-license.php
            (4) Stepwise articles:
            http://www.stepwise.com/Articles/Technical/Packages/InstallerWoes.html
            http://www.stepwise.com/Articles/Technical/Packages/InstallerOnX.html
            (5) http://developer.apple.com/techpubs/macosx/Essentials/SystemOverview/InstallIntegrate/Installing__Application.html
            http://developer.apple.com/techpubs/macosx/ReleaseNotes/PackageMaker.html
            (6) Andrew Stone's notes on creating disk images:
            http://www.stone.com/The_Cocoa_Files/Just_Ship_it_.html
            (7) Open Source Initiative, BSD License:
            http://opensource.org/licenses/bsd-license.php
            Dinu C. Gherman,
            gherman@europemail.com
            September 2002
            
             
             
             
            src
            #####################################################################################################################
              1#!/usr/bin/env python
              2
              3"""buildpkg.py -- Build OS X packages for Apple's Installer.app.
              4
              5This is an experimental command-line tool for building packages to be
              6installed with the Mac OS X Installer.app application. 
              7
              8Please read the file ReadMe.txt for more information!
              9
             10Dinu C. Gherman, 
             11gherman@europemail.com
             12September 2002
             13
             14!! USE AT YOUR OWN RISK !!
             15"""
             16
             17__version__ = 0.3
             18__license__ = "FreeBSD"
             19
             20
             21import os, sys, glob, fnmatch, shutil, string, copy, getopt
             22from os.path import basename, dirname, join, islink, isdir, isfile
             23
             24Error = "buildpkg.Error"
             25
             26PKG_INFO_FIELDS = """\
             27Title
             28Version
             29Description
             30DefaultLocation
             31Diskname
             32DeleteWarning
             33NeedsAuthorization
             34DisableStop
             35UseUserMask
             36Application
             37Relocatable
             38Required
             39InstallOnly
             40RequiresReboot
             41InstallFat\
             42"""
             43
             44######################################################################
             45# Helpers
             46######################################################################
             47
             48# Convenience class, as suggested by /F.
             49
             50class GlobDirectoryWalker:
             51    "A forward iterator that traverses files in a directory tree."
             52
             53    def __init__(self, directory, pattern="*"):
             54        self.stack = [directory]
             55        self.pattern = pattern
             56        self.files = []
             57        self.index = 0
             58
             59
             60    def __getitem__(self, index):
             61        while 1:
             62            try:
             63                file = self.files[self.index]
             64                self.index = self.index + 1
             65            except IndexError:
             66                # pop next directory from stack
             67                self.directory = self.stack.pop()
             68                self.files = os.listdir(self.directory)
             69                self.index = 0
             70            else:
             71                # got a filename
             72                fullname = join(self.directory, file)
             73                if isdir(fullname) and not islink(fullname):
             74                    self.stack.append(fullname)
             75                if fnmatch.fnmatch(file, self.pattern):
             76                    return fullname
             77
             78
             79######################################################################
             80# The real thing
             81######################################################################
             82
             83class PackageMaker:
             84    """A class to generate packages for Mac OS X.
             85
             86    This is intended to create OS X packages (with extension .pkg)
             87    containing archives of arbitrary files that the Installer.app 
             88    (Apple's OS X installer) will be able to handle.
             89
             90    As of now, PackageMaker instances need to be created with the 
             91    title, version and description of the package to be built. 
             92    
             93    The package is built after calling the instance method 
             94    build(root, resources, **options). The generated package is 
             95    a folder hierarchy with the top-level folder name equal to the 
             96    constructor's title argument plus a '.pkg' extension. This final
             97    package is stored in the current folder.
             98    
             99    The sources from the root folder will be stored in the package
            100    as a compressed archive, while all files and folders from the
            101    resources folder will be added to the package as they are.
            102
            103    Example:
            104    
            105    With /my/space being the current directory, the following will
            106    create /my/space/distutils-1.0.2.pkg/:
            107
            108      PM = PackageMaker
            109      pm = PM("distutils-1.0.2", "1.0.2", "Python distutils.")
            110      pm.build("/my/space/sources/distutils-1.0.2")
            111      
            112    After a package is built you can still add further individual
            113    resource files or folders to its Contents/Resources subfolder
            114    by using the addResource(path) method: 
            115
            116      pm.addResource("/my/space/metainfo/distutils/")
            117    """
            118
            119    packageInfoDefaults = {
            120        'Title': None,
            121        'Version': None,
            122        'Description''',
            123        'DefaultLocation''/',
            124        'Diskname''(null)',
            125        'DeleteWarning''',
            126        'NeedsAuthorization''NO',
            127        'DisableStop''NO',
            128        'UseUserMask''YES',
            129        'Application''NO',
            130        'Relocatable''YES',
            131        'Required''NO',
            132        'InstallOnly''NO',
            133        'RequiresReboot''NO',
            134        'InstallFat''NO'}
            135
            136
            137    def __init__(self, title, version, desc):
            138        "Init. with mandatory title/version/description arguments."
            139
            140        info = {"Title": title, "Version": version, "Description": desc}
            141        self.packageInfo = copy.deepcopy(self.packageInfoDefaults)
            142        self.packageInfo.update(info)
            143        
            144        # variables set later
            145        self.packageRootFolder = None
            146        self.packageResourceFolder = None
            147        self.sourceFolder = None
            148        self.resourceFolder = None
            149
            150
            151    def _escapeBlanks(self, s):
            152        "Return a string with escaped blanks."
            153        
            154        return s.replace(' ''')
            155                
            156
            157    def build(self, root, resources=None, **options):
            158        """Create a package for some given root folder.
            159
            160        With no 'resources' argument set it is assumed to be the same 
            161        as the root directory. Option items replace the default ones 
            162        in the package info.
            163        """
            164
            165        # set folder attributes
            166        self.sourceFolder = root
            167        if resources == None:
            168            self.resourceFolder = None
            169        else:
            170            self.resourceFolder = resources
            171
            172        # replace default option settings with user ones if provided
            173        fields = self. packageInfoDefaults.keys()
            174        for k, v in options.items():
            175            if k in fields:
            176                self.packageInfo[k] = v
            177            elif not k in ["OutputDir"]:
            178                raise Error, "Unknown package option: %s" % k
            179        
            180        # Check where we should leave the output. Default is current directory
            181        outputdir = options.get("OutputDir", os.getcwd())
            182        packageName = self.packageInfo["Title"]
            183        self.packageRootFolder = os.path.join(outputdir, packageName + ".pkg")
            184 
            185        # do what needs to be done
            186        self._makeFolders()
            187        self._addInfo()
            188        self._addBom()
            189        self._addArchive()
            190        self._addResources()
            191        self._addSizes()
            192
            193
            194    def addResource(self, path):
            195        "Add arbitrary file or folder to the package resource folder."
            196        
            197        # Folder basenames become subfolders of Contents/Resources.
            198        # This method is made public for those who wknow what they do!
            199   
            200        prf = self.packageResourceFolder
            201        if isfile(path) and not isdir(path):
            202            shutil.copy(path, prf)
            203        elif isdir(path):
            204            path = self._escapeBlanks(path)
            205            prf = self._escapeBlanks(prf)
            206            os.system("cp -r %s %s" % (path, prf))
            207        
            208
            209    def _makeFolders(self):
            210        "Create package folder structure."
            211
            212        # Not sure if the package name should contain the version or not
            213        # packageName = "%s-%s" % (self.packageInfo["Title"], 
            214        #                          self.packageInfo["Version"]) # ??
            215
            216        contFolder = join(self.packageRootFolder, "Contents")
            217        self.packageResourceFolder = join(contFolder, "Resources")
            218        os.mkdir(self.packageRootFolder)
            219        os.mkdir(contFolder)
            220        os.mkdir(self.packageResourceFolder)
            221
            222
            223    def _addInfo(self):
            224        "Write .info file containing installing options."
            225
            226        # Not sure if options in PKG_INFO_FIELDS are complete
            227
            228        info = ""
            229        for f in string.split(PKG_INFO_FIELDS, "\n"):
            230            info = info + "%s %%(%s)s\n" % (f, f)
            231        info = info % self.packageInfo
            232        base = self.packageInfo["Title"+ ".info"
            233        path = join(self.packageResourceFolder, base)
            234        f = open(path, "w")
            235        f.write(info)
            236
            237
            238    def _addBom(self):
            239        "Write .bom file containing 'Bill of Materials'."
            240
            241        # Currently ignores if the 'mkbom' tool is not available.
            242
            243        try:
            244            base = self.packageInfo["Title"+ ".bom"
            245            bomPath = join(self.packageResourceFolder, base)
            246            bomPath = self._escapeBlanks(bomPath)
            247            sourceFolder = self._escapeBlanks(self.sourceFolder)
            248            cmd = "mkbom %s %s" % (sourceFolder, bomPath)
            249            res = os.system(cmd)
            250        except:
            251            pass
            252
            253
            254    def _addArchive(self):
            255        "Write .pax.gz file, a compressed archive using pax/gzip."
            256
            257        # Currently ignores if the 'pax' tool is not available.
            258
            259        cwd = os.getcwd()
            260
            261        # create archive
            262        os.chdir(self.sourceFolder)
            263        base = basename(self.packageInfo["Title"]) + ".pax"
            264        self.archPath = join(self.packageResourceFolder, base)
            265        archPath = self._escapeBlanks(self.archPath)
            266        cmd = "pax -w -f %s %s" % (archPath, ".")
            267        res = os.system(cmd)
            268        
            269        # compress archive
            270        cmd = "gzip %s" % archPath
            271        res = os.system(cmd)
            272        os.chdir(cwd)
            273
            274
            275    def _addResources(self):
            276        "Add all files and folders inside a resources folder to the package."
            277
            278        # This folder normally contains Welcome/ReadMe/License files, 
            279        # .lproj folders and scripts.
            280
            281        if not self.resourceFolder:
            282            return
            283
            284        files = glob.glob("%s/*" % self.resourceFolder)
            285        for f in files:
            286            self.addResource(f)
            287        
            288
            289    def _addSizes(self):
            290        "Write .sizes file with info about number and size of files."
            291
            292        # Not sure if this is correct, but 'installedSize' and 
            293        # 'zippedSize' are now in Bytes. Maybe blocks are needed? 
            294        # Well, Installer.app doesn't seem to care anyway, saying 
            295        # the installation needs 100+ MB
            296
            297        numFiles = 0
            298        installedSize = 0
            299        zippedSize = 0
            300
            301        files = GlobDirectoryWalker(self.sourceFolder)
            302        for f in files:
            303            numFiles = numFiles + 1
            304            installedSize = installedSize + os.lstat(f)[6]
            305
            306        try:
            307            zippedSize = os.stat(self.archPath+ ".gz")[6]
            308        except OSError: # ignore error 
            309            pass
            310        base = self.packageInfo["Title"+ ".sizes"
            311        f = open(join(self.packageResourceFolder, base), "w")
            312        format = "NumFiles %d\nInstalledSize %d\nCompressedSize %d\n"
            313        f.write(format % (numFiles, installedSize, zippedSize))
            314
            315
            316# Shortcut function interface
            317
            318def buildPackage(*args, **options):
            319    "A shortcut function for building a package."
            320    
            321    o = options
            322    title, version, desc = o["Title"], o["Version"], o["Description"]
            323    pm = PackageMaker(title, version, desc)
            324    apply(pm.build, list(args), options)
            325
            326    return pm
            327
            328
            329######################################################################
            330# Command-line interface
            331######################################################################
            332
            333def printUsage():
            334    "Print usage message."
            335
            336    format = "Usage: %s <opts1> [<opts2>] <root> [<resources>]"
            337    print format % basename(sys.argv[0])
            338    print
            339    print "       with arguments:"
            340    print "           (mandatory) root:         the package root folder"
            341    print "           (optional)  resources:    the package resources folder"
            342    print
            343    print "       and options:"
            344    print "           (mandatory) opts1:"
            345    mandatoryKeys = string.split("Title Version Description"" ")
            346    for k in mandatoryKeys:
            347        print "               --%s" % k
            348    print "           (optional) opts2: (with default values)"
            349
            350    pmDefaults = PackageMaker.packageInfoDefaults
            351    optionalKeys = pmDefaults.keys()
            352    for k in mandatoryKeys:
            353        optionalKeys.remove(k)
            354    optionalKeys.sort()
            355    maxKeyLen = max(map(len, optionalKeys))
            356    for k in optionalKeys:
            357        format = "               --%%s:%s %%s"
            358        format = format % (" " * (maxKeyLen-len(k)))
            359        print format % (k, repr(pmDefaults[k]))
            360
            361
            362def main():
            363    "Command-line interface."
            364
            365    shortOpts = ""
            366    keys = PackageMaker.packageInfoDefaults.keys()
            367    longOpts = map(lambda k: k+"=", keys)
            368
            369    try:
            370        opts, args = getopt.getopt(sys.argv[1:], shortOpts, longOpts)
            371    except getopt.GetoptError, details:
            372        print details
            373        printUsage()
            374        return
            375
            376    optsDict = {}
            377    for k, v in opts:
            378        optsDict[k[2:]] = v
            379
            380    ok = optsDict.keys()
            381    if not (1 <= len(args) <= 2):
            382        print "No argument given!"
            383    elif not ("Title" in ok and \
            384              "Version" in ok and \
            385              "Description" in ok):
            386        print "Missing mandatory option!"
            387    else:
            388        pm = apply(buildPackage, args, optsDict)
            389        return
            390
            391    printUsage()
            392
            393    # sample use:
            394    # buildpkg.py --Title=distutils \
            395    #             --Version=1.0.2 \
            396    #             --Description="Python distutils package." \
            397    #             /Users/dinu/Desktop/distutils
            398
            399
            400if __name__ == "__main__":
            401    main()
            402
            #################################################################################################################
             
            
            自述
            buildpkg.py - Python的工具來構建一個蘋果的installer.app安裝OS X軟件包。
            目的
            這是一個Python的工具包的建設要與installer.app安裝Mac OS X的應用程序安裝。這是許多靈感來自蘋果的圖形用戶界面稱為PackageMaker.app工具,它是OS X的開發商/開發/應用安裝工具的一部分。還有其他一些免費的GUI工具做同樣的事(1),(2)。這個工具沒有GUI這是一個特色,而不是一個錯誤。
            版本
            當前版本是0.3。
            許可證
            此版本目前的授權是“BSD許可證”由開放源碼促進會(7)中所述。
            關于蘋果的installer.app安裝
            蘋果公司已經確定了它自己的格式的軟件程序包將在OS X系統安裝。源于這種格式最初是從馬赫/ NeXTSTEP的操作系統OS X是其中一個直接的繼任者。這種一包的形狀基本上是與高層有一個嵌套目錄的擴展集。封裝(或。的MPKG)。它包含一個存檔與“百富”,再加上進一步說明包內容的文件,以及其他可選腳本在安裝過程中運行壓縮。不幸的是,蘋果并沒有全面記錄其所有的功能或宣布安裝包中的布局變化。
            特點buildpkg.py
            由buildpkg.py的重要工作進行名為<PACKAGE>一個新的包是:
            - 創建一個包目錄<PACKAGE>封裝/加上其整個布局(子目錄)。
            - 添加文件<PACKAGE>封裝/ <PACKAGE>信息包含安裝選項。。
            - 增加了“材料清單”文件<PACKAGE>封裝/ <PACKAGE>的BOM(用“mkbom”)。。
            - 添加為<PACKAGE>封裝/ <PACKAGE>源根目錄pax.gz。。
            - 添加可選的資源<PACKAGE> .pkg /目錄/資源
            - 添加文件<PACKAGE>封裝/ <PACKAGE>大小顯示已安裝的包的總大小。。
            其中可選的資源文件有歡迎,自述文件和許可證文件(無論是在的。txt,。RTF格式。rtfd /或。HTML格式)在安裝過程中顯示。這些也可以包內的定位,如English.lproj /或German.lproj /)。其他資源將主要是安裝腳本(比如預檢,<PACKAGE> {前,后} - 。{升級,安裝},飛行后,或許其他人也如此)由安裝在適當的時候調用。
            buildpkg.py不自作聰明足夠的過濾器只從你指定的資源相關的文件。它簡單地復制到它們打包。
            命令行用法
            該buildpkg.py腳本的用途是兩個,作為一個命令行工具,作為一個Python模塊,它可以導入其他Python程序(用“的distutils”是最明顯的候選人的Python包)。
            - 呼叫不帶任何選項/參數的程序
            達爾文%的Python buildpkg.py
            沒有參數??給出!
            用法:buildpkg.py <opts1> [<opts2>] <根目錄[<resources>]
            帶參數:
            (強制)的根:包根文件夾
            (可選)資源:軟件包資源文件夾
            和選項:
            (強制)opts1:
            - 標題
            - 版本
            - 描述
            (可選)opts2:(使用默認值)
            - 應用:'沒有'
            - DefaultLocation:'/'
            - DeleteWarning:''
            - DisableStop:'沒有'
            - Diskname:'(空)'
            - InstallFat:'沒有'
            - InstallOnly:'沒有'
            - NeedsAuthorization:'沒有'
            - 重新定位:'是'
            - 必需的:'沒有'
            - RequiresReboot:'沒有'
            - UseUserMask:'是'
            - 呼叫,只有強制性的選項和參數的程序
            達爾文%的Python buildpkg.py - 標題= readline的- 4.3 - 版本= 4.3 \
            - 描述=“GNU的readline庫”/ my/space/readline-4.3
            - 同上,但有更多的選擇 - RequiresReboot是的
            達爾文%的Python buildpkg.py - 標題= readline的- 4.3 - 版本= 4.3 \
            - 描述=“GNU的readline庫” - RequiresReboot是\
            / my/space/readline-4.3
            - 同上,但更多的資源目錄參數(將復制到/ my/space/readline-4.3/pkg/Contents/Resources其內容/)
            達爾文%的Python buildpkg.py - 標題= readline的- 4.3 - 版本= 4.3 \
            - 描述=“GNU的readline庫” - RequiresReboot是\
            / my/space/readline-4.3 /我/空間/資源/ readline的/
            作為一個Python模塊的使用情況
            - 創建的ReadLine從一個包含GNU readline庫源文件夾4.3.pkg:
            下午= PackageMaker(“readline的- 4.3”,“4.3”,“GNU的readline庫”)
            pm.build(“/ my/space/readline-4.3”)
            - 同上,但有更多的選擇 - RequiresReboot是的
            下午= PackageMaker(“readline的- 4.3”,“4.3”,“GNU的readline庫”)
            pm.build(“/ my/space/readline-4.3”,RequiresReboot =“是”)
            - 同上,但更多的資源目錄參數(將復制到/ my/space/readline-4.3/pkg/Contents/Resources其內容/)
            下午= PackageMaker(“readline的- 4.3”,“4.3”,“GNU的readline庫”)
            pm.build(“/ my/space/readline-4.3”,“/我/空間/資源/ readline的/”)
            - 同上,但與其他單一的資源文件
            下午= PackageMaker(“readline的- 4.3”,“4.3”,“GNU的readline庫”)
            pm.build(“/ my/space/readline-4.3”,“/我/空間/資源/ readline的/”)
            pm.addResource(“/我/空間/資源/腳本/飛行后”)
            注釋
            雖然包布局從前期的OS X版本10.2通過,應該在10.2 installer.app安裝在與由此產生的包處理沒有問題。就目前這個時間似乎足以布局,所以沒有與創造,可以安裝新的installer.app安裝只包處理點!
            由于這些包有一個目錄“形”,他們是不適合在互聯網上下載。因此,他們需要縮減到一個單一的二進制文件不知。這可能是一個。tar.gz的,這是可能的,但在OS X上不尋常的(這里沒有說明原因)。在OS X上有一個專門的格式,擴展名為“磁盤圖像”。傷害它代表一個可直接安裝到文件系統歸檔。沒有GUI工具,例如創建磁盤映像是有點黑色藝術(6)。
            現在你應該能夠運行buildpkg.py即使在非OS X系統,并得到類似的一包,但沒有真正的存檔(需求人數)和BOM文件(需要mkbom)里面!這只是提供OS X的測試沒有機會到民間的
            慎防installer.app安裝多包的功能(這是目前還不支持在這里),可以潛在螺桿式安裝,并在兩個逐步(4)文章中討論。在對OS X版本10.2之前至少這似乎是一個問題。
            托多
            - 測試預處理和后處理的腳本
            - 處理元包(擴展名的MPKG。)
            - 融入的distutils
            - 使用“百富”(2)替代品
            鏈接
            (1)布萊恩希爾的PackageMaker:
            http://personalpages.tds.net/?brian_hill / packagemaker.html
            (2)的克里斯羅伯茨OSXPM:
            http://www.osxgnu.org/
            (3)的BSD許可:
            http://opensource.org/licenses/bsd-license.php
            (4)逐步文章:
            http://www.stepwise.com/Articles/Technical/Packages/InstallerWoes.html
            http://www.stepwise.com/Articles/Technical/Packages/InstallerOnX.html
            (5)http://developer.apple.com/techpubs/macosx/Essentials/SystemOverview/InstallIntegrate/Installing__Application.html
            http://developer.apple.com/techpubs/macosx/ReleaseNotes/PackageMaker.html
            (6)創建磁盤映像安德魯斯通的注意事項:
            http://www.stone.com/The_Cocoa_Files/Just_Ship_it_.html
            (7)開源倡議,BSD許可證:
            http://opensource.org/licenses/bsd-license.php
            Dinu三蓋爾曼,
            gherman@europemail.com
            2002年9月
            
            欧美日韩久久中文字幕| 国产精品一久久香蕉产线看| 曰曰摸天天摸人人看久久久| 韩国免费A级毛片久久| 狠狠色噜噜狠狠狠狠狠色综合久久| 久久综合九色综合97_久久久| 久久91综合国产91久久精品| 久久久WWW免费人成精品| 思思久久99热只有频精品66| 亚洲AV日韩精品久久久久久 | 青青青国产精品国产精品久久久久 | 亚洲色欲久久久综合网| 欧美黑人又粗又大久久久| 久久久久久久99精品免费观看| 久久国产乱子伦精品免费午夜| 亚洲国产成人久久精品99| 97久久久久人妻精品专区 | 欧美性猛交xxxx免费看久久久| 久久久久久精品久久久久| 久久精品成人免费网站| 日韩人妻无码精品久久久不卡| 久久一本综合| 91久久精品国产91性色也| 久久综合精品国产二区无码| 少妇久久久久久被弄到高潮 | 93精91精品国产综合久久香蕉 | 无码人妻久久久一区二区三区 | 久久精品国产亚洲av高清漫画| 久久久久久国产a免费观看不卡 | 99精品久久精品一区二区| 免费一级做a爰片久久毛片潮| 国产精品久久久久久| 18岁日韩内射颜射午夜久久成人| 蜜桃麻豆www久久国产精品| 久久免费观看视频| 久久亚洲国产精品123区| 久久精品国产亚洲7777| 久久99精品久久久久久水蜜桃| 伊人久久综合热线大杳蕉下载| 国内精品久久久久久99| 97久久精品人妻人人搡人人玩|