Просмотр исходного кода

Merge branch 'bugfix/cmake_idf_path' into 'feature/cmake'

cmake: Fix issues when IDF_PATH is not set in environment

See merge request idf/esp-idf!2557
Angus Gratton 7 лет назад
Родитель
Сommit
e7faa1d851

+ 1 - 1
components/bootloader/project_include.cmake

@@ -17,7 +17,7 @@ externalproject_add(bootloader
     # TODO: support overriding the bootloader in COMPONENT_PATHS
     SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject"
     BINARY_DIR "${bootloader_build_dir}"
-    CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH="${IDF_PATH}"
+    CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH}
     INSTALL_COMMAND ""
     BUILD_ALWAYS 1  # no easy way around this...
     BUILD_BYPRODUCTS ${bootloader_binary_files}

+ 6 - 1
components/bootloader/subproject/CMakeLists.txt

@@ -5,6 +5,11 @@ if(NOT SDKCONFIG)
         "in by the parent build process.")
 endif()
 
+if(NOT IDF_PATH)
+    message(FATAL_ERROR "Bootloader subproject expects the IDF_PATH variable to be passed "
+        "in by the parent build process.")
+endif()
+
 set(COMPONENTS bootloader esptool_py esp32 soc bootloader_support log spi_flash micro-ecc soc)
 set(BOOTLOADER_BUILD 1)
 add_definitions(-DBOOTLOADER_BUILD=1)
@@ -13,7 +18,7 @@ set(COMPONENT_REQUIRES_COMMON log esp32 soc)
 
 set(MAIN_SRCS main/bootloader_start.c)
 
-include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+include("${IDF_PATH}/tools/cmake/project.cmake")
 project(bootloader)
 
 target_linker_script(bootloader.elf

+ 35 - 1
tools/ci/test_build_system_cmake.sh

@@ -171,13 +171,47 @@ function run_tests()
     idf.py build
     take_build_snapshot
     # Need to actually change the build config, or CMake won't do anything
+    cp CMakeLists.txt CMakeLists.bak
     sed -i 's/^project(/add_compile_options("-DUSELESS_MACRO_DOES_NOTHING=1")\nproject\(/' CMakeLists.txt
-    idf.py build
+    idf.py build || failure "Build failed"
+    mv CMakeLists.bak CMakeLists.txt
     # similar to previous test
     assert_rebuilt newlib/CMakeFiles/newlib.dir/syscall_table.c.obj
     assert_rebuilt nvs_flash/CMakeFiles/nvs_flash.dir/src/nvs_api.cpp.obj
     assert_rebuilt freertos/CMakeFiles/freertos.dir/xtensa_vectors.S.obj
 
+    print_status "Can build with Ninja (no idf.py)"
+    clean_build_dir
+    (cd build && cmake -G Ninja .. && ninja)  || failure "Ninja build failed"
+    assert_built ${APP_BINS} ${BOOTLOADER_BINS} ${PARTITION_BIN}
+
+    print_status "Can build with GNU Make (no idf.py)"
+    clean_build_dir
+    mkdir build
+    (cd build && cmake -G "Unix Makefiles" .. && make) || failure "Make build failed"
+    assert_built ${APP_BINS} ${BOOTLOADER_BINS} ${PARTITION_BIN}
+
+    print_status "Can build with IDF_PATH set via cmake cache not environment"
+    clean_build_dir
+    cp CMakeLists.txt CMakeLists.bak
+    sed -i 's/ENV{IDF_PATH}/{IDF_PATH}/' CMakeLists.txt
+    export IDF_PATH_BACKUP="$IDF_PATH"
+    (unset IDF_PATH &&
+         cd build &&
+         cmake -G Ninja .. -DIDF_PATH=${IDF_PATH_BACKUP} &&
+         ninja) || failure "Ninja build failed"
+    mv CMakeLists.bak CMakeLists.txt
+    assert_built ${APP_BINS} ${BOOTLOADER_BINS} ${PARTITION_BIN}
+
+    print_status "Can build with IDF_PATH unset and inferred by build system"
+    clean_build_dir
+    cp CMakeLists.txt CMakeLists.bak
+    sed -i "s%\$ENV{IDF_PATH}%${IDF_PATH}%" CMakeLists.txt  # expand to a hardcoded path
+    (unset IDF_PATH && cd build &&
+         cmake -G Ninja .. && ninja) || failure "Ninja build failed"
+    mv CMakeLists.bak CMakeLists.txt
+    assert_built ${APP_BINS} ${BOOTLOADER_BINS} ${PARTITION_BIN}
+
     print_status "All tests completed"
     if [ -n "${FAILURES}" ]; then
         echo "Some failures were detected:"

+ 2 - 1
tools/cmake/idf_functions.cmake

@@ -119,7 +119,8 @@ function(idf_verify_environment)
 
     # Check toolchain is configured properly in cmake
     if(NOT ( ${CMAKE_SYSTEM_NAME} STREQUAL "Generic" AND ${CMAKE_C_COMPILER} MATCHES xtensa))
-        message(FATAL_ERROR "Internal error, toolchain has not been set correctly by project")
+        message(FATAL_ERROR "Internal error, toolchain has not been set correctly by project "
+            "(or an invalid CMakeCache.txt file has been generated somehow)")
     endif()
 
     #

+ 4 - 3
tools/cmake/project.cmake

@@ -6,11 +6,12 @@ cmake_minimum_required(VERSION 3.5)
 set(IDF_PATH "$ENV{IDF_PATH}")
 if(NOT IDF_PATH)
     # Documentation says you should set IDF_PATH in your environment, but we
-    # can infer it here if it's not set.
-    set(IDF_PATH ${CMAKE_CURRENT_LIST_DIR})
+    # can infer it relative to tools/cmake directory if it's not set.
+    get_filename_component(IDF_PATH "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
 endif()
 file(TO_CMAKE_PATH "${IDF_PATH}" IDF_PATH)
-set($ENV{IDF_PATH} "${IDF_PATH}")
+set(ENV{IDF_PATH} ${IDF_PATH})
+
 
 #
 # Load cmake modules

+ 2 - 1
tools/idf.py

@@ -41,7 +41,7 @@ class FatalError(RuntimeError):
 PYTHON=sys.executable
 
 # note: os.environ changes don't automatically propagate to child processes,
-# you have to pass this in explicitly
+# you have to pass env=os.environ explicitly anywhere that we create a process
 os.environ["PYTHON"]=sys.executable
 
 # Make flavors, across the various kinds of Windows environments & POSIX...
@@ -95,6 +95,7 @@ def check_environment():
             print("WARNING: IDF_PATH environment variable is set to %s but idf.py path indicates IDF directory %s. Using the environment variable directory, but results may be unexpected..."
                   % (set_idf_path, detected_idf_path))
     else:
+        print("Setting IDF_PATH environment variable: %s" % detected_idf_path)
         os.environ["IDF_PATH"] = detected_idf_path
 
 def executable_exists(args):