Skip to content

Commit b48fca2

Browse files
committed
Reuse already built Arduino libraries
1 parent 6abc7cc commit b48fca2

File tree

1 file changed

+81
-31
lines changed

1 file changed

+81
-31
lines changed

toolchain/arduino-cli-toolchain.cmake

Lines changed: 81 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -696,50 +696,80 @@ endfunction()
696696
# if not hundreds of out-of-tree sources the library is built separately and later gets pulled as IMPORT library.
697697
# ----------------------------------------------------------------------------------------------------------------------
698698
function(__arduino_add_import_library NAME SOURCE_DIR) # [SOURCE_DIR...]
699+
string(TOUPPER "ARDUINO_${NAME}" _prefix)
700+
699701
set(_libname "Arduino${NAME}")
700702
set(_target "Arduino::${NAME}")
701703

702-
set(_library_binary_dir "${CMAKE_BINARY_DIR}/Arduino/${NAME}")
703-
set(_library_source_dir "${CMAKE_BINARY_DIR}/ArduinoFiles/${NAME}")
704-
set(_library_template "${ARDUINO_TOOLCHAIN_DIR}/Templates/ArduinoLibraryCMakeLists.txt.in")
705-
set(_library_filepath "${_library_binary_dir}/lib${_libname}.a")
704+
if (${_prefix}_FILEPATH)
705+
message(STATUS "Using ${_target} from ${${_prefix}_FILEPATH}")
706706

707-
set(_library_directories "${SOURCE_DIR}" ${ARGN})
708-
list(FILTER _library_directories EXCLUDE REGEX "^ *\$")
709-
list(REMOVE_DUPLICATES _library_directories)
707+
set(_library_binary_dir "${${_prefix}_BINARY_DIR}")
708+
set(_library_source_dir "${${_prefix}_BINARY_DIR}")
709+
set(_library_directories "${${_prefix}_INCLUDE_DIRS}")
710+
set(_library_filepath "${${_prefix}_FILEPATH}")
711+
else()
712+
message(STATUS "Building ${_target} from scratch")
710713

711-
__arduino_collect_source_files(_library_sources ${_library_directories}) # <----- collect the library's source files
714+
set(_library_binary_dir "${CMAKE_BINARY_DIR}/Arduino/${NAME}")
715+
set(_library_source_dir "${CMAKE_BINARY_DIR}/ArduinoFiles/${NAME}")
716+
set(_library_filepath "${_library_binary_dir}/lib${_libname}.a")
712717

713-
list(LENGTH _library_sources _source_file_count)
714-
message(STATUS " ${_source_file_count} source files found for ${_target}")
718+
set(_library_directories "${SOURCE_DIR}" ${ARGN}) # <---------------- normalize the library's source directories
719+
list(FILTER _library_directories EXCLUDE REGEX "^ *\$")
720+
list(REMOVE_DUPLICATES _library_directories)
715721

716-
list(JOIN _library_sources "\"\n \"" _quoted_library_sources) # <--------- prepare CMake to build out of tree
717-
list(JOIN _library_directories "\"\n \"" _quoted_library_directories)
718-
configure_file("${_library_template}" "${_library_source_dir}/CMakeLists.txt")
722+
__arduino_collect_source_files(_library_sources ${_library_directories}) # <--------- find the library's sources
719723

720-
add_custom_command(
721-
OUTPUT "${_library_binary_dir}/CMakeCache.txt"
722-
DEPENDS "${_library_template}" "${CMAKE_CURRENT_LIST_FILE}"
723-
COMMENT "Configuring ${_target} library"
724-
WORKING_DIRECTORY "${_library_binary_dir}"
724+
list(LENGTH _library_sources _source_file_count)
725+
message(STATUS " ${_source_file_count} source files found for ${_target}")
726+
727+
list(JOIN _library_sources "\"\n \"" _quoted_library_sources) # <----- prepare CMake to build out of tree
728+
list(JOIN _library_directories "\"\n \"" _quoted_library_directories)
729+
730+
set(_library_template "${ARDUINO_TOOLCHAIN_DIR}/Templates/ArduinoLibraryCMakeLists.txt.in")
731+
configure_file("${_library_template}" "${_library_source_dir}/CMakeLists.txt")
732+
733+
add_custom_command(
734+
OUTPUT "${_library_binary_dir}/CMakeCache.txt"
735+
DEPENDS "${_library_template}" "${CMAKE_CURRENT_LIST_FILE}"
736+
COMMENT "Configuring ${_target} library"
737+
WORKING_DIRECTORY "${_library_binary_dir}"
725738

726-
COMMAND "${CMAKE_COMMAND}"
739+
COMMAND "${CMAKE_COMMAND}"
727740
--toolchain "${CMAKE_CURRENT_FUNCTION_LIST_FILE}"
728741
-G "${CMAKE_GENERATOR}" -S "${_library_source_dir}"
742+
-D "__ARDUINO_IMPORTED_TARGET_CACHE=${__ARDUINO_IMPORTED_TARGET_CACHE}"
729743
-D "ARDUINO_BOARD:STRING=${ARDUINO_BOARD}")
730744

731-
add_custom_command(
732-
OUTPUT "${_library_filepath}"
733-
DEPENDS ${_library_sources} "${_library_binary_dir}/CMakeCache.txt"
734-
COMMENT "Building ${_target} library"
735-
WORKING_DIRECTORY "${_library_binary_dir}"
745+
add_custom_command(
746+
OUTPUT "${_library_filepath}"
747+
DEPENDS ${_library_sources} "${_library_binary_dir}/CMakeCache.txt"
748+
COMMENT "Building ${_target} library"
749+
WORKING_DIRECTORY "${_library_binary_dir}"
750+
751+
COMMAND "${CMAKE_COMMAND}" --build "${_library_binary_dir}")
736752

737-
COMMAND "${CMAKE_COMMAND}" --build "${_library_binary_dir}")
753+
add_custom_target("${_libname}_compile" DEPENDS "${_library_filepath}")
738754

739-
add_custom_target("${_libname}_compile" DEPENDS "${_library_filepath}")
755+
set(${_prefix}_BINARY_DIR "${_library_binary_dir}" PARENT_SCOPE) # <------------------- set cache variables
756+
set(${_prefix}_SOURCE_DIR "${_library_source_dir}" PARENT_SCOPE)
757+
set(${_prefix}_FILEPATH "${_library_filepath}" PARENT_SCOPE)
758+
set(${_prefix}_INCLUDE_DIRS "${_library_directories}" PARENT_SCOPE)
759+
760+
file(
761+
APPEND "${__ARDUINO_IMPORTED_TARGET_CACHE}"
762+
"set(${_prefix}_BINARY_DIR \"${_library_binary_dir}\")\n"
763+
"set(${_prefix}_SOURCE_DIR \"${_library_source_dir}\")\n"
764+
"set(${_prefix}_FILEPATH \"${_library_filepath}\")\n"
765+
"set(${_prefix}_INCLUDE_DIRS \"${_library_directories}\")\n")
766+
endif()
740767

741768
add_library("${_target}" STATIC IMPORTED) # <-------------------- define import library for the built static library
742-
add_dependencies("${_target}" "${_libname}_compile")
769+
770+
if (TARGET "${_libname}_compile")
771+
add_dependencies("${_target}" "${_libname}_compile")
772+
endif()
743773

744774
if (NOT NAME STREQUAL "Core")
745775
target_link_libraries("${_target}" INTERFACE Arduino::Core)
@@ -759,11 +789,22 @@ endfunction()
759789
# Creates an import library for Arduino's core library.
760790
# ----------------------------------------------------------------------------------------------------------------------
761791
function(__arduino_add_arduino_core_library)
762-
set(_library_directories
763-
"${ARDUINO_PROPERTIES_EXPANDED_BUILD_CORE_PATH}"
764-
"${ARDUINO_PROPERTIES_EXPANDED_BUILD_VARIANT_PATH}")
792+
cmake_path(
793+
CONVERT "${ARDUINO_PROPERTIES_EXPANDED_BUILD_CORE_PATH}"
794+
TO_CMAKE_PATH_LIST _core_dirpath
795+
NORMALIZE)
796+
797+
cmake_path(
798+
CONVERT "${ARDUINO_PROPERTIES_EXPANDED_BUILD_VARIANT_PATH}"
799+
TO_CMAKE_PATH_LIST _variant_dirpath
800+
NORMALIZE)
765801

802+
set(_library_directories "${_core_dirpath}" "${_variant_dirpath}")
766803
__arduino_add_import_library(Core ${_library_directories})
804+
805+
foreach(_suffix IN ITEMS BINARY_DIR SOURCE_DIR FILEPATH)
806+
set("ARDUINO_CORE_${_suffix}" "${ARDUINO_CORE_${_suffix}}" PARENT_SCOPE)
807+
endforeach()
767808
endfunction()
768809

769810
# ----------------------------------------------------------------------------------------------------------------------
@@ -1036,14 +1077,23 @@ list( # <-----------------------------------------------------------------------
10361077
ARDUINO_BOARD # make it just work
10371078
__ARDUINO_PROPERTIES_EXPANDED_CACHE # make it MUCH faster
10381079
__ARDUINO_PROPERTIES_UNEXPANDED_CACHE
1039-
__ARDUINO_INSTALLED_LIBRARIES_CACHE)
1080+
__ARDUINO_INSTALLED_LIBRARIES_CACHE
1081+
__ARDUINO_IMPORTED_TARGET_CACHE)
10401082

10411083
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) # try_compile() doesn't provide setup() and loop()
10421084

10431085
set(CMAKE_USER_MAKE_RULES_OVERRIDE # <------------------ align object and library filenames with Arduino for convenience
10441086
"${ARDUINO_TOOLCHAIN_DIR}/Arduino/RulesOverride.cmake")
10451087

10461088
if (CMAKE_PARENT_LIST_FILE MATCHES "CMakeSystem\\.cmake$") # <----------------- define additonal API, additional targets
1089+
if (__ARDUINO_IMPORTED_TARGET_CACHE)
1090+
message(STATUS "Using library cache from ${__ARDUINO_IMPORTED_TARGET_CACHE}")
1091+
include("${__ARDUINO_IMPORTED_TARGET_CACHE}")
1092+
else()
1093+
set(__ARDUINO_IMPORTED_TARGET_CACHE "${CMAKE_BINARY_DIR}/ArduinoFiles/ArduinoLibraries.cmake")
1094+
file(WRITE "${__ARDUINO_IMPORTED_TARGET_CACHE}" "# Generated from toolchain\n")
1095+
endif()
1096+
10471097
if (NOT CMAKE_PROJECT_NAME STREQUAL ArduinoCore) # FIXME Rather check for __ARDUINO_CORE_FILEPATH
10481098
__arduino_add_arduino_core_library()
10491099
endif()

0 commit comments

Comments
 (0)