build_pytest_apps.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
  2. # SPDX-License-Identifier: Apache-2.0
  3. """
  4. This file is used to generate binary files for the given path.
  5. """
  6. import argparse
  7. import logging
  8. import os
  9. import sys
  10. from typing import List
  11. from idf_ci_utils import IDF_PATH, get_pytest_dirs
  12. try:
  13. from build_apps import build_apps
  14. from find_apps import find_apps, find_builds_for_app
  15. from find_build_apps import BuildItem, CMakeBuildSystem, config_rules_from_str, setup_logging
  16. except ImportError:
  17. sys.path.append(os.path.join(IDF_PATH, 'tools'))
  18. from build_apps import build_apps
  19. from find_apps import find_apps, find_builds_for_app
  20. from find_build_apps import BuildItem, CMakeBuildSystem, config_rules_from_str, setup_logging
  21. def main(args: argparse.Namespace) -> None:
  22. if args.all_pytest_apps:
  23. paths = get_pytest_dirs(IDF_PATH, args.under_dir)
  24. args.recursive = True
  25. elif args.paths is None:
  26. paths = [os.getcwd()]
  27. else:
  28. paths = args.paths
  29. app_dirs = []
  30. for path in paths:
  31. app_dirs += find_apps(CMakeBuildSystem, path, args.recursive, [], args.target)
  32. if not app_dirs:
  33. logging.error('No apps found')
  34. sys.exit(1)
  35. logging.info('Found {} apps'.format(len(app_dirs)))
  36. app_dirs.sort()
  37. # Find compatible configurations of each app, collect them as BuildItems
  38. build_items: List[BuildItem] = []
  39. config_rules = config_rules_from_str(args.config or [])
  40. for app_dir in app_dirs:
  41. app_dir = os.path.realpath(app_dir)
  42. build_items += find_builds_for_app(
  43. app_dir,
  44. app_dir,
  45. 'build_@t_@w',
  46. f'{app_dir}/build_@t_@w/build.log',
  47. args.target,
  48. 'cmake',
  49. config_rules,
  50. True,
  51. )
  52. logging.info('Found {} builds'.format(len(build_items)))
  53. build_items.sort(key=lambda x: x.build_path) # type: ignore
  54. build_apps(build_items, args.parallel_count, args.parallel_index, False, args.build_verbose, True, None,
  55. args.size_info)
  56. if __name__ == '__main__':
  57. parser = argparse.ArgumentParser(description='Tool to generate build steps for IDF apps')
  58. parser.add_argument(
  59. '--recursive',
  60. action='store_true',
  61. help='Look for apps in the specified directories recursively.',
  62. )
  63. parser.add_argument('--target', required=True, help='Build apps for given target.')
  64. parser.add_argument(
  65. '--config',
  66. default=['sdkconfig.ci=default', 'sdkconfig.ci.*=', '=default'],
  67. action='append',
  68. help='Adds configurations (sdkconfig file names) to build. This can either be ' +
  69. 'FILENAME[=NAME] or FILEPATTERN. FILENAME is the name of the sdkconfig file, ' +
  70. 'relative to the project directory, to be used. Optional NAME can be specified, ' +
  71. 'which can be used as a name of this configuration. FILEPATTERN is the name of ' +
  72. 'the sdkconfig file, relative to the project directory, with at most one wildcard. ' +
  73. 'The part captured by the wildcard is used as the name of the configuration.',
  74. )
  75. parser.add_argument(
  76. '-p', '--paths',
  77. nargs='*',
  78. help='One or more app paths. Will use the current path if not specified.'
  79. )
  80. parser.add_argument(
  81. '--all-pytest-apps',
  82. action='store_true',
  83. help='Look for all pytest apps. "--paths" would be ignored if specify this flag.'
  84. )
  85. parser.add_argument(
  86. '--under-dir',
  87. help='Build only the pytest apps under this directory if specified. '
  88. 'Would be ignored if "--all-pytest-apps" is unflagged.'
  89. )
  90. parser.add_argument(
  91. '--parallel-count',
  92. default=1,
  93. type=int,
  94. help='Number of parallel build jobs.'
  95. )
  96. parser.add_argument(
  97. '--parallel-index',
  98. default=1,
  99. type=int,
  100. help='Index (1-based) of the job, out of the number specified by --parallel-count.',
  101. )
  102. parser.add_argument(
  103. '--size-info',
  104. type=argparse.FileType('a'),
  105. help='If specified, the test case name and size info json will be written to this file'
  106. )
  107. parser.add_argument(
  108. '-v',
  109. '--verbose',
  110. action='count',
  111. help='Increase the logging level of the script. Can be specified multiple times.',
  112. )
  113. parser.add_argument(
  114. '--build-verbose',
  115. action='store_true',
  116. help='Enable verbose output from build system.',
  117. )
  118. arguments = parser.parse_args()
  119. setup_logging(arguments)
  120. main(arguments)