]> granicus.if.org Git - esp-idf/blob - tools/cmake/utilities.cmake
Merge branch 'docs/wifi_correct_mistake_in_csi_doc' into 'master'
[esp-idf] / tools / cmake / utilities.cmake
1 # set_default
2 #
3 # Define a variable to a default value if otherwise unset.
4 #
5 # Priority for new value is:
6 # - Existing cmake value (ie set with cmake -D, or already set in CMakeLists)
7 # - Value of any non-empty environment variable of the same name
8 # - Default value as provided to function
9 #
10 function(set_default variable default_value)
11     if(NOT ${variable})
12         if(DEFINED ENV{${variable}} AND NOT "$ENV{${variable}}" STREQUAL "")
13             set(${variable} $ENV{${variable}} PARENT_SCOPE)
14         else()
15             set(${variable} ${default_value} PARENT_SCOPE)
16         endif()
17     endif()
18 endfunction()
19
20 # spaces2list
21 #
22 # Take a variable whose value was space-delimited values, convert to a cmake
23 # list (semicolon-delimited)
24 #
25 # Note: if using this for directories, keeps the issue in place that
26 # directories can't contain spaces...
27 #
28 # TODO: look at cmake separate_arguments, which is quote-aware
29 function(spaces2list variable_name)
30     string(REPLACE " " ";" tmp "${${variable_name}}")
31     set("${variable_name}" "${tmp}" PARENT_SCOPE)
32 endfunction()
33
34 # lines2list
35 #
36 # Take a variable with multiple lines of output in it, convert it
37 # to a cmake list (semicolon-delimited), one line per item
38 #
39 function(lines2list variable_name)
40     string(REGEX REPLACE "\r?\n" ";" tmp "${${variable_name}}")
41     string(REGEX REPLACE ";;" ";" tmp "${tmp}")
42     set("${variable_name}" "${tmp}" PARENT_SCOPE)
43 endfunction()
44
45
46 # move_if_different
47 #
48 # If 'source' has different md5sum to 'destination' (or destination
49 # does not exist, move it across.
50 #
51 # If 'source' has the same md5sum as 'destination', delete 'source'.
52 #
53 # Avoids timestamp updates for re-generated files where content hasn't
54 # changed.
55 function(move_if_different source destination)
56     set(do_copy 1)
57     file(GLOB dest_exists ${destination})
58     if(dest_exists)
59         file(MD5 ${source} source_md5)
60         file(MD5 ${destination} dest_md5)
61         if(source_md5 STREQUAL dest_md5)
62             set(do_copy "")
63         endif()
64     endif()
65
66     if(do_copy)
67         message("Moving ${source} -> ${destination}")
68         file(RENAME ${source} ${destination})
69     else()
70         message("Not moving ${source} -> ${destination}")
71         file(REMOVE ${source})
72     endif()
73
74 endfunction()
75
76
77 # add_compile_options variant for C++ code only
78 #
79 # This adds global options, set target properties for
80 # component-specific flags
81 function(add_cxx_compile_options)
82     foreach(option ${ARGV})
83         # note: the Visual Studio Generator doesn't support this...
84         add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${option}>)
85     endforeach()
86 endfunction()
87
88 # add_compile_options variant for C code only
89 #
90 # This adds global options, set target properties for
91 # component-specific flags
92 function(add_c_compile_options)
93     foreach(option ${ARGV})
94         # note: the Visual Studio Generator doesn't support this...
95         add_compile_options($<$<COMPILE_LANGUAGE:C>:${option}>)
96     endforeach()
97 endfunction()
98
99
100 # target_add_binary_data adds binary data into the built target,
101 # by converting it to a generated source file which is then compiled
102 # to a binary object as part of the build
103 function(target_add_binary_data target embed_file embed_type)
104
105     get_filename_component(embed_file "${embed_file}" ABSOLUTE)
106
107     get_filename_component(name "${embed_file}" NAME)
108     set(embed_srcfile "${CMAKE_BINARY_DIR}/${name}.S")
109
110     add_custom_command(OUTPUT "${embed_srcfile}"
111         COMMAND "${CMAKE_COMMAND}"
112         -D "DATA_FILE=${embed_file}"
113         -D "SOURCE_FILE=${embed_srcfile}"
114         -D "FILE_TYPE=${embed_type}"
115         -P "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
116         MAIN_DEPENDENCY "${embed_file}"
117         DEPENDENCIES "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
118         WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
119
120     set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${embed_srcfile}")
121
122     target_sources("${target}" PRIVATE "${embed_srcfile}")
123 endfunction()
124
125 macro(include_if_exists path)
126     if(EXISTS "${path}")
127         include("${path}")
128     endif()
129 endmacro()
130
131 # Append a single line to the file specified
132 # The line ending is determined by the host OS
133 function(file_append_line file line)
134     if(DEFINED ENV{MSYSTEM} OR CMAKE_HOST_WIN32)
135         set(line_ending "\r\n")
136     else() # unix
137         set(line_ending "\n")
138     endif()
139     file(READ ${file} existing)
140     string(FIND ${existing} ${line_ending} last_newline REVERSE)
141     string(LENGTH ${existing} length)
142     math(EXPR length "${length}-1")
143     if(NOT length EQUAL last_newline) # file doesn't end with a newline
144         file(APPEND "${file}" "${line_ending}")
145     endif()
146     file(APPEND "${file}" "${line}${line_ending}")
147 endfunction()
148
149 # Add one or more linker scripts to the target, including a link-time dependency
150 #
151 # Automatically adds a -L search path for the containing directory (if found),
152 # and then adds -T with the filename only. This allows INCLUDE directives to be
153 # used to include other linker scripts in the same directory.
154 function(target_linker_script target)
155     foreach(scriptfile ${ARGN})
156         get_filename_component(abs_script "${scriptfile}" ABSOLUTE)
157         message(STATUS "Adding linker script ${abs_script}")
158
159         get_filename_component(search_dir "${abs_script}" DIRECTORY)
160         get_filename_component(scriptname "${abs_script}" NAME)
161
162         get_target_property(link_libraries "${target}" LINK_LIBRARIES)
163         list(FIND "${link_libraries}" "-L ${search_dir}" found_search_dir)
164         if(found_search_dir EQUAL "-1")  # not already added as a search path
165             target_link_libraries("${target}" "-L ${search_dir}")
166         endif()
167
168         target_link_libraries("${target}" "-T ${scriptname}")
169
170         # Note: In ESP-IDF, most targets are libraries and libary LINK_DEPENDS don't propagate to
171         # executable(s) the library is linked to. This is done manually in components.cmake.
172         set_property(TARGET "${target}" APPEND PROPERTY LINK_DEPENDS "${abs_script}")
173     endforeach()
174 endfunction()
175
176 # Convert a CMake list to a JSON list and store it in a variable
177 function(make_json_list list variable)
178     string(REPLACE ";" "\", \"" result "[ \"${list}\" ]")
179     set("${variable}" "${result}" PARENT_SCOPE)
180 endfunction()
181
182 # add_prefix
183 #
184 # Adds a prefix to each item in the specified list.
185 #
186 function(add_prefix var prefix)
187     foreach(elm ${ARGN})
188         list(APPEND newlist "${prefix}${elm}")
189     endforeach()
190     set(${var} "${newlist}" PARENT_SCOPE)
191 endfunction()