diff --git a/BLAS/SRC/CMakeLists.txt b/BLAS/SRC/CMakeLists.txt index 501560531..b9b8be628 100644 --- a/BLAS/SRC/CMakeLists.txt +++ b/BLAS/SRC/CMakeLists.txt @@ -117,7 +117,9 @@ if(BUILD_COMPLEX16) endif() list(REMOVE_DUPLICATES SOURCES) -add_library(${BLASLIB}_obj OBJECT ${SOURCES}) +if(BUILD_DEFAULT_API) + add_library(${BLASLIB}_obj OBJECT ${SOURCES}) +endif() if(BUILD_INDEX64_EXT_API) include(ExtendedAPIHelpers) @@ -128,7 +130,7 @@ if(BUILD_INDEX64_EXT_API) endif() add_library(${BLASLIB} - $ + $<$: $> $<$: $>) # For flang, use C linker instead of Fortran linker to avoid macOS-specific flags diff --git a/CBLAS/src/CMakeLists.txt b/CBLAS/src/CMakeLists.txt index 15a82a38d..cea606dc6 100644 --- a/CBLAS/src/CMakeLists.txt +++ b/CBLAS/src/CMakeLists.txt @@ -1,7 +1,10 @@ # This Makefile compiles the CBLAS routines +# Sources that are shared accross all APIs +set(COMMON_SOURCES cblas_globals.c) + # Error handling routines for level 2 & 3 -set(ERRHAND cblas_globals.c cblas_xerbla.c xerbla.c) +set(ERRHAND cblas_xerbla.c xerbla.c) # # @@ -132,23 +135,21 @@ endif() list(REMOVE_DUPLICATES SOURCES_C) list(REMOVE_DUPLICATES SOURCES_F) -add_library(${CBLASLIB}_obj OBJECT ${SOURCES_C} ${SOURCES_F}) -if(HAS_ATTRIBUTE_WEAK_SUPPORT) - target_compile_definitions(${CBLASLIB}_obj PRIVATE - "$<$:HAS_ATTRIBUTE_WEAK_SUPPORT>") +if(BUILD_DEFAULT_API) + add_library(${CBLASLIB}_obj OBJECT ${COMMON_SOURCES} ${SOURCES_C} ${SOURCES_F}) + if(HAS_ATTRIBUTE_WEAK_SUPPORT) + target_compile_definitions(${CBLASLIB}_obj PRIVATE + "$<$:HAS_ATTRIBUTE_WEAK_SUPPORT>") + endif() +else() + add_library(${CBLASLIB}_obj OBJECT ${COMMON_SOURCES}) endif() if(BUILD_INDEX64_EXT_API) include(ExtendedAPIHelpers) - - # Define list of C files for 64bit interface - set(SOURCES_64_C ${SOURCES_C}) - list(REMOVE_ITEM SOURCES_64_C cblas_globals.c) - - # Generate list of Fortran files for 64bit interface generate_64bit_suffixed_sources(${CBLASLIB} SOURCES_F SOURCES_64_F) - add_library(${CBLASLIB}_64_obj OBJECT ${SOURCES_64_C} ${SOURCES_64_F}) + add_library(${CBLASLIB}_64_obj OBJECT ${SOURCES_C} ${SOURCES_64_F}) target_compile_definitions(${CBLASLIB}_64_obj PRIVATE "$<$:WeirdNEC>" "$<$:CBLAS_API64>") target_compile_options(${CBLASLIB}_64_obj PRIVATE diff --git a/CMAKE/ExtendedAPIHelpers.cmake b/CMAKE/ExtendedAPIHelpers.cmake index 0617bc772..0c83866f6 100644 --- a/CMAKE/ExtendedAPIHelpers.cmake +++ b/CMAKE/ExtendedAPIHelpers.cmake @@ -27,8 +27,6 @@ function(generate_64bit_suffixed_sources target source_list generated_sources) continue() endif() - message("${EXTENDED_API_GENERATOR}") - add_custom_command( OUTPUT "${output_file}" COMMAND diff --git a/CMAKE/Generate64BitSuffixedSource.cmake b/CMAKE/Generate64BitSuffixedSource.cmake index 791bb8e09..610926689 100644 --- a/CMAKE/Generate64BitSuffixedSource.cmake +++ b/CMAKE/Generate64BitSuffixedSource.cmake @@ -73,46 +73,46 @@ function(_normalize_fortran_statement_fragment line result) set(${result} "${fragment}" PARENT_SCOPE) endfunction() -# Create one logical Fortran statement by appending all continuation lines. -function(_collect_logical_fortran_line line_list_name start_index logical_line next_index) - list(GET ${line_list_name} ${start_index} current_line) - _normalize_fortran_statement_fragment("${current_line}" merged_line) - - list(LENGTH ${line_list_name} raw_line_count) - set(last_line "${current_line}") - math(EXPR current_index "${start_index} + 1") - - while(current_index LESS raw_line_count) - list(GET ${line_list_name} ${current_index} continuation_line) - _is_fortran_comment_line("${continuation_line}" continuation_is_comment) - if(continuation_is_comment) - break() - endif() - - # Check for continuation based on the form of the Fortran source - if(_rewrite_source_is_free_form) - if("${last_line}" MATCHES "&[ \t]*$" OR "${continuation_line}" MATCHES "^[ \t]*&") - _normalize_fortran_statement_fragment("${continuation_line}" continuation_fragment) - else() - break() - endif() +# Pop one physical source line from a newline-delimited string. Do not use a +# CMake list here: source comments may contain unmatched brackets, which changes +# how list semicolons are interpreted. +macro(_pop_source_line remaining_source line result) + if("${${remaining_source}}" STREQUAL "") + set(${line} "") + set(${result} FALSE) + else() + string(FIND "${${remaining_source}}" "\n" _source_line_newline_index) + if(_source_line_newline_index EQUAL -1) + set(${line} "${${remaining_source}}") + set(${remaining_source} "") else() - _is_fixed_form_continuation_line("${continuation_line}" is_fixed_form_continuation) - if(is_fixed_form_continuation) - _normalize_fortran_statement_fragment("${continuation_line}" continuation_fragment) - else() - break() - endif() + string(SUBSTRING "${${remaining_source}}" 0 + ${_source_line_newline_index} ${line}) + math(EXPR _source_line_next_index + "${_source_line_newline_index} + 1") + string(SUBSTRING "${${remaining_source}}" + ${_source_line_next_index} -1 ${remaining_source}) endif() + set(${result} TRUE) + endif() +endmacro() - string(APPEND merged_line " ${continuation_fragment}") - set(last_line "${continuation_line}") - math(EXPR current_index "${current_index} + 1") - endwhile() - - set(${logical_line} "${merged_line}" PARENT_SCOPE) - set(${next_index} ${current_index} PARENT_SCOPE) -endfunction() +# Peek at the next physical line without consuming it. +macro(_peek_source_line remaining_source line result) + if("${${remaining_source}}" STREQUAL "") + set(${line} "") + set(${result} FALSE) + else() + string(FIND "${${remaining_source}}" "\n" _source_line_newline_index) + if(_source_line_newline_index EQUAL -1) + set(${line} "${${remaining_source}}") + else() + string(SUBSTRING "${${remaining_source}}" 0 + ${_source_line_newline_index} ${line}) + endif() + set(${result} TRUE) + endif() +endmacro() # Extract function/subroutine names from one logical Fortran statement. function(_extract_symbols statement_text result) @@ -120,8 +120,9 @@ function(_extract_symbols statement_text result) if("${statement_text}" MATCHES "(external|EXTERNAL)") string(REGEX REPLACE - "^[a-zA-Z0-9_ *]*(external|EXTERNAL)[ ]*" "" + "^.*(external|EXTERNAL)[ \t]*(::)?[ \t]*" "" external_names "${statement_text}") + string(REGEX REPLACE "^[ \t]*::[ \t]*" "" external_names "${external_names}") string(REPLACE "," ";" external_names "${external_names}") foreach(external_name IN LISTS external_names) string(STRIP "${external_name}" external_name) @@ -143,6 +144,110 @@ function(_extract_symbols statement_text result) set(${result} ${symbols} PARENT_SCOPE) endfunction() +# Find a safe fixed-form split point at or before the 72-column limit. +function(_find_fixed_form_split line result) + set(split_pos -1) + set(space_pos -1) + set(index 71) + + while(index GREATER 6) + string(SUBSTRING "${line}" ${index} 1 current_char) + if(current_char STREQUAL ",") + math(EXPR split_pos "${index} + 1") + break() + elseif(space_pos LESS 0 AND current_char MATCHES "[ \t]") + set(space_pos ${index}) + endif() + math(EXPR index "${index} - 1") + endwhile() + + if(split_pos LESS 0 AND NOT space_pos LESS 0) + set(split_pos ${space_pos}) + endif() + + set(${result} ${split_pos} PARENT_SCOPE) +endfunction() + +# Wrap one fixed-form physical line so generated sources remain valid with the +# standard 72-column statement field. +function(_wrap_fixed_form_line line result) + _is_fortran_comment_line("${line}" is_comment_line) + if(is_comment_line OR "${line}" MATCHES "^#") + set(${result} "${line}" PARENT_SCOPE) + return() + endif() + + set(wrapped_line "") + set(current_line "${line}") + + while(TRUE) + string(LENGTH "${current_line}" line_length) + if(NOT line_length GREATER 72) + if(wrapped_line STREQUAL "") + set(wrapped_line "${current_line}") + else() + string(APPEND wrapped_line "\n${current_line}") + endif() + break() + endif() + + _find_fixed_form_split("${current_line}" split_pos) + if(NOT split_pos GREATER 6) + if(wrapped_line STREQUAL "") + set(wrapped_line "${current_line}") + else() + string(APPEND wrapped_line "\n${current_line}") + endif() + break() + endif() + + string(SUBSTRING "${current_line}" 0 ${split_pos} line_head) + string(SUBSTRING "${current_line}" ${split_pos} -1 line_tail) + string(STRIP "${line_tail}" line_tail) + + if(wrapped_line STREQUAL "") + set(wrapped_line "${line_head}") + else() + string(APPEND wrapped_line "\n${line_head}") + endif() + + set(current_line " $ ${line_tail}") + endwhile() + + set(${result} "${wrapped_line}" PARENT_SCOPE) +endfunction() + +function(_wrap_fixed_form_source source_text result) + if(_rewrite_source_is_free_form) + set(${result} "${source_text}" PARENT_SCOPE) + return() + endif() + + string(REPLACE "\r\n" "\n" remaining_source "${source_text}") + string(REPLACE "\r" "\n" remaining_source "${remaining_source}") + set(wrapped_source "") + + while(TRUE) + string(FIND "${remaining_source}" "\n" newline_index) + if(newline_index EQUAL -1) + if(NOT remaining_source STREQUAL "") + _wrap_fixed_form_line("${remaining_source}" wrapped_line) + string(APPEND wrapped_source "${wrapped_line}") + endif() + break() + endif() + + string(SUBSTRING "${remaining_source}" 0 ${newline_index} source_line) + math(EXPR next_index "${newline_index} + 1") + string(SUBSTRING "${remaining_source}" ${next_index} -1 remaining_source) + + _wrap_fixed_form_line("${source_line}" wrapped_line) + string(APPEND wrapped_source "${wrapped_line}\n") + endwhile() + + set(${result} "${wrapped_source}" PARENT_SCOPE) +endfunction() + get_filename_component(output_dir "${OUTPUT_FILE}" DIRECTORY) file(MAKE_DIRECTORY "${output_dir}") @@ -150,26 +255,67 @@ file(READ "${INPUT_FILE}" source_content) set(rewritten_content "${source_content}") # Extract symbol names from the source file -file(STRINGS "${INPUT_FILE}" raw_lines) +string(REPLACE "\r\n" "\n" symbol_scan_source "${source_content}") +string(REPLACE "\r" "\n" symbol_scan_source "${symbol_scan_source}") set(symbol_names) -list(LENGTH raw_lines raw_line_count) -set(line_index 0) -while(line_index LESS raw_line_count) - list(GET raw_lines ${line_index} current_line) + +while(TRUE) + _pop_source_line(symbol_scan_source current_line has_line) + if(NOT has_line) + break() + endif() + _is_fortran_comment_line("${current_line}" is_comment_line) if(is_comment_line) - math(EXPR line_index "${line_index} + 1") continue() endif() - _collect_logical_fortran_line(raw_lines ${line_index} logical_line next_index) + _normalize_fortran_statement_fragment("${current_line}" logical_line) + set(last_line "${current_line}") + + while(TRUE) + _peek_source_line(symbol_scan_source continuation_line has_line) + if(NOT has_line) + break() + endif() + + _is_fortran_comment_line("${continuation_line}" continuation_is_comment) + if(continuation_is_comment) + break() + endif() + + set(consume_continuation FALSE) + if(_rewrite_source_is_free_form) + if("${last_line}" MATCHES "&[ \t]*$" OR + "${continuation_line}" MATCHES "^[ \t]*&") + set(consume_continuation TRUE) + endif() + else() + _is_fixed_form_continuation_line("${continuation_line}" + is_fixed_form_continuation) + if(is_fixed_form_continuation) + set(consume_continuation TRUE) + endif() + endif() + + if(NOT consume_continuation) + break() + endif() + + _pop_source_line(symbol_scan_source continuation_line has_line) + _normalize_fortran_statement_fragment("${continuation_line}" + continuation_fragment) + string(APPEND logical_line " ${continuation_fragment}") + set(last_line "${continuation_line}") + endwhile() + _extract_symbols("${logical_line}" symbols) if(symbols) list(APPEND symbol_names ${symbols}) endif() - set(line_index ${next_index}) endwhile() list(REMOVE_DUPLICATES symbol_names) +list(REMOVE_ITEM symbol_names ETIME etime ETIME_ etime_) # Replace symbol names with their suffixed versions in the source content foreach(symbol_name IN LISTS symbol_names) @@ -187,6 +333,8 @@ foreach(symbol_name IN LISTS symbol_names) endforeach() endforeach() +_wrap_fixed_form_source("${rewritten_content}" rewritten_content) + if(EXISTS "${OUTPUT_FILE}") file(READ "${OUTPUT_FILE}" existing_output) endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index defdb6b92..9213ecb03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,17 +113,11 @@ else() set(TMGLIB "tmglib") endif() -# By default build extended _64 API for supported compilers only. This needs -# CMake >= 3.18! Let's disable it by default for CMake < 3.18. -if(CMAKE_VERSION VERSION_LESS "3.18") - set(INDEX64_EXT_API_DEFAULT OFF) -else() - set(INDEX64_EXT_API_DEFAULT ON) -endif() -set(INDEX64_EXT_API_COMPILERS "Intel|GNU") -option(BUILD_INDEX64_EXT_API - "Build Index-64 API as extended API with _64 suffix (needs CMake >= 3.18)" - ${INDEX64_EXT_API_DEFAULT}) +option(BUILD_DEFAULT_API "Build default API. Disable and combine with -DBUILD_INDEX64_EXT_API=ON to build only extended API" ON) +message(STATUS "Build default API: ${BUILD_DEFAULT_API}") + +# By default build extended _64 API for supported compilers only. +option(BUILD_INDEX64_EXT_API "Build Index-64 API as extended API with _64 suffix" ON) message(STATUS "Build Index-64 API as extended API with _64 suffix: ${BUILD_INDEX64_EXT_API}") include(GNUInstallDirs) diff --git a/LAPACKE/CMakeLists.txt b/LAPACKE/CMakeLists.txt index 91ed61b3b..186f7c76a 100644 --- a/LAPACKE/CMakeLists.txt +++ b/LAPACKE/CMakeLists.txt @@ -33,6 +33,7 @@ message(STATUS "Build LAPACKE double precision real: ${LAPACKE_BUILD_DOUBLE}") message(STATUS "Build LAPACKE single precision complex: ${LAPACKE_BUILD_COMPLEX}") message(STATUS "Build LAPACKE double precision complex: ${LAPACKE_BUILD_COMPLEX16}") +append_subdir_files(COMMON_SOURCES "src") append_subdir_files(SOURCES "src") if (LAPACKE_BUILD_SINGLE) append_subdir_files(SOURCES_SINGLE "src") @@ -54,6 +55,7 @@ append_subdir_files(DEPRECATED "src") append_subdir_files(EXTENDED "src") append_subdir_files(MATGEN "src") append_subdir_files(UTILS "utils") +append_subdir_files(COMMON_UTILS "utils") if(BUILD_DEPRECATED) list(APPEND SOURCES ${DEPRECATED}) @@ -66,17 +68,14 @@ if(LAPACKE_WITH_TMG) endif() list(APPEND SOURCES ${UTILS}) -add_library(${LAPACKELIB}_obj OBJECT ${SOURCES}) +if(BUILD_DEFAULT_API) + add_library(${LAPACKELIB}_obj OBJECT ${COMMON_SOURCES} ${COMMON_UTILS} ${SOURCES}) +else() + add_library(${LAPACKELIB}_obj OBJECT ${COMMON_SOURCES} ${COMMON_UTILS}) +endif() if(BUILD_INDEX64_EXT_API) - # 64bit Integer Extended Interface - set(SOURCES_64 ${SOURCES}) - list(REMOVE_ITEM SOURCES_64 - src/lapacke_nancheck.c - utils/lapacke_make_complex_float.c - utils/lapacke_make_complex_double.c) - - add_library(${LAPACKELIB}_64_obj OBJECT ${SOURCES_64}) + add_library(${LAPACKELIB}_64_obj OBJECT ${SOURCES}) target_compile_definitions(${LAPACKELIB}_64_obj PRIVATE LAPACK_ILP64 LAPACKE_API64 WeirdNEC CBLAS_API64) endif() diff --git a/LAPACKE/src/CMakeLists.txt b/LAPACKE/src/CMakeLists.txt index 45307c180..a46bc5b77 100644 --- a/LAPACKE/src/CMakeLists.txt +++ b/LAPACKE/src/CMakeLists.txt @@ -1203,8 +1203,10 @@ lapacke_dtzrzf.c lapacke_dtzrzf_work.c ) -set(SOURCES +set(COMMON_SOURCES lapacke_nancheck.c +) +set(SOURCES lapacke_ilaver.c ) set(SOURCES_SINGLE diff --git a/LAPACKE/utils/CMakeLists.txt b/LAPACKE/utils/CMakeLists.txt index dfb9aa370..9c26984b7 100644 --- a/LAPACKE/utils/CMakeLists.txt +++ b/LAPACKE/utils/CMakeLists.txt @@ -1,3 +1,5 @@ +set(COMMON_UTILS lapacke_make_complex_float.c lapacke_make_complex_double.c) + set(UTILS lapacke_c_nancheck.c lapacke_d_nancheck.c lapacke_s_nancheck.c lapacke_z_nancheck.c lapacke_cgb_nancheck.c lapacke_dgb_nancheck.c lapacke_sgb_nancheck.c lapacke_zgb_trans.c @@ -39,8 +41,6 @@ lapacke_ctr_nancheck.c lapacke_dtr_nancheck.c lapacke_str_nancheck lapacke_ctr_trans.c lapacke_dtr_trans.c lapacke_str_trans.c lapacke_ztr_trans.c lapacke_ctz_nancheck.c lapacke_dtz_nancheck.c lapacke_stz_nancheck.c lapacke_ztz_nancheck.c lapacke_ctz_trans.c lapacke_dtz_trans.c lapacke_stz_trans.c lapacke_ztz_trans.c - -lapacke_make_complex_float.c lapacke_make_complex_double.c lapacke_lsame.c lapacke_xerbla.c ) diff --git a/TESTING/MATGEN/CMakeLists.txt b/TESTING/MATGEN/CMakeLists.txt index 96ad04e43..7bd2f9425 100644 --- a/TESTING/MATGEN/CMakeLists.txt +++ b/TESTING/MATGEN/CMakeLists.txt @@ -47,12 +47,14 @@ if(BUILD_COMPLEX16) endif() list(REMOVE_DUPLICATES SOURCES) -add_library(${TMGLIB}_obj OBJECT ${SOURCES}) -set_target_properties(${TMGLIB}_obj PROPERTIES Fortran_PREPROCESS ON) +if(BUILD_DEFAULT_API) + add_library(${TMGLIB}_obj OBJECT ${SOURCES}) + set_target_properties(${TMGLIB}_obj PROPERTIES Fortran_PREPROCESS ON) +endif() if(BUILD_INDEX64_EXT_API) include(ExtendedAPIHelpers) - generate_64bit_suffixed_sources( ${TMGLIB} SOURCES SOURCES_64) + generate_64bit_suffixed_sources(${TMGLIB} SOURCES SOURCES_64) add_library(${TMGLIB}_64_obj OBJECT ${SOURCES_64}) target_compile_options(${TMGLIB}_64_obj PRIVATE "${FOPT_ILP64}") @@ -60,7 +62,7 @@ if(BUILD_INDEX64_EXT_API) endif() add_library(${TMGLIB} - $ + $<$: $> $<$: $>) set_target_properties(