CMAKE: generalize the 64-bit suffixed-source generator
SUFFIX is now a required argument and an optional SYMBOL_ALLOWLIST restricts the renaming to the listed symbols (needed by the upcoming LAPACKE test suite). All 3523 generated _64 sources stay byte-identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f0f3e5f9a8
commit
3705542eac
@@ -1,22 +1,34 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
set(EXTENDED_API_GENERATOR
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Generate64BitSuffixedSource.cmake" CACHE INTERNAL
|
||||
"Script that generates 64-bit suffixed sources for the extended API")
|
||||
"${CMAKE_CURRENT_LIST_DIR}/GenerateSuffixedSource.cmake" CACHE INTERNAL
|
||||
"Script that generates suffixed sources for extended APIs")
|
||||
|
||||
if(BUILD_INDEX64_EXT_API)
|
||||
add_custom_target(64bit_codegen ALL
|
||||
COMMENT "Generating 64-bit suffixed sources for extended API")
|
||||
endif()
|
||||
|
||||
# Generate 64-bit suffixed sources for the extended API. The generation happens
|
||||
# at build time in the Generate64BitSuffixedSource.cmake script.
|
||||
function(generate_64bit_suffixed_sources target source_list generated_sources)
|
||||
# Generate suffixed sources for an extended API. The generation happens at
|
||||
# build time in the GenerateSuffixedSource.cmake script. Arguments:
|
||||
# SUFFIX <suffix> -- suffix appended to symbols and file names
|
||||
# (required)
|
||||
# SYMBOL_ALLOWLIST <sym>... -- only rename the listed symbols
|
||||
# (case-insensitive); by default every symbol
|
||||
# defined in the sources is renamed
|
||||
# NO_STRING_REPLACEMENTS -- do not rename symbols inside string literals
|
||||
function(generate_suffixed_sources target source_list generated_sources)
|
||||
set(options NO_STRING_REPLACEMENTS)
|
||||
cmake_parse_arguments(PARSE_ARGV 3 extended_api "${options}" "" "")
|
||||
set(oneValueArgs SUFFIX)
|
||||
set(multiValueArgs SYMBOL_ALLOWLIST)
|
||||
cmake_parse_arguments(PARSE_ARGV 3 extended_api "${options}" "${oneValueArgs}" "${multiValueArgs}")
|
||||
|
||||
get_filename_component(destination "${target}_64_sources" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
get_property(_generated_64bit_source_files GLOBAL PROPERTY EXTENDED_API_GENERATED_SOURCE_FILES)
|
||||
if(NOT DEFINED extended_api_SUFFIX)
|
||||
message(FATAL_ERROR "generate_suffixed_sources: SUFFIX is required")
|
||||
endif()
|
||||
|
||||
get_filename_component(destination "${target}${extended_api_SUFFIX}_sources" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
get_property(_generated_suffixed_source_files GLOBAL PROPERTY EXTENDED_API_GENERATED_SOURCE_FILES)
|
||||
set(new_generated_source_files)
|
||||
set(generated_source_files)
|
||||
|
||||
@@ -24,7 +36,7 @@ function(generate_64bit_suffixed_sources target source_list generated_sources)
|
||||
get_filename_component(source_abs "${_source}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
get_filename_component(source_name "${_source}" NAME_WLE)
|
||||
get_filename_component(source_ext "${_source}" EXT)
|
||||
set(output_file "${destination}/${source_name}_64${source_ext}")
|
||||
set(output_file "${destination}/${source_name}${extended_api_SUFFIX}${source_ext}")
|
||||
|
||||
set(_fortran_extensions ".f" ".F" ".f90" ".F90")
|
||||
if(NOT source_ext IN_LIST _fortran_extensions)
|
||||
@@ -33,13 +45,21 @@ function(generate_64bit_suffixed_sources target source_list generated_sources)
|
||||
endif()
|
||||
|
||||
# Make sure we only have one custom command generating a given output file
|
||||
if(NOT "${output_file}" IN_LIST _generated_64bit_source_files)
|
||||
if(NOT "${output_file}" IN_LIST _generated_suffixed_source_files)
|
||||
set(generator_args
|
||||
"-DINPUT_FILE=${source_abs}"
|
||||
"-DOUTPUT_FILE=${output_file}")
|
||||
"-DOUTPUT_FILE=${output_file}"
|
||||
"-DSUFFIX=${extended_api_SUFFIX}")
|
||||
if(extended_api_NO_STRING_REPLACEMENTS)
|
||||
list(APPEND generator_args "-DREPLACE_IN_STRINGS=OFF")
|
||||
endif()
|
||||
if(DEFINED extended_api_SYMBOL_ALLOWLIST)
|
||||
# Join with $<SEMICOLON> so that the allowlist stays one -D argument
|
||||
# on the command line but still reaches the script as a CMake list.
|
||||
# An allowlist change re-runs the generation (the command changes).
|
||||
list(JOIN extended_api_SYMBOL_ALLOWLIST "$<SEMICOLON>" _symbol_allowlist)
|
||||
list(APPEND generator_args "-DSYMBOL_ALLOWLIST=${_symbol_allowlist}")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${output_file}"
|
||||
@@ -50,7 +70,7 @@ function(generate_64bit_suffixed_sources target source_list generated_sources)
|
||||
DEPENDS
|
||||
"${source_abs}"
|
||||
"${EXTENDED_API_GENERATOR}"
|
||||
COMMENT "Generating 64-bit extended API source for ${_source}"
|
||||
COMMENT "Generating ${extended_api_SUFFIX} extended API source for ${_source}"
|
||||
VERBATIM)
|
||||
|
||||
list(APPEND new_generated_source_files "${output_file}")
|
||||
@@ -62,13 +82,32 @@ function(generate_64bit_suffixed_sources target source_list generated_sources)
|
||||
# Make sure each generated source file is only part of one target to
|
||||
# avoid multiple targets trying to generate the same file
|
||||
if(new_generated_source_files)
|
||||
add_custom_target("${target}_64bit_codegen" ALL
|
||||
add_custom_target("${target}${extended_api_SUFFIX}_codegen" ALL
|
||||
DEPENDS ${new_generated_source_files}
|
||||
COMMENT "Generating 64-bit suffixed sources for target ${target}")
|
||||
add_dependencies(64bit_codegen "${target}_64bit_codegen")
|
||||
COMMENT "Generating ${extended_api_SUFFIX} suffixed sources for target ${target}")
|
||||
if(extended_api_SUFFIX STREQUAL "_64" AND TARGET 64bit_codegen)
|
||||
add_dependencies(64bit_codegen "${target}${extended_api_SUFFIX}_codegen")
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY EXTENDED_API_GENERATED_SOURCE_FILES ${new_generated_source_files})
|
||||
endif()
|
||||
|
||||
set(${generated_sources} ${generated_source_files} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Generate 64-bit suffixed sources for the extended API. Kept as a thin
|
||||
# wrapper around generate_suffixed_sources for the Index-64 extended API.
|
||||
function(generate_64bit_suffixed_sources target source_list generated_sources)
|
||||
set(options NO_STRING_REPLACEMENTS)
|
||||
cmake_parse_arguments(PARSE_ARGV 3 extended_api "${options}" "" "")
|
||||
|
||||
set(_forwarded_options)
|
||||
if(extended_api_NO_STRING_REPLACEMENTS)
|
||||
list(APPEND _forwarded_options NO_STRING_REPLACEMENTS)
|
||||
endif()
|
||||
|
||||
generate_suffixed_sources("${target}" "${source_list}" _generated_source_files
|
||||
SUFFIX "_64" ${_forwarded_options})
|
||||
|
||||
set(${generated_sources} ${_generated_source_files} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -10,6 +10,22 @@ if(NOT DEFINED REPLACE_IN_STRINGS)
|
||||
set(REPLACE_IN_STRINGS ON)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED SUFFIX)
|
||||
message(FATAL_ERROR "SUFFIX must be set")
|
||||
endif()
|
||||
|
||||
# Optional allowlist: if given, only the listed symbols (case-insensitive)
|
||||
# are suffixed. Used to route a subset of the routines to alternative
|
||||
# implementations (e.g. LAPACKE test wrappers) while all other references
|
||||
# keep resolving to their default implementation.
|
||||
if(DEFINED SYMBOL_ALLOWLIST)
|
||||
set(_symbol_allowlist)
|
||||
foreach(_allowlist_entry IN LISTS SYMBOL_ALLOWLIST)
|
||||
string(TOLOWER "${_allowlist_entry}" _allowlist_entry)
|
||||
list(APPEND _symbol_allowlist "${_allowlist_entry}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Check whether the input file is fixed or free form based on its extension.
|
||||
get_filename_component(input_extension "${INPUT_FILE}" LAST_EXT)
|
||||
string(TOLOWER "${input_extension}" input_extension_lower)
|
||||
@@ -279,7 +295,7 @@ function(_protect_fortran_string_literals input_text result count_result)
|
||||
string(REGEX MATCHALL "${string_literal_regex}" string_literals
|
||||
"${current_line}")
|
||||
foreach(string_literal IN LISTS string_literals)
|
||||
set(placeholder "@@LAPACK_64_STRING_LITERAL_${literal_count}@@")
|
||||
set(placeholder "@@LAPACK_SUFFIX_STRING_LITERAL_${literal_count}@@")
|
||||
string(REPLACE "${string_literal}" "${placeholder}" current_line
|
||||
"${current_line}")
|
||||
set(protected_string_literal_${literal_count} "${string_literal}"
|
||||
@@ -304,7 +320,7 @@ function(_restore_fortran_string_literals input_text literal_count result)
|
||||
if(literal_count GREATER 0)
|
||||
math(EXPR last_literal_index "${literal_count} - 1")
|
||||
foreach(index RANGE 0 ${last_literal_index})
|
||||
set(placeholder "@@LAPACK_64_STRING_LITERAL_${index}@@")
|
||||
set(placeholder "@@LAPACK_SUFFIX_STRING_LITERAL_${index}@@")
|
||||
string(REPLACE "${placeholder}" "${protected_string_literal_${index}}"
|
||||
output_text "${output_text}")
|
||||
endforeach()
|
||||
@@ -382,6 +398,19 @@ endwhile()
|
||||
list(REMOVE_DUPLICATES symbol_names)
|
||||
list(REMOVE_ITEM symbol_names ETIME etime ETIME_ etime_)
|
||||
|
||||
# Restrict the renaming to allowlisted symbols if an allowlist was given
|
||||
if(DEFINED SYMBOL_ALLOWLIST)
|
||||
set(_filtered_symbol_names)
|
||||
foreach(symbol_name IN LISTS symbol_names)
|
||||
string(TOLOWER "${symbol_name}" _symbol_name_lower)
|
||||
list(FIND _symbol_allowlist "${_symbol_name_lower}" _symbol_allowlist_index)
|
||||
if(NOT _symbol_allowlist_index EQUAL -1)
|
||||
list(APPEND _filtered_symbol_names "${symbol_name}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(symbol_names ${_filtered_symbol_names})
|
||||
endif()
|
||||
|
||||
# If string literals should not be modified, protect them before performing replacements
|
||||
if(NOT REPLACE_IN_STRINGS)
|
||||
_protect_fortran_string_literals(
|
||||
@@ -394,7 +423,7 @@ foreach(symbol_name IN LISTS symbol_names)
|
||||
string(TOUPPER "${symbol_name}" symbol_upper)
|
||||
foreach(symbol_variant "${symbol_name}" "${symbol_lower}" "${symbol_upper}")
|
||||
set(match_regex "(^|[^A-Za-z0-9_])${symbol_variant}([^A-Za-z0-9_]|$)")
|
||||
set(replacement "\\1${symbol_variant}_64\\2")
|
||||
set(replacement "\\1${symbol_variant}${SUFFIX}\\2")
|
||||
string(REGEX REPLACE
|
||||
"${match_regex}" "${replacement}"
|
||||
rewritten_content "${rewritten_content}")
|
||||
Reference in New Issue
Block a user