cmake.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import logging
  2. import os
  3. import shutil
  4. import subprocess
  5. import sys
  6. from .common import BuildError, BuildItem, BuildSystem
  7. BUILD_SYSTEM_CMAKE = 'cmake'
  8. IDF_PY = os.path.join(os.environ['IDF_PATH'], 'tools', 'idf.py')
  9. # While ESP-IDF component CMakeLists files can be identified by the presence of 'idf_component_register' string,
  10. # there is no equivalent for the project CMakeLists files. This seems to be the best option...
  11. CMAKE_PROJECT_LINE = r'include($ENV{IDF_PATH}/tools/cmake/project.cmake)'
  12. class CMakeBuildSystem(BuildSystem):
  13. NAME = BUILD_SYSTEM_CMAKE
  14. @classmethod
  15. def build(cls, build_item): # type: (BuildItem) -> None
  16. build_path, work_path, extra_cmakecache_items = cls.build_prepare(build_item)
  17. # Prepare the build arguments
  18. args = [
  19. sys.executable,
  20. IDF_PY,
  21. '-B',
  22. build_path,
  23. '-C',
  24. work_path,
  25. '-DIDF_TARGET=' + build_item.target,
  26. ]
  27. if extra_cmakecache_items:
  28. for key, val in extra_cmakecache_items.items():
  29. args.append('-D{}={}'.format(key, val))
  30. if 'TEST_EXCLUDE_COMPONENTS' in extra_cmakecache_items \
  31. and 'TEST_COMPONENTS' not in extra_cmakecache_items:
  32. args.append('-DTESTS_ALL=1')
  33. if build_item.verbose:
  34. args.append('-v')
  35. args.append('build')
  36. cmdline = format(' '.join(args))
  37. logging.info('Running {}'.format(cmdline))
  38. if build_item.dry_run:
  39. return
  40. log_file = None
  41. build_stdout = sys.stdout
  42. build_stderr = sys.stderr
  43. if build_item.build_log_path:
  44. logging.info('Writing build log to {}'.format(build_item.build_log_path))
  45. log_file = open(build_item.build_log_path, 'w')
  46. build_stdout = log_file
  47. build_stderr = log_file
  48. try:
  49. subprocess.check_call(args, stdout=build_stdout, stderr=build_stderr)
  50. except subprocess.CalledProcessError as e:
  51. raise BuildError('Build failed with exit code {}'.format(e.returncode))
  52. else:
  53. # Also save the sdkconfig file in the build directory
  54. shutil.copyfile(
  55. os.path.join(work_path, 'sdkconfig'),
  56. os.path.join(build_path, 'sdkconfig'),
  57. )
  58. build_item.size_json_fp = build_item.get_size_json_fp()
  59. finally:
  60. if log_file:
  61. log_file.close()
  62. @staticmethod
  63. def _read_cmakelists(app_path):
  64. cmakelists_path = os.path.join(app_path, 'CMakeLists.txt')
  65. if not os.path.exists(cmakelists_path):
  66. return None
  67. with open(cmakelists_path, 'r') as cmakelists_file:
  68. return cmakelists_file.read()
  69. @staticmethod
  70. def is_app(path):
  71. cmakelists_file_content = CMakeBuildSystem._read_cmakelists(path)
  72. if not cmakelists_file_content:
  73. return False
  74. if CMAKE_PROJECT_LINE not in cmakelists_file_content:
  75. return False
  76. return True
  77. @classmethod
  78. def supported_targets(cls, app_path):
  79. return cls._supported_targets(app_path)