Jim Cownie | 3b81ce6 | 2014-08-05 09:32:28 +0000 | [diff] [blame] | 1 | # |
| 2 | #//===----------------------------------------------------------------------===// |
| 3 | #// |
| 4 | #// The LLVM Compiler Infrastructure |
| 5 | #// |
| 6 | #// This file is dual licensed under the MIT and the University of Illinois Open |
| 7 | #// Source Licenses. See LICENSE.txt for details. |
| 8 | #// |
| 9 | #//===----------------------------------------------------------------------===// |
| 10 | # |
| 11 | |
| 12 | ####################################### FUNCTIONS/MACROS ########################################### |
| 13 | # It should be noted that in cmake, functions can only be used on a single line with the return value |
| 14 | # stored in a parameter you send to the function. There isn't a true return value. So technically, |
| 15 | # all functions would have a C/C++ prototype of: |
| 16 | # void function_name(parameter1, parameter2, ...); |
| 17 | # |
| 18 | # If you want a return value, you have to use a parameter so the function prototype would be: |
| 19 | # void function_name(input_parameter1, input_parameter2, ..., return_value) |
| 20 | # ################## |
| 21 | |
| 22 | # void say(string message_to_user); |
| 23 | # - prints out message_to_user |
| 24 | macro(say message_to_user) |
Andrey Churbanov | 648467e | 2015-05-05 20:02:52 +0000 | [diff] [blame] | 25 | message(STATUS "${message_to_user}") |
Jim Cownie | 3b81ce6 | 2014-08-05 09:32:28 +0000 | [diff] [blame] | 26 | endmacro() |
| 27 | |
| 28 | # void warning_say(string message_to_user); |
| 29 | # - prints out message_to_user with a warning |
| 30 | macro(warning_say message_to_user) |
| 31 | message(WARNING "${message_to_user}") |
| 32 | endmacro() |
| 33 | |
| 34 | # void error_say(string message_to_user); |
| 35 | # - prints out message_to_user with an error and exits cmake |
| 36 | macro(error_say message_to_user) |
| 37 | message(FATAL_ERROR "${message_to_user}") |
| 38 | endmacro() |
| 39 | |
| 40 | # void debug_say(string message_to_developer); |
| 41 | # - prints out message when GLOBAL_DEBUG == 1 (for debugging cmake build) |
| 42 | macro(debug_say message_to_developer) |
| 43 | if(${GLOBAL_DEBUG} STREQUAL "1") |
| 44 | say("DEBUG: ${message_to_developer}") |
| 45 | endif() |
| 46 | endmacro() |
| 47 | |
| 48 | # void debug_say_var(variable var); |
| 49 | # - prints the variable name and its value (for debugging cmake build) |
| 50 | macro(debug_say_var var) |
| 51 | if(${GLOBAL_DEBUG} STREQUAL "1") |
| 52 | say("DEBUG: Variable: ${var} = ${${var}} ") |
| 53 | endif() |
| 54 | endmacro() |
| 55 | |
| 56 | # void set_legal_arch(string* return_arch_string); |
| 57 | # - returns (through return_arch_string) the formal architecture |
| 58 | # string or warns user of unknown architecture |
| 59 | function(set_legal_arch return_arch_string) |
| 60 | if(${IA32}) |
| 61 | set(${return_arch_string} "IA-32" PARENT_SCOPE) |
| 62 | elseif(${INTEL64}) |
| 63 | set(${return_arch_string} "Intel(R) 64" PARENT_SCOPE) |
| 64 | elseif(${MIC}) |
| 65 | set(${return_arch_string} "Intel(R) Many Integrated Core Architecture" PARENT_SCOPE) |
Andrey Churbanov | 7af7c8d | 2015-05-25 20:01:16 +0000 | [diff] [blame] | 66 | elseif(${LIBOMP_ARCH} STREQUAL "l1") |
Jim Cownie | 3b81ce6 | 2014-08-05 09:32:28 +0000 | [diff] [blame] | 67 | set(${return_arch_string} "L1OM" PARENT_SCOPE) |
| 68 | elseif(${ARM}) |
| 69 | set(${return_arch_string} "ARM" PARENT_SCOPE) |
Andrey Churbanov | d1c5504 | 2015-01-19 18:29:35 +0000 | [diff] [blame] | 70 | elseif(${PPC64BE}) |
| 71 | set(${return_arch_string} "PPC64BE" PARENT_SCOPE) |
| 72 | elseif(${PPC64LE}) |
| 73 | set(${return_arch_string} "PPC64LE" PARENT_SCOPE) |
Andrey Churbanov | cbda868 | 2015-01-13 14:43:35 +0000 | [diff] [blame] | 74 | elseif(${AARCH64}) |
| 75 | set(${return_arch_string} "AARCH64" PARENT_SCOPE) |
Jim Cownie | 3b81ce6 | 2014-08-05 09:32:28 +0000 | [diff] [blame] | 76 | else() |
| 77 | warning_say("set_legal_arch(): Warning: Unknown architecture...") |
| 78 | endif() |
| 79 | endfunction() |
| 80 | |
| 81 | # void check_variable(string var, string var_name, list<string>values_list); |
| 82 | # - runs through values_list checking if ${var} == values_list[i] for any i. |
| 83 | # - if the var is found, then just print it out |
| 84 | # - if the var is not found, then warn user |
| 85 | function(check_variable var values_list) |
| 86 | set(valid_flag 0) |
| 87 | foreach(value IN LISTS values_list) |
| 88 | if("${${var}}" STREQUAL "${value}") |
| 89 | set(valid_flag 1) |
| 90 | set(the_value "${value}") |
| 91 | endif() |
| 92 | endforeach() |
| 93 | if(${valid_flag} EQUAL 0) |
| 94 | error_say("check_variable(): ${var} = ${${var}} is unknown") |
| 95 | endif() |
| 96 | endfunction() |
| 97 | |
| 98 | # void _export_lib_dir(string export_dir, string platform, string suffix, string* return_value); |
| 99 | # - basically a special case for mac platforms where it adds '.thin' to the output lib directory |
| 100 | function(_export_lib_dir pltfrm return_value) |
| 101 | if(${MAC}) |
| 102 | set(${return_value} "${export_dir}/${pltfrm}${suffix}/lib.thin" PARENT_SCOPE) |
| 103 | else() |
| 104 | set(${return_value} "${export_dir}/${pltfrm}${suffix}/lib" PARENT_SCOPE) |
| 105 | endif() |
| 106 | endfunction() |
| 107 | |
| 108 | # void _export_lib_fat_dir(string export_dir, string platform, string suffix, string* return_value); |
| 109 | # - another mac specialty case for fat libraries. |
| 110 | # - this sets export_lib_fat_dir in the MAIN part of CMakeLists.txt |
| 111 | function(_export_lib_fat_dir pltfrm return_value) |
| 112 | set(${return_value} "${export_dir}/${pltfrm}${suffix}/lib" PARENT_SCOPE) |
| 113 | endfunction() |
| 114 | |
| 115 | # void get_build_number(string src_dir, string* return_build_number); |
| 116 | # - grab the eight digit build number (or 00000000) from kmp_version.c |
| 117 | function(get_build_number src_dir return_build_number) |
| 118 | # sets file_lines_list to a list of all lines in kmp_version.c |
| 119 | file(STRINGS "${src_dir}/src/kmp_version.c" file_lines_list) |
| 120 | |
| 121 | # runs through each line in kmp_version.c |
| 122 | foreach(line IN LISTS file_lines_list) |
| 123 | # if the line begins with "#define KMP_VERSION_BUILD" then we take not of the build number |
| 124 | string(REGEX MATCH "^[ \t]*#define[ \t]+KMP_VERSION_BUILD" valid "${line}") |
| 125 | if(NOT "${valid}" STREQUAL "") # if we matched "#define KMP_VERSION_BUILD", then grab the build number |
| 126 | string(REGEX REPLACE "^[ \t]*#define[ \t]+KMP_VERSION_BUILD[ \t]+([0-9]+)" "\\1" |
| 127 | build_number "${line}" |
| 128 | ) |
| 129 | endif() |
| 130 | endforeach() |
| 131 | set(${return_build_number} "${build_number}" PARENT_SCOPE) # return build number |
| 132 | endfunction() |
| 133 | |
| 134 | # void set_legal_type(string* return_legal_type); |
| 135 | # - set the legal type name Performance/Profiling/Stub |
| 136 | function(set_legal_type return_legal_type) |
| 137 | if(${NORMAL_LIBRARY}) |
| 138 | set(${return_legal_type} "Performance" PARENT_SCOPE) |
| 139 | elseif(${PROFILE_LIBRARY}) |
| 140 | set(${return_legal_type} "Profiling" PARENT_SCOPE) |
| 141 | elseif(${STUBS_LIBRARY}) |
| 142 | set(${return_legal_type} "Stub" PARENT_SCOPE) |
| 143 | endif() |
| 144 | endfunction() |
| 145 | |
| 146 | # void set_mac_os_new(bool* return_mac_os_new); |
| 147 | # - sets the return_mac_os_new variable to true or false based on macosx version |
| 148 | # - no real "cmakey" way to do this. Have to call execute_process() |
| 149 | function(set_mac_os_new return_mac_os_new) |
| 150 | execute_process(COMMAND "sw_vers" "-productVersion" OUTPUT_VARIABLE mac_osx_version) |
| 151 | if("${mac_osx_version}" VERSION_GREATER "10.6") |
| 152 | set(${return_mac_os_new} TRUE PARENT_SCOPE) |
| 153 | else() |
| 154 | set(${return_mac_os_new} FALSE PARENT_SCOPE) |
| 155 | endif() |
| 156 | endfunction() |
| 157 | |
| 158 | # void add_prefix(string prefix, list<string>* list_of_items); |
| 159 | # - returns list_of_items with prefix prepended to all items |
| 160 | # - original list is modified |
| 161 | function(add_prefix prefix list_of_items) |
| 162 | set(local_list "") |
| 163 | foreach(item IN LISTS "${list_of_items}") |
| 164 | if(NOT "${item}" STREQUAL "") |
| 165 | list(APPEND local_list "${prefix}${item}") |
| 166 | endif() |
| 167 | endforeach() |
| 168 | set(${list_of_items} "${local_list}" PARENT_SCOPE) |
| 169 | endfunction() |
| 170 | |
| 171 | # void add_suffix(string suffix, list<string>* list_of_items); |
| 172 | # - returns list_of_items with suffix appended to all items |
| 173 | # - original list is modified |
| 174 | function(add_suffix suffix list_of_items) |
| 175 | set(local_list "") |
| 176 | foreach(item IN LISTS "${list_of_items}") |
| 177 | if(NOT "${item}" STREQUAL "") |
| 178 | list(APPEND local_list "${item}${suffix}") |
| 179 | endif() |
| 180 | endforeach() |
| 181 | set(${list_of_items} "${local_list}" PARENT_SCOPE) |
| 182 | endfunction() |
| 183 | |
| 184 | # void strip_suffix(list<string> list_of_items, list<string>* return_list); |
| 185 | # - returns a new list with suffix stripped (i.e., foo.c => foo) |
| 186 | # - list_of_items is not modified, return_list is modified |
| 187 | function(strip_suffix list_of_items return_list) |
| 188 | set(local_list "") |
| 189 | foreach(item IN LISTS "${list_of_items}") |
| 190 | if(NOT "${item}" STREQUAL "") |
| 191 | get_filename_component(filename "${item}" NAME_WE) |
| 192 | list(APPEND local_list "${filename}") |
| 193 | endif() |
| 194 | endforeach() |
| 195 | set(${return_list} "${local_list}" PARENT_SCOPE) |
| 196 | endfunction() |
| 197 | |
| 198 | # void list_to_string(list<string> list_of_things, string* return_string); |
| 199 | # - converts a list to a space separated string |
| 200 | function(list_to_string list_of_things return_string) |
| 201 | string(REPLACE ";" " " output_variable "${list_of_things}") |
| 202 | set(${return_string} "${output_variable}" PARENT_SCOPE) |
| 203 | endfunction() |
| 204 | |
| 205 | # void string_to_list(string str, list<string>* return_list); |
| 206 | # - converts a string to a semicolon separated list |
| 207 | # - what it really does is just string_replace all running whitespace to a semicolon |
| 208 | # - in cmake, a list is strings separated by semicolons: i.e., list of four items, list = "item1;item2;item3;item4" |
| 209 | function(string_to_list str return_list) |
| 210 | set(outstr) |
| 211 | string(REGEX REPLACE "[ \t]+" ";" outstr "${str}") |
| 212 | set(${return_list} "${outstr}" PARENT_SCOPE) |
| 213 | endfunction() |
| 214 | |
| 215 | # void get_date(string* return_date); |
| 216 | # - returns the current date "yyyy-mm-dd hh:mm:ss UTC" |
| 217 | # - this function alone causes the need for CMake v2.8.11 (TIMESTAMP) |
| 218 | #function(get_date return_date) |
| 219 | # string(TIMESTAMP local_date "%Y-%m-%d %H:%M:%S UTC" UTC) |
| 220 | # set(${return_date} ${local_date} PARENT_SCOPE) |
| 221 | #endfunction() |
| 222 | |
| 223 | # void find_a_program(string program_name, list<string> extra_paths, bool fail_on_not_found, string return_variable_name); |
| 224 | # - returns the full path of a program_name |
| 225 | # - first looks in the list of extra_paths |
| 226 | # - if not found in extra_paths, then look through system path |
| 227 | # - errors out if fail_on_not_found == true and cmake could not find program_name. |
| 228 | function(find_a_program program_name extra_paths fail_on_not_found return_variable_name) |
| 229 | # first try to find the program in the extra_paths |
| 230 | find_program(${return_variable_name} "${program_name}" PATHS "${extra_paths}" DOC "Path to ${program_name}" NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) |
| 231 | if("${${return_variable_name}}" MATCHES NOTFOUND) |
| 232 | # if no extra_paths, or couldn't find it, then look in system $PATH |
| 233 | find_program(${return_variable_name} "${program_name}" DOC "Path to ${program_name}") |
| 234 | if("${${return_variable_name}}" MATCHES NOTFOUND AND ${fail_on_not_found}) |
| 235 | error_say("Error: Could not find program: ${program_name}") |
| 236 | endif() |
| 237 | endif() |
| 238 | |
| 239 | if(NOT "${${return_variable_name}}" MATCHES NOTFOUND) |
| 240 | say("-- Found ${program_name}: ${${return_variable_name}}") |
| 241 | endif() |
| 242 | |
| 243 | set(${return_variable_name} ${${return_variable_name}} PARENT_SCOPE) |
| 244 | endfunction() |
| 245 | |
| 246 | # WINDOWS SPECIFIC |
| 247 | # void replace_md_with_mt(string flags_var) |
| 248 | # - This macro replaces the /MD compiler flags (Windows specific) with /MT compiler flags |
| 249 | # - This does nothing if no /MD flags were replaced. |
| 250 | macro(replace_md_with_mt flags_var) |
| 251 | set(flags_var_name ${flags_var}) # i.e., CMAKE_C_FLAGS_RELEASE |
| 252 | set(flags_var_value ${${flags_var}}) # i.e., "/MD /O2 ..." |
| 253 | string(REPLACE /MD /MT temp_out "${flags_var_value}") |
| 254 | string(COMPARE NOTEQUAL "${temp_out}" "${flags_var_value}" something_was_replaced) |
| 255 | if("${something_was_replaced}") |
| 256 | unset(${flags_var_name} CACHE) |
| 257 | set(${flags_var_name} ${temp_out} CACHE STRING "Replaced /MD with /MT compiler flags") |
| 258 | endif() |
| 259 | endmacro() |
| 260 | |