Skip to content
This repository was archived by the owner on Apr 17, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
7d3a876
Started refactoring of libraries sub-system.
MrPointer Sep 25, 2018
b0df5ab
Refactored the entire library architecture processing logic.
MrPointer Sep 25, 2018
53280f0
Fixed bug in 'find_dependent_platform_libraries' function.
MrPointer Sep 25, 2018
e7d46d3
Refactored 'StringUtils' to be more readable.
MrPointer Sep 25, 2018
26b3981
Documented many new functions and renamed a few, all related to archi…
MrPointer Sep 25, 2018
3f2d66b
Removed code related to header-only-libraries, it belongs to another …
MrPointer Sep 25, 2018
2e66839
Merge branch 'develop' into feature/lib-arch-refactor
MrPointer Sep 25, 2018
641cc97
Added-back header-only related code to `find_library` API.
MrPointer Sep 25, 2018
08f8702
Refactored the 'ArduinoCMakeLibraryTarget' module.
MrPointer Sep 25, 2018
ee41ec7
Added utility function to parse scope arguments of a function.
MrPointer Sep 25, 2018
83ca465
Added utility function to parse sources from cmake's unparsed arguments.
MrPointer Sep 26, 2018
1ddf71f
Updated `add_arduino_library` function to use new argument parsing ut…
MrPointer Sep 26, 2018
0720c5d
Added utility function to get common root directory of sources.
MrPointer Sep 26, 2018
e9f7edb
Removed the need for the 'library_root_dir' argument in all functions.
MrPointer Sep 26, 2018
5c2d905
Updated header-only library API to use new argument parsing function …
MrPointer Sep 26, 2018
4e71924
Reordered scope argument-parsing function's arguments - Return var is…
MrPointer Sep 26, 2018
4e3a9e3
Separated crooked list-initialization technique from source argument …
MrPointer Sep 26, 2018
f4ab16c
Added utility-helper function to consume reserved arguments before pa…
MrPointer Sep 26, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions cmake/Platform/Arduino.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Other)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Properties)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Sketches)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Sources)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Libraries)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Targets)

include(MathUtils)
include(ListUtils)
include(StringUtils)
include(PropertyUtils)
include(PlatformLibraryUtils)
include(Utilities)

include(BoardManager)
include(RecipeParser)
include(TargetFlagsManager)
include(SourcesManager)
include(SketchManager)
include(DefaultsManager)
include(ArchitectureSupportQuery)

include(Libraries)

include(BuildSystemInitializer)

Expand Down
4 changes: 4 additions & 0 deletions cmake/Platform/Libraries/Libraries.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include(LibraryArchitectureParser)
include(LibrarySourcesArchitectureResolver)
include(LibraryFlagsManager)
include(LibrariesFinder)
64 changes: 64 additions & 0 deletions cmake/Platform/Libraries/LibrariesFinder.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#=============================================================================#
# Finds an Arduino library with the given library name and creates a library target from it
# with the given target name.
# The search process also resolves library's architecture to check if it even can be built
# using the current platform architecture.
# _target_name - Name of the library target to be created. Usually library's real name.
# _library_name - Name of the Arduino library to find.
# _board_id - Board ID associated with the linked Core Lib.
# [3RD_PARTY] - Whether library should be treated as a 3rd Party library.
#=============================================================================#
function(find_arduino_library _target_name _library_name _board_id)

set(argument_options "3RD_PARTY" "HEADER_ONLY")
cmake_parse_arguments(parsed_args "${argument_options}" "" "" ${ARGN})

if (NOT parsed_args_3RD_PARTY)
convert_string_to_pascal_case(${_library_name} _library_name)
endif ()

find_file(library_properties_file library.properties
PATHS ${ARDUINO_SDK_LIBRARIES_PATH} ${ARDUINO_CMAKE_SKETCHBOOK_PATH}/libraries
PATH_SUFFIXES ${_library_name}
NO_DEFAULT_PATH
NO_CMAKE_FIND_ROOT_PATH)

if (${library_properties_file} MATCHES "NOTFOUND")
message(SEND_ERROR "Couldn't find library named ${_library_name}")
else () # Library is found

get_filename_component(library_path ${library_properties_file} DIRECTORY)

find_library_header_files("${library_path}" library_headers)

if (NOT library_headers)
message(SEND_ERROR "Couldn't find any header files for the ${_library_name} library")
else ()

if (parsed_args_HEADER_ONLY)
add_arduino_header_only_library(${_target_name} ${_board_id} ${library_headers})

else ()

find_library_source_files("${library_path}" library_sources)

if (NOT library_sources)
message(SEND_ERROR "Couldn't find any source files for the "
"${_library_name} library - Is it a header-only library?"
"If so, please pass the HEADER_ONLY option "
"as an argument to the function")
else ()
set(sources ${library_headers} ${library_sources})

add_arduino_library(${_target_name} ${_board_id}
LIB_PROPS_FILE ${library_properties_file}
${sources})
endif ()

endif ()
endif ()
endif ()

unset(library_properties_file CACHE)

endfunction()
22 changes: 22 additions & 0 deletions cmake/Platform/Libraries/LibraryArchitectureParser.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#=============================================================================#
# Gets a list of architectures supported by a library.
# The list is read from the given properties file, which includes metadata about the library.
# _library_properties_file - Full path to a library's properties file
# (usually named 'library,propertie').
# _return_var - Name of variable in parent-scope holding the return value.
# Returns - List of architectures supported by the library or '*'
# if it's architecture-agnostic (Supports all arhcitectures).
#=============================================================================#
function(get_arduino_library_supported_architectures _library_properties_file _return_var)

file(STRINGS ${_library_properties_file} library_properties)

list(FILTER library_properties INCLUDE REGEX "arch")

_get_property_value("${library_properties}" _library_arch_list)

string(REPLACE "," ";" _library_arch_list ${_library_arch_list}) # Turn into a valid list

set(${_return_var} ${_library_arch_list} PARENT_SCOPE)

endfunction()
19 changes: 19 additions & 0 deletions cmake/Platform/Libraries/LibraryFlagsManager.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#=============================================================================#
# Sets compiler and linker flags on the given library target.
# Changes are kept even outside the scope of the function since they apply on a target.
# _library_target - Name of the library target.
# _board_id - Board ID associated with the library. Some flags require it.
#=============================================================================#
function(set_library_flags _library_target _board_id)

parse_scope_argument(scope "${ARGN}"
DEFAULT_SCOPE PUBLIC)

# Set C++ compiler flags
get_cmake_compliant_language_name(cpp flags_language)
set_compiler_target_flags(${_library_target} "${_board_id}" ${scope} LANGUAGE ${flags_language})

# Set linker flags
set_linker_flags(${_library_target} "${_board_id}")

endfunction()
66 changes: 66 additions & 0 deletions cmake/Platform/Libraries/LibrarySourcesArchitectureResolver.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#=============================================================================#
# Filters sources that relate to an architecture from the given list of unsupported architectures.
# _unsupported_archs_regex - List of unsupported architectures as a regex-pattern string.
# _sources - List of sources to check and potentially filter.
# _return_var - Name of variable in parent-scope holding the return value.
# Returns - Filtered list of sources containing only those that don't relate to
# any unsupported architecture.
#=============================================================================#
function(_filter_unsupported_arch_sources _unsupported_archs_regex _sources _return_var)

if (NOT "${_unsupported_archs_regex}" STREQUAL "") # Not all architectures are supported
# Filter sources dependant on unsupported architectures
list(FILTER _sources EXCLUDE REGEX ${_unsupported_archs_regex})
endif ()

set(${_return_var} ${_sources} PARENT_SCOPE)

endfunction()

#=============================================================================#
# Resolves library's architecture-related elements by doing several things:
# 1. Checking whether the platform's architecture is supported by the library
# 2. Filtering out any library sources that relate to unsupported architectures, i.e
# architectures other than the platform's.
# If the platform's architecture isn't supported by the library, CMake generates an error and stops.
# _library_sources - List of library's sources to check and potentially filter.
# [LIB_PROPS_FILE] - Full path to the library's properties file. Optional.
# _return_var - Name of variable in parent-scope holding the return value.
# Returns - Filtered list of sources containing only those that don't relate to
# any unsupported architecture.
#=============================================================================#
function(resolve_library_architecture _library_sources _return_var)

cmake_parse_arguments(parsed_args "" "LIB_PROPS_FILE" "" ${ARGN})

if (parsed_args_LIB_PROPS_FILE) # Library properties file is given
set(lib_props_file ${parsed_args_LIB_PROPS_FILE})
else ()

# Warn user and assume library is arch-agnostic
message(STATUS "Library's properties file can't be found "
"under its' root directory - Assuming the library "
"is architecture-agnostic (supports all architectures)")
set(${_return_var} "${_library_sources}" PARENT_SCOPE)
return()

endif ()

get_arduino_library_supported_architectures("${lib_props_file}" lib_archs)

# Check if the platform's architecture is supported by the library
is_platform_architecture_supported(${lib_archs} arch_supported_by_lib)

if (NOT ${arch_supported_by_lib})
message(SEND_ERROR "The platform's architecture, ${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE}, "
"isn't supported by the ${_library_name} library")
endif ()

get_unsupported_architectures("${lib_archs}" unsupported_archs REGEX)

# Filter any sources that aren't supported by the platform's architecture
_filter_unsupported_arch_sources("${unsupported_archs}" "${_library_sources}" valid_sources)

set(${_return_var} "${valid_sources}" PARENT_SCOPE)

endfunction()
64 changes: 64 additions & 0 deletions cmake/Platform/Other/ArchitectureSupportQuery.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#=============================================================================#
# Checks whether the platform's architecture is supported in the context of the given list
# of architectures, i.e If the list contains the platform's architecture.
# _arch_list - List of architectures supported by the library,
# inferred from its' 'library.properties' file.
# _return_var - Name of variable in parent-scope holding the return value.
# Returns - True if supported, false otherwise.
#=============================================================================#
function(is_platform_architecture_supported _arch_list _return_var)

if ("${_arch_list}" MATCHES "\\*") # Any architecture is supported
set(result TRUE)
else ()
if (${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE} IN_LIST _arch_list)
set(result TRUE) # Our platform's arch is supported
else ()
set(result FALSE) # Our arch isn't supported
endif ()
endif ()

set(${_return_var} ${result} PARENT_SCOPE)

endfunction()

#=============================================================================#
# Gets a filtered list of architectures that aren't compliant with the platform's architecture.
# e.g If a list contains 'avr' and 'nrf52', while our arch is 'avr', 'nrf52' will be returned.
# _arch_list - List of all architectures probably read from a library's properties file
# [REGEX] - Returns list in a regex-compatible mode, allowing caller to
# use result in search patterns. This is currently the only supported mode.
# _return_var - Name of variable in parent-scope holding the return value.
# Returns - Filtered list of architectures.
#=============================================================================#
function(get_unsupported_architectures _arch_list _return_var)

cmake_parse_arguments(parsed_args "REGEX" "" "" ${ARGN})

if ("${_arch_list}" MATCHES "\\*") # All architectures are supported, return nothing
return()
endif ()

list(FILTER _arch_list EXCLUDE REGEX ${ARDUINO_CMAKE_PLATFORM_ARCHITECTURE})
set(unsupported_arch_list ${_arch_list}) # Just for better readability

if (parsed_args_REGEX) # Return in regex format

foreach (arch ${unsupported_arch_list})
# Append every unsupported-architecture and "|" to represent "or" in regex-fomart
string(APPEND unsupported_archs_regex "${arch}" "|")
endforeach ()

# Remove last "|" as it's unnecessary - There's no element after it
string(LENGTH ${unsupported_archs_regex} str_len)
decrement_integer(str_len 1) # Decrement string's length by 1 to trim last char ('|')
string(SUBSTRING ${unsupported_archs_regex} 0 ${str_len} unsupported_archs_regex)

# prepare for generalized function return
set(unsupported_arch_list ${unsupported_archs_regex})

endif ()

set(${_return_var} ${unsupported_arch_list} PARENT_SCOPE)

endfunction()
46 changes: 31 additions & 15 deletions cmake/Platform/Other/TargetFlagsManager.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,24 @@
#=============================================================================#
function(set_compiler_target_flags _target_name _board_id)

set(option_args PRIVATE PUBLIC INTERFACE)
set(single_args LANGUAGE)
cmake_parse_arguments(compiler "${option_args}" "${single_args}" "" ${ARGN})

if (compiler_LANGUAGE)
if (compiler_PRIVATE)
set(scope PRIVATE)
elseif (compiler_INTERFACE)
set(scope INTERFACE)
else ()
set(scope PUBLIC)
endif ()
cmake_parse_arguments(parsed_args "" "LANGUAGE" "" ${ARGN})
parse_scope_argument(scope "${ARGN}"
DEFAULT_SCOPE PUBLIC)

if (parsed_args_LANGUAGE)

parse_compiler_recipe_flags("${_board_id}" compiler_recipe_flags
LANGUAGE "${compiler_LANGUAGE}")
LANGUAGE "${parsed_args_LANGUAGE}")

target_compile_options(${_target_name} ${scope}
$<$<COMPILE_LANGUAGE:${compiler_LANGUAGE}>:${compiler_recipe_flags}>)
$<$<COMPILE_LANGUAGE:${parsed_args_LANGUAGE}>:${compiler_recipe_flags}>)

else ()

parse_compiler_recipe_flags("${_board_id}" compiler_recipe_flags)
target_compile_options(${_target_name} PUBLIC ${compiler_recipe_flags})

target_compile_options(${_target_name} ${scope} ${compiler_recipe_flags})

endif ()

endfunction()
Expand All @@ -36,7 +35,9 @@ endfunction()
function(set_linker_flags _target_name _board_id)

parse_linker_recpie_pattern("${_board_id}" linker_recipe_flags)

string(REPLACE ";" " " cmake_compliant_linker_flags "${linker_recipe_flags}")

set(CMAKE_EXE_LINKER_FLAGS "${cmake_compliant_linker_flags}" CACHE STRING "" FORCE)

endfunction()
Expand Down Expand Up @@ -81,3 +82,18 @@ function(set_upload_target_flags _target_name _board_id _upload_port _return_var

endfunction()

#=============================================================================#
# Adds a compiler definition (#define) for the given architecture to the target.
# The affecting scope of the definition is controlled by the _scope argument.
# _target - Name of the target (Executable) to set flags on.
# _scope - PUBLIC|INTERFACE|PRIVATE. Affects outer scope - How other targets see it.
# _architecture - Architecture to define, e.g. 'avr'
#=============================================================================#
function(set_target_architecture_definition _target _scope _architecture)

string(TOUPPER ${_architecture} upper_arch)
set(arch_definition "ARDUINO_ARCH_${upper_arch}")

target_compile_definitions(${_target} ${_scope} ${arch_definition})

endfunction()
8 changes: 8 additions & 0 deletions cmake/Platform/System/DefaultsManager.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ function(set_default_arduino_cmake_options)

endfunction()

function(set_default_paths)

set(ARDUINO_CMAKE_LIBRARY_PROPERTIES_FILE_NAME "library.properties" CACHE STRING
"Name of the libraries' properties file")

endfunction()

#=============================================================================#
# Sets various defaults used throughout the platform.
#=============================================================================#
Expand All @@ -65,5 +72,6 @@ function(set_arduino_cmake_defaults)
set_internal_search_patterns()
set_source_files_patterns()
set_default_arduino_cmake_options()
set_default_paths()

endfunction()
Loading