res.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. from _common import iterpair, listid, pathid, rootrel_arc_src, tobuilddir, filter_out_by_keyword
  2. import ymake
  3. def split(lst, limit):
  4. # paths are specified with replaceable prefix
  5. # real length is unknown at the moment, that why we use root_lenght
  6. # as a rough estimation
  7. root_lenght = 200
  8. filepath = None
  9. lenght = 0
  10. bucket = []
  11. for item in lst:
  12. if filepath:
  13. lenght += root_lenght + len(filepath) + len(item)
  14. if lenght > limit and bucket:
  15. yield bucket
  16. bucket = []
  17. lenght = 0
  18. bucket.append(filepath)
  19. bucket.append(item)
  20. filepath = None
  21. else:
  22. filepath = item
  23. if bucket:
  24. yield bucket
  25. def remove_prefix(text, prefix):
  26. if text.startswith(prefix):
  27. return text[len(prefix):]
  28. return text
  29. def onfat_resource(unit, *args):
  30. unit.onpeerdir(['library/cpp/resource'])
  31. # Since the maximum length of lpCommandLine string for CreateProcess is 8kb (windows) characters,
  32. # we make several calls of rescompiler
  33. # https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682425.aspx
  34. for part_args in split(args, 8000):
  35. output = listid(part_args) + '.cpp'
  36. inputs = [x for x, y in iterpair(part_args) if x != '-']
  37. if inputs:
  38. inputs = ['IN'] + inputs
  39. unit.onrun_program(['tools/rescompiler', output] + part_args + inputs + ['OUT_NOAUTO', output])
  40. unit.onsrcs(['GLOBAL', output])
  41. def onresource_files(unit, *args):
  42. """
  43. @usage: RESOURCE_FILES([DONT_PARSE] [PREFIX {prefix}] [STRIP prefix_to_strip] {path})
  44. This macro expands into
  45. RESOURCE([DONT_PARSE] {path} resfs/file/{prefix}{path}
  46. - resfs/src/resfs/file/{prefix}{remove_prefix(path, prefix_to_strip)}={rootrel_arc_src(path)}
  47. )
  48. resfs/src/{key} stores a source root (or build root) relative path of the
  49. source of the value of the {key} resource.
  50. resfs/file/{key} stores any value whose source was a file on a filesystem.
  51. resfs/src/resfs/file/{key} must store its path.
  52. DONT_PARSE disables parsing for source code files (determined by extension)
  53. Please don't abuse: use separate DONT_PARSE macro call only for files subject to parsing
  54. This form is for use from other plugins:
  55. RESOURCE_FILES([DEST {dest}] {path}) expands into RESOURCE({path} resfs/file/{dest})
  56. @see: https://wiki.yandex-team.ru/devtools/commandsandvars/resourcefiles/
  57. """
  58. prefix = ''
  59. prefix_to_strip = None
  60. dest = None
  61. res = []
  62. first = 0
  63. if args and not unit.enabled('_GO_MODULE'):
  64. # GO_RESOURCE currently doesn't support DONT_PARSE
  65. res.append('DONT_PARSE')
  66. if args and args[0] == 'DONT_PARSE':
  67. first = 1
  68. args = iter(args[first:])
  69. for arg in args:
  70. if arg == 'DONT_PARSE':
  71. # ignore explicit specification
  72. continue
  73. if arg == 'PREFIX':
  74. prefix, dest = next(args), None
  75. elif arg == 'DEST':
  76. dest, prefix = next(args), None
  77. elif arg == 'STRIP':
  78. prefix_to_strip = next(args)
  79. else:
  80. path = arg
  81. key = 'resfs/file/' + (dest or (prefix + (path if not prefix_to_strip else remove_prefix(path, prefix_to_strip))))
  82. src = 'resfs/src/{}={}'.format(key, rootrel_arc_src(path, unit))
  83. res += ['-', src, path, key]
  84. if unit.enabled('_GO_MODULE'):
  85. unit.on_go_resource(res)
  86. else:
  87. unit.onresource(res)
  88. def onall_resource_files(unit, *args):
  89. # This is only validation, actual work is done in ymake.core.conf implementation
  90. for arg in args:
  91. if '*' in arg or '?' in arg:
  92. ymake.report_configure_error('Wildcards in [[imp]]ALL_RESOURCE_FILES[[rst]] are not allowed')