OVMS3-idf/tools/cmake/utilities.cmake
Angus Gratton da390618c2 cmake: Fix psram workaround compiler flag application
Previously, this compiler flag was not being applied
regardless of CONFIG_SPIRAM_CACHE_WORKAROUND setting.

Explanation: add_compile_options() only applies to
source files added after the function is run, or in
subdirectories added after the function is run. In
this case, no new source files were being added after
this function was run.
2019-02-26 04:07:51 +00:00

190 lines
6.7 KiB
CMake

# set_default
#
# Define a variable to a default value if otherwise unset.
#
# Priority for new value is:
# - Existing cmake value (ie set with cmake -D, or already set in CMakeLists)
# - Value of any non-empty environment variable of the same name
# - Default value as provided to function
#
function(set_default variable default_value)
if(NOT ${variable})
if(DEFINED ENV{${variable}} AND NOT "$ENV{${variable}}" STREQUAL "")
set(${variable} $ENV{${variable}} PARENT_SCOPE)
else()
set(${variable} ${default_value} PARENT_SCOPE)
endif()
endif()
endfunction()
# spaces2list
#
# Take a variable whose value was space-delimited values, convert to a cmake
# list (semicolon-delimited)
#
# Note: if using this for directories, keeps the issue in place that
# directories can't contain spaces...
#
# TODO: look at cmake separate_arguments, which is quote-aware
function(spaces2list variable_name)
string(REPLACE " " ";" tmp "${${variable_name}}")
set("${variable_name}" "${tmp}" PARENT_SCOPE)
endfunction()
# lines2list
#
# Take a variable with multiple lines of output in it, convert it
# to a cmake list (semicolon-delimited), one line per item
#
function(lines2list variable_name)
string(REGEX REPLACE "\r?\n" ";" tmp "${${variable_name}}")
string(REGEX REPLACE ";;" ";" tmp "${tmp}")
set("${variable_name}" "${tmp}" PARENT_SCOPE)
endfunction()
# move_if_different
#
# If 'source' has different md5sum to 'destination' (or destination
# does not exist, move it across.
#
# If 'source' has the same md5sum as 'destination', delete 'source'.
#
# Avoids timestamp updates for re-generated files where content hasn't
# changed.
function(move_if_different source destination)
set(do_copy 1)
file(GLOB dest_exists ${destination})
if(dest_exists)
file(MD5 ${source} source_md5)
file(MD5 ${destination} dest_md5)
if(source_md5 STREQUAL dest_md5)
set(do_copy "")
endif()
endif()
if(do_copy)
message("Moving ${source} -> ${destination}")
file(RENAME ${source} ${destination})
else()
message("Not moving ${source} -> ${destination}")
file(REMOVE ${source})
endif()
endfunction()
# target_add_binary_data adds binary data into the built target,
# by converting it to a generated source file which is then compiled
# to a binary object as part of the build
function(target_add_binary_data target embed_file embed_type)
get_filename_component(embed_file "${embed_file}" ABSOLUTE)
get_filename_component(name "${embed_file}" NAME)
set(embed_srcfile "${IDF_BUILD_ARTIFACTS_DIR}/${name}.S")
add_custom_command(OUTPUT "${embed_srcfile}"
COMMAND "${CMAKE_COMMAND}"
-D "DATA_FILE=${embed_file}"
-D "SOURCE_FILE=${embed_srcfile}"
-D "FILE_TYPE=${embed_type}"
-P "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
MAIN_DEPENDENCY "${embed_file}"
DEPENDS "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
WORKING_DIRECTORY "${IDF_BUILD_ARTIFACTS_DIR}"
VERBATIM)
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${embed_srcfile}")
target_sources("${target}" PRIVATE "${embed_srcfile}")
endfunction()
macro(include_if_exists path)
if(EXISTS "${path}")
include("${path}")
endif()
endmacro()
# Append a single line to the file specified
# The line ending is determined by the host OS
function(file_append_line file line)
if(DEFINED ENV{MSYSTEM} OR CMAKE_HOST_WIN32)
set(line_ending "\r\n")
else() # unix
set(line_ending "\n")
endif()
file(READ ${file} existing)
string(FIND ${existing} ${line_ending} last_newline REVERSE)
string(LENGTH ${existing} length)
math(EXPR length "${length}-1")
if(NOT length EQUAL last_newline) # file doesn't end with a newline
file(APPEND "${file}" "${line_ending}")
endif()
file(APPEND "${file}" "${line}${line_ending}")
endfunction()
# Add one or more linker scripts to the target, including a link-time dependency
#
# Automatically adds a -L search path for the containing directory (if found),
# and then adds -T with the filename only. This allows INCLUDE directives to be
# used to include other linker scripts in the same directory.
function(target_linker_script target)
foreach(scriptfile ${ARGN})
get_filename_component(abs_script "${scriptfile}" ABSOLUTE)
message(STATUS "Adding linker script ${abs_script}")
get_filename_component(search_dir "${abs_script}" DIRECTORY)
get_filename_component(scriptname "${abs_script}" NAME)
get_target_property(link_libraries "${target}" LINK_LIBRARIES)
list(FIND "${link_libraries}" "-L ${search_dir}" found_search_dir)
if(found_search_dir EQUAL "-1") # not already added as a search path
target_link_libraries("${target}" "-L ${search_dir}")
endif()
target_link_libraries("${target}" "-T ${scriptname}")
# Note: In ESP-IDF, most targets are libraries and libary LINK_DEPENDS don't propagate to
# executable(s) the library is linked to. This is done manually in components.cmake.
set_property(TARGET "${target}" APPEND PROPERTY LINK_DEPENDS "${abs_script}")
endforeach()
endfunction()
# Convert a CMake list to a JSON list and store it in a variable
function(make_json_list list variable)
string(REPLACE ";" "\", \"" result "[ \"${list}\" ]")
set("${variable}" "${result}" PARENT_SCOPE)
endfunction()
# add_prefix
#
# Adds a prefix to each item in the specified list.
#
function(add_prefix var prefix)
foreach(elm ${ARGN})
list(APPEND newlist "${prefix}${elm}")
endforeach()
set(${var} "${newlist}" PARENT_SCOPE)
endfunction()
# fail_at_build_time
#
# Creates a phony target which fails the build and touches CMakeCache.txt to cause a cmake run next time.
#
# This is used when a missing file is required at CMake runtime, but we can't fail the build if it is not found,
# because the "menuconfig" target may be required to fix the problem.
#
# We cannot use CMAKE_CONFIGURE_DEPENDS instead because it only works for files which exist at CMake runtime.
#
function(fail_at_build_time target_name message_line0)
set(message_lines COMMAND ${CMAKE_COMMAND} -E echo "${message_line0}")
foreach(message_line ${ARGN})
set(message_lines ${message_lines} COMMAND ${CMAKE_COMMAND} -E echo "${message_line}")
endforeach()
add_custom_target(${target_name} ALL
${message_lines}
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_BINARY_DIR}/CMakeCache.txt"
COMMAND ${CMAKE_COMMAND} -P ${IDF_PATH}/tools/cmake/scripts/fail.cmake
VERBATIM)
endfunction()