You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
6.2 KiB

6 years ago
  1. """SCons.Tool.Packaging.ipk
  2. """
  3. #
  4. # Copyright (c) 2001 - 2017 The SCons Foundation
  5. #
  6. # Permission is hereby granted, free of charge, to any person obtaining
  7. # a copy of this software and associated documentation files (the
  8. # "Software"), to deal in the Software without restriction, including
  9. # without limitation the rights to use, copy, modify, merge, publish,
  10. # distribute, sublicense, and/or sell copies of the Software, and to
  11. # permit persons to whom the Software is furnished to do so, subject to
  12. # the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included
  15. # in all copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
  18. # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  19. # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  21. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  22. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  23. # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. #
  25. __revision__ = "src/engine/SCons/Tool/packaging/ipk.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
  26. import SCons.Builder
  27. import SCons.Node.FS
  28. import os
  29. from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
  30. def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION,
  31. SUMMARY, X_IPK_PRIORITY, X_IPK_SECTION, SOURCE_URL,
  32. X_IPK_MAINTAINER, X_IPK_DEPENDS, **kw):
  33. """ This function prepares the packageroot directory for packaging with the
  34. ipkg builder.
  35. """
  36. SCons.Tool.Tool('ipkg').generate(env)
  37. # setup the Ipkg builder
  38. bld = env['BUILDERS']['Ipkg']
  39. target, source = stripinstallbuilder(target, source, env)
  40. target, source = putintopackageroot(target, source, env, PACKAGEROOT)
  41. # This should be overrideable from the construction environment,
  42. # which it is by using ARCHITECTURE=.
  43. # Guessing based on what os.uname() returns at least allows it
  44. # to work for both i386 and x86_64 Linux systems.
  45. archmap = {
  46. 'i686' : 'i386',
  47. 'i586' : 'i386',
  48. 'i486' : 'i386',
  49. }
  50. buildarchitecture = os.uname()[4]
  51. buildarchitecture = archmap.get(buildarchitecture, buildarchitecture)
  52. if 'ARCHITECTURE' in kw:
  53. buildarchitecture = kw['ARCHITECTURE']
  54. # setup the kw to contain the mandatory arguments to this function.
  55. # do this before calling any builder or setup function
  56. loc=locals()
  57. del loc['kw']
  58. kw.update(loc)
  59. del kw['source'], kw['target'], kw['env']
  60. # generate the specfile
  61. specfile = gen_ipk_dir(PACKAGEROOT, source, env, kw)
  62. # override the default target.
  63. if str(target[0])=="%s-%s"%(NAME, VERSION):
  64. target=[ "%s_%s_%s.ipk"%(NAME, VERSION, buildarchitecture) ]
  65. # now apply the Ipkg builder
  66. return bld(env, target, specfile, **kw)
  67. def gen_ipk_dir(proot, source, env, kw):
  68. # make sure the packageroot is a Dir object.
  69. if SCons.Util.is_String(proot): proot=env.Dir(proot)
  70. # create the specfile builder
  71. s_bld=SCons.Builder.Builder(
  72. action = build_specfiles,
  73. )
  74. # create the specfile targets
  75. spec_target=[]
  76. control=proot.Dir('CONTROL')
  77. spec_target.append(control.File('control'))
  78. spec_target.append(control.File('conffiles'))
  79. spec_target.append(control.File('postrm'))
  80. spec_target.append(control.File('prerm'))
  81. spec_target.append(control.File('postinst'))
  82. spec_target.append(control.File('preinst'))
  83. # apply the builder to the specfile targets
  84. s_bld(env, spec_target, source, **kw)
  85. # the packageroot directory does now contain the specfiles.
  86. return proot
  87. def build_specfiles(source, target, env):
  88. """ Filter the targets for the needed files and use the variables in env
  89. to create the specfile.
  90. """
  91. #
  92. # At first we care for the CONTROL/control file, which is the main file for ipk.
  93. #
  94. # For this we need to open multiple files in random order, so we store into
  95. # a dict so they can be easily accessed.
  96. #
  97. #
  98. opened_files={}
  99. def open_file(needle, haystack):
  100. try:
  101. return opened_files[needle]
  102. except KeyError:
  103. file=filter(lambda x: x.get_path().rfind(needle)!=-1, haystack)[0]
  104. opened_files[needle]=open(file.get_abspath(), 'w')
  105. return opened_files[needle]
  106. control_file=open_file('control', target)
  107. if 'X_IPK_DESCRIPTION' not in env:
  108. env['X_IPK_DESCRIPTION']="%s\n %s"%(env['SUMMARY'],
  109. env['DESCRIPTION'].replace('\n', '\n '))
  110. content = """
  111. Package: $NAME
  112. Version: $VERSION
  113. Priority: $X_IPK_PRIORITY
  114. Section: $X_IPK_SECTION
  115. Source: $SOURCE_URL
  116. Architecture: $ARCHITECTURE
  117. Maintainer: $X_IPK_MAINTAINER
  118. Depends: $X_IPK_DEPENDS
  119. Description: $X_IPK_DESCRIPTION
  120. """
  121. control_file.write(env.subst(content))
  122. #
  123. # now handle the various other files, which purpose it is to set post-,
  124. # pre-scripts and mark files as config files.
  125. #
  126. # We do so by filtering the source files for files which are marked with
  127. # the "config" tag and afterwards we do the same for x_ipk_postrm,
  128. # x_ipk_prerm, x_ipk_postinst and x_ipk_preinst tags.
  129. #
  130. # The first one will write the name of the file into the file
  131. # CONTROL/configfiles, the latter add the content of the x_ipk_* variable
  132. # into the same named file.
  133. #
  134. for f in [x for x in source if 'PACKAGING_CONFIG' in dir(x)]:
  135. config=open_file('conffiles')
  136. config.write(f.PACKAGING_INSTALL_LOCATION)
  137. config.write('\n')
  138. for str in 'POSTRM PRERM POSTINST PREINST'.split():
  139. name="PACKAGING_X_IPK_%s"%str
  140. for f in [x for x in source if name in dir(x)]:
  141. file=open_file(name)
  142. file.write(env[str])
  143. #
  144. # close all opened files
  145. for f in list(opened_files.values()):
  146. f.close()
  147. # call a user specified function
  148. if 'CHANGE_SPECFILE' in env:
  149. content += env['CHANGE_SPECFILE'](target)
  150. return 0
  151. # Local Variables:
  152. # tab-width:4
  153. # indent-tabs-mode:nil
  154. # End:
  155. # vim: set expandtab tabstop=4 shiftwidth=4: