test_build.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  2. # SPDX-License-Identifier: Apache-2.0
  3. import logging
  4. import os
  5. import sys
  6. import textwrap
  7. from pathlib import Path
  8. from typing import List, Union
  9. import pytest
  10. from test_build_system_helpers import (APP_BINS, BOOTLOADER_BINS, PARTITION_BIN, IdfPyFunc, append_to_file,
  11. file_contains, get_idf_build_env, replace_in_file, run_cmake_and_build)
  12. def assert_built(paths: Union[List[str], List[Path]]) -> None:
  13. for path in paths:
  14. assert os.path.exists(path)
  15. def test_build_alternative_directories(idf_py: IdfPyFunc, session_work_dir: Path, test_app_copy: Path) -> None:
  16. logging.info('Moving BUILD_DIR_BASE out of tree')
  17. alt_build_dir = session_work_dir / 'alt_build'
  18. idf_py('-B', str(alt_build_dir), 'build')
  19. assert os.listdir(alt_build_dir) != [], 'No files found in new build directory!'
  20. default_build_dir = test_app_copy / 'build'
  21. if default_build_dir.exists():
  22. assert os.listdir(default_build_dir) == [], f'Some files were incorrectly put into the default build directory: {default_build_dir}'
  23. logging.info('BUILD_DIR_BASE inside default build directory')
  24. build_subdir_inside_build_dir = default_build_dir / 'subdirectory'
  25. idf_py('-B', str(build_subdir_inside_build_dir), 'build')
  26. assert os.listdir(build_subdir_inside_build_dir) != [], 'No files found in new build directory!'
  27. @pytest.mark.usefixtures('test_app_copy')
  28. def test_build_cmake_ninja() -> None:
  29. logging.info('Can build with Ninja (no idf.py)')
  30. run_cmake_and_build('-G', 'Ninja', '..')
  31. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
  32. @pytest.mark.skipif(sys.platform == 'win32', reason="GNU Make doesn't work on Windows")
  33. @pytest.mark.usefixtures('test_app_copy')
  34. def test_build_cmake_makefile() -> None:
  35. logging.info('Can build with GNU Make (no idf.py)')
  36. run_cmake_and_build('-G', 'Unix Makefiles', '..')
  37. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
  38. @pytest.mark.usefixtures('test_app_copy')
  39. def test_build_with_generator_ninja(idf_py: IdfPyFunc) -> None:
  40. logging.info('idf.py can build with Ninja')
  41. idf_py('-G', 'Ninja', 'build')
  42. cmake_cache_file = Path('build', 'CMakeCache.txt')
  43. assert_built([cmake_cache_file])
  44. assert file_contains(cmake_cache_file, 'CMAKE_GENERATOR:INTERNAL=Ninja')
  45. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
  46. @pytest.mark.skipif(sys.platform == 'win32', reason="GNU Make doesn't work on Windows")
  47. @pytest.mark.usefixtures('test_app_copy')
  48. def test_build_with_generator_makefile(idf_py: IdfPyFunc) -> None:
  49. logging.info('idf.py can build with Unix Makefiles')
  50. idf_py('-G', 'Unix Makefiles', 'build')
  51. cmake_cache_file = Path('build', 'CMakeCache.txt')
  52. assert_built([cmake_cache_file])
  53. assert file_contains(cmake_cache_file, 'CMAKE_GENERATOR:INTERNAL=Unix Makefiles')
  54. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
  55. def test_build_with_cmake_and_idf_path_unset(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  56. idf_path = Path(os.environ['IDF_PATH'])
  57. env = get_idf_build_env(idf_path)
  58. env.pop('IDF_PATH')
  59. logging.info('Can build with IDF_PATH set via cmake cache not environment')
  60. replace_in_file('CMakeLists.txt', 'ENV{IDF_PATH}', '{IDF_PATH}')
  61. run_cmake_and_build('-G', 'Ninja', '..', '-DIDF_PATH={}'.format(idf_path), env=env)
  62. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
  63. idf_py('fullclean')
  64. logging.info('Can build with IDF_PATH unset and inferred by cmake when Kconfig needs it to be set')
  65. # working with already changed CMakeLists.txt
  66. kconfig_file = test_app_copy / 'main' / 'Kconfig.projbuild'
  67. kconfig_file.write_text('source "$IDF_PATH/examples/wifi/getting_started/station/main/Kconfig.projbuild"')
  68. run_cmake_and_build('-G', 'Ninja', '..', '-DIDF_PATH={}'.format(idf_path), env=env)
  69. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
  70. kconfig_file.unlink() # remove file to not affect following sub-test
  71. idf_py('fullclean')
  72. logging.info('Can build with IDF_PATH unset and inferred by build system')
  73. # replacing {IDF_PATH} not ENV{IDF_PATH} since CMakeLists.txt was already changed in this test
  74. replace_in_file('CMakeLists.txt', '{IDF_PATH}', '{ci_idf_path}')
  75. run_cmake_and_build('-G', 'Ninja', '-D', 'ci_idf_path={}'.format(idf_path), '..', env=env)
  76. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN)
  77. def test_build_skdconfig_phy_init_data(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  78. logging.info('can build with phy_init_data')
  79. (test_app_copy / 'sdkconfig.defaults').touch()
  80. (test_app_copy / 'sdkconfig.defaults').write_text('CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION=y')
  81. idf_py('reconfigure')
  82. idf_py('build')
  83. assert_built(BOOTLOADER_BINS + APP_BINS + PARTITION_BIN + ['build/phy_init_data.bin'])
  84. def test_build_compiler_flag_in_source_file(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  85. logging.info('Compiler flags on build command line are taken into account')
  86. compiler_flag = textwrap.dedent("""
  87. #ifndef USER_FLAG
  88. #error "USER_FLAG is not defined!"
  89. #endif
  90. """)
  91. append_to_file((test_app_copy / 'main' / 'build_test_app.c'), compiler_flag)
  92. idf_py('build', '-DCMAKE_C_FLAGS=-DUSER_FLAG')
  93. @pytest.mark.usefixtures('test_app_copy')
  94. def test_build_compiler_flags_no_overwriting(idf_py: IdfPyFunc) -> None:
  95. logging.info('Compiler flags cannot be overwritten')
  96. # If the compiler flags are overriden, the following build command will
  97. # cause issues at link time.
  98. idf_py('build', '-DCMAKE_C_FLAGS=', '-DCMAKE_CXX_FLAGS=')
  99. def test_build_with_sdkconfig_build_abspath(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
  100. build_path = test_app_copy / 'build_tmp'
  101. sdkconfig_path = build_path / 'sdkconfig'
  102. idf_py('-D', f'SDKCONFIG={sdkconfig_path}', '-B', str(build_path), 'build')