cmake 3.16.2 is required

This commit is contained in:
kleuter
2023-10-31 23:20:22 +01:00
parent bc5ac068d8
commit 595eafc085
2806 changed files with 20730 additions and 9028 deletions

View File

@ -0,0 +1,103 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(FortranCInterface C Fortran)
include(${FortranCInterface_BINARY_DIR}/Input.cmake OPTIONAL)
# Check if the C compiler supports '$' in identifiers.
include(CheckCSourceCompiles)
check_c_source_compiles("
extern int dollar$(void);
int main() { return 0; }
" C_SUPPORTS_DOLLAR)
# List manglings of global symbol names to try.
set(global_symbols
my_sub # VisualAge
my_sub_ # GNU, Intel, HP, SunPro, PGI
my_sub__ # GNU g77
MY_SUB # Intel on Windows
mysub # VisualAge
mysub_ # GNU, Intel, HP, SunPro, PGI
MYSUB # Intel on Windows
${FortranCInterface_GLOBAL_SYMBOLS}
)
list(REMOVE_DUPLICATES global_symbols)
# List manglings of module symbol names to try.
set(module_symbols
__my_module_MOD_my_sub # GNU 4.3
__my_module_NMOD_my_sub # VisualAge
__my_module__my_sub # GNU 4.2
__mymodule_MOD_mysub # GNU 4.3
__mymodule_NMOD_mysub # VisualAge
__mymodule__mysub # GNU 4.2
my_module$my_sub # HP
my_module_mp_my_sub_ # Intel
MY_MODULE_mp_MY_SUB # Intel on Windows
my_module_my_sub_ # PGI
my_module_MP_my_sub # NAG
mymodule$mysub # HP
mymodule_mp_mysub_ # Intel
MYMODULE_mp_MYSUB # Intel on Windows
mymodule_mysub_ # PGI
mymodule_MP_mysub # NAG
${FortranCInterface_MODULE_SYMBOLS}
)
list(REMOVE_DUPLICATES module_symbols)
# Note that some compiler manglings cannot be invoked from C:
# SunPro uses "my_module.my_sub_"
# PathScale uses "MY_SUB.in.MY_MODULE"
# Add module symbols only with Fortran90.
if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
set(myfort_modules mymodule.f90 my_module.f90)
set(call_mod call_mod.f90)
set_property(SOURCE main.F PROPERTY COMPILE_DEFINITIONS CALL_MOD)
else()
set(module_symbols)
endif()
# Generate C symbol sources.
set(symbol_sources)
if(NOT CMAKE_Fortran_COMPILER_ID MATCHES "^(PathScale|Cray)$")
# Provide mymodule_ and my_module_ init symbols because:
# - PGI Fortran uses module init symbols
# but not for:
# - PathScale Fortran uses module init symbols but module symbols
# use '.in.' so we cannot provide them anyway.
# - Cray Fortran >= 7.3.2 uses module init symbols but module symbols
# use 'mysub$mymodule_' so we cannot provide them anyway.
list(APPEND symbol_sources mymodule_.c my_module_.c MY_MODULE.c MYMODULE.c)
endif()
foreach(symbol IN LISTS global_symbols module_symbols)
# Skip symbols with '$' if C cannot handle them.
if(C_SUPPORTS_DOLLAR OR NOT "${symbol}" MATCHES "\\$")
if("${symbol}" MATCHES "SUB")
set(upper "-UPPER")
else()
set(upper)
endif()
string(REPLACE "$" "S" name "${symbol}")
set(source ${CMAKE_CURRENT_BINARY_DIR}/symbols/${name}${upper}.c)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/symbol.c.in ${source} @ONLY)
list(APPEND symbol_sources ${source})
endif()
endforeach()
# Provide symbols through Fortran.
add_library(myfort STATIC mysub.f my_sub.f ${myfort_modules})
# Provide symbols through C but fall back to Fortran.
add_library(symbols STATIC ${symbol_sources})
target_link_libraries(symbols PUBLIC myfort)
# In case the Fortran compiler produces PIC by default make sure
# the C compiler produces PIC even if it is not its default.
set_property(TARGET symbols PROPERTY POSITION_INDEPENDENT_CODE 1)
# Require symbols through Fortran.
add_executable(FortranCInterface main.F call_sub.f ${call_mod})
target_link_libraries(FortranCInterface PUBLIC symbols)

View File

@ -0,0 +1,178 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
configure_file(${FortranCInterface_SOURCE_DIR}/Input.cmake.in
${FortranCInterface_BINARY_DIR}/Input.cmake @ONLY)
# Detect the Fortran/C interface on the first run or when the
# configuration changes.
if(${FortranCInterface_BINARY_DIR}/Input.cmake
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
OR ${FortranCInterface_SOURCE_DIR}/Output.cmake.in
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
OR ${FortranCInterface_SOURCE_DIR}/CMakeLists.txt
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
OR ${CMAKE_CURRENT_LIST_FILE}
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
)
message(STATUS "Detecting Fortran/C Interface")
else()
return()
endif()
# Invalidate verification results.
unset(FortranCInterface_VERIFIED_C CACHE)
unset(FortranCInterface_VERIFIED_CXX CACHE)
set(_result)
# Build a sample project which reports symbols.
set(CMAKE_TRY_COMPILE_CONFIGURATION Release)
try_compile(FortranCInterface_COMPILED
${FortranCInterface_BINARY_DIR}
${FortranCInterface_SOURCE_DIR}
FortranCInterface # project name
FortranCInterface # target name
CMAKE_FLAGS
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}"
"-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
"-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}"
"-DCMAKE_Fortran_FLAGS_RELEASE:STRING=${CMAKE_Fortran_FLAGS_RELEASE}"
OUTPUT_VARIABLE FortranCInterface_OUTPUT)
set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED})
unset(FortranCInterface_COMPILED CACHE)
# Locate the sample project executable.
if(FortranCInterface_COMPILED)
find_program(FortranCInterface_EXE
NAMES FortranCInterface${CMAKE_EXECUTABLE_SUFFIX}
PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Release
NO_DEFAULT_PATH
)
set(FortranCInterface_EXE ${FortranCInterface_EXE})
unset(FortranCInterface_EXE CACHE)
else()
set(_result "Failed to compile")
set(FortranCInterface_EXE)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Fortran/C interface test project failed with the following output:\n"
"${FortranCInterface_OUTPUT}\n")
endif()
# Load symbols from INFO:symbol[] strings in the executable.
set(FortranCInterface_SYMBOLS)
if(FortranCInterface_EXE)
file(STRINGS "${FortranCInterface_EXE}" _info_strings
LIMIT_COUNT 8 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
foreach(info ${_info_strings})
if("${info}" MATCHES "INFO:symbol\\[([^]]*)\\]")
list(APPEND FortranCInterface_SYMBOLS ${CMAKE_MATCH_1})
endif()
endforeach()
elseif(NOT _result)
set(_result "Failed to load sample executable")
endif()
set(_case_mysub "LOWER")
set(_case_my_sub "LOWER")
set(_case_MYSUB "UPPER")
set(_case_MY_SUB "UPPER")
set(_global_regex "^(_*)(mysub|MYSUB)([_$]*)$")
set(_global__regex "^(_*)(my_sub|MY_SUB)([_$]*)$")
set(_module_regex "^(_*)(mymodule|MYMODULE)([A-Za-z_$]*)(mysub|MYSUB)([_$]*)$")
set(_module__regex "^(_*)(my_module|MY_MODULE)([A-Za-z_$]*)(my_sub|MY_SUB)([_$]*)$")
# Parse the symbol names.
foreach(symbol ${FortranCInterface_SYMBOLS})
foreach(form "" "_")
# Look for global symbols.
string(REGEX REPLACE "${_global_${form}regex}"
"\\1;\\2;\\3" pieces "${symbol}")
list(LENGTH pieces len)
if(len EQUAL 3)
set(FortranCInterface_GLOBAL_${form}SYMBOL "${symbol}")
list(GET pieces 0 FortranCInterface_GLOBAL_${form}PREFIX)
list(GET pieces 1 name)
list(GET pieces 2 FortranCInterface_GLOBAL_${form}SUFFIX)
set(FortranCInterface_GLOBAL_${form}CASE "${_case_${name}}")
endif()
# Look for module symbols.
string(REGEX REPLACE "${_module_${form}regex}"
"\\1;\\2;\\3;\\4;\\5" pieces "${symbol}")
list(LENGTH pieces len)
if(len EQUAL 5)
set(FortranCInterface_MODULE_${form}SYMBOL "${symbol}")
list(GET pieces 0 FortranCInterface_MODULE_${form}PREFIX)
list(GET pieces 1 module)
list(GET pieces 2 FortranCInterface_MODULE_${form}MIDDLE)
list(GET pieces 3 name)
list(GET pieces 4 FortranCInterface_MODULE_${form}SUFFIX)
set(FortranCInterface_MODULE_${form}CASE "${_case_${name}}")
endif()
endforeach()
endforeach()
# Construct mangling macro definitions.
set(_name_LOWER "name")
set(_name_UPPER "NAME")
foreach(form "" "_")
if(FortranCInterface_GLOBAL_${form}SYMBOL)
if(FortranCInterface_GLOBAL_${form}PREFIX)
set(_prefix "${FortranCInterface_GLOBAL_${form}PREFIX}##")
else()
set(_prefix "")
endif()
if(FortranCInterface_GLOBAL_${form}SUFFIX)
set(_suffix "##${FortranCInterface_GLOBAL_${form}SUFFIX}")
else()
set(_suffix "")
endif()
set(_name "${_name_${FortranCInterface_GLOBAL_${form}CASE}}")
set(FortranCInterface_GLOBAL${form}_MACRO
"(name,NAME) ${_prefix}${_name}${_suffix}")
endif()
if(FortranCInterface_MODULE_${form}SYMBOL)
if(FortranCInterface_MODULE_${form}PREFIX)
set(_prefix "${FortranCInterface_MODULE_${form}PREFIX}##")
else()
set(_prefix "")
endif()
if(FortranCInterface_MODULE_${form}SUFFIX)
set(_suffix "##${FortranCInterface_MODULE_${form}SUFFIX}")
else()
set(_suffix "")
endif()
set(_name "${_name_${FortranCInterface_MODULE_${form}CASE}}")
set(_middle "##${FortranCInterface_MODULE_${form}MIDDLE}##")
set(FortranCInterface_MODULE${form}_MACRO
"(mod_name,name, mod_NAME,NAME) ${_prefix}mod_${_name}${_middle}${_name}${_suffix}")
endif()
endforeach()
# Summarize what is available.
foreach(scope GLOBAL MODULE)
if(FortranCInterface_${scope}_SYMBOL AND
FortranCInterface_${scope}__SYMBOL)
set(FortranCInterface_${scope}_FOUND 1)
else()
set(FortranCInterface_${scope}_FOUND 0)
endif()
endforeach()
# Record the detection results.
configure_file(${FortranCInterface_SOURCE_DIR}/Output.cmake.in
${FortranCInterface_BINARY_DIR}/Output.cmake @ONLY)
file(APPEND ${FortranCInterface_BINARY_DIR}/Output.cmake "\n")
# Report the results.
if(FortranCInterface_GLOBAL_FOUND)
if(FortranCInterface_MODULE_FOUND)
set(_result "Found GLOBAL and MODULE mangling")
else()
set(_result "Found GLOBAL but not MODULE mangling")
endif()
elseif(NOT _result)
set(_result "Failed to recognize symbols")
endif()
message(STATUS "Detecting Fortran/C Interface - ${_result}")

View File

@ -0,0 +1,3 @@
set(CMAKE_Fortran_COMPILER_ID "@CMAKE_Fortran_COMPILER_ID@")
set(FortranCInterface_GLOBAL_SYMBOLS "@FortranCInterface_GLOBAL_SYMBOLS@")
set(FortranCInterface_MODULE_SYMBOLS "@FortranCInterface_MODULE_SYMBOLS@")

View File

@ -0,0 +1,3 @@
void MYMODULE(void)
{
}

View File

@ -0,0 +1,3 @@
void MY_MODULE(void)
{
}

View File

@ -0,0 +1,4 @@
#ifndef @MACRO_NAMESPACE@HEADER_INCLUDED
#define @MACRO_NAMESPACE@HEADER_INCLUDED
@HEADER_CONTENT@
#endif

View File

@ -0,0 +1,33 @@
# Global symbol without underscore.
set(FortranCInterface_GLOBAL_SYMBOL "@FortranCInterface_GLOBAL_SYMBOL@")
set(FortranCInterface_GLOBAL_PREFIX "@FortranCInterface_GLOBAL_PREFIX@")
set(FortranCInterface_GLOBAL_SUFFIX "@FortranCInterface_GLOBAL_SUFFIX@")
set(FortranCInterface_GLOBAL_CASE "@FortranCInterface_GLOBAL_CASE@")
set(FortranCInterface_GLOBAL_MACRO "@FortranCInterface_GLOBAL_MACRO@")
# Global symbol with underscore.
set(FortranCInterface_GLOBAL__SYMBOL "@FortranCInterface_GLOBAL__SYMBOL@")
set(FortranCInterface_GLOBAL__PREFIX "@FortranCInterface_GLOBAL__PREFIX@")
set(FortranCInterface_GLOBAL__SUFFIX "@FortranCInterface_GLOBAL__SUFFIX@")
set(FortranCInterface_GLOBAL__CASE "@FortranCInterface_GLOBAL__CASE@")
set(FortranCInterface_GLOBAL__MACRO "@FortranCInterface_GLOBAL__MACRO@")
# Module symbol without underscore.
set(FortranCInterface_MODULE_SYMBOL "@FortranCInterface_MODULE_SYMBOL@")
set(FortranCInterface_MODULE_PREFIX "@FortranCInterface_MODULE_PREFIX@")
set(FortranCInterface_MODULE_MIDDLE "@FortranCInterface_MODULE_MIDDLE@")
set(FortranCInterface_MODULE_SUFFIX "@FortranCInterface_MODULE_SUFFIX@")
set(FortranCInterface_MODULE_CASE "@FortranCInterface_MODULE_CASE@")
set(FortranCInterface_MODULE_MACRO "@FortranCInterface_MODULE_MACRO@")
# Module symbol with underscore.
set(FortranCInterface_MODULE__SYMBOL "@FortranCInterface_MODULE__SYMBOL@")
set(FortranCInterface_MODULE__PREFIX "@FortranCInterface_MODULE__PREFIX@")
set(FortranCInterface_MODULE__MIDDLE "@FortranCInterface_MODULE__MIDDLE@")
set(FortranCInterface_MODULE__SUFFIX "@FortranCInterface_MODULE__SUFFIX@")
set(FortranCInterface_MODULE__CASE "@FortranCInterface_MODULE__CASE@")
set(FortranCInterface_MODULE__MACRO "@FortranCInterface_MODULE__MACRO@")
# Summarize what was found.
set(FortranCInterface_GLOBAL_FOUND @FortranCInterface_GLOBAL_FOUND@)
set(FortranCInterface_MODULE_FOUND @FortranCInterface_MODULE_FOUND@)

View File

@ -0,0 +1,26 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(VerifyFortranC C Fortran)
option(VERIFY_CXX "Whether to verify C++ and Fortran" OFF)
if(VERIFY_CXX)
enable_language(CXX)
set(VerifyCXX VerifyCXX.cxx)
add_definitions(-DVERIFY_CXX)
endif()
include(FortranCInterface)
FortranCInterface_HEADER(VerifyFortran.h SYMBOLS VerifyFortran)
include_directories(${VerifyFortranC_BINARY_DIR})
add_library(VerifyFortran STATIC VerifyFortran.f)
add_executable(VerifyFortranC main.c VerifyC.c ${VerifyCXX})
target_link_libraries(VerifyFortranC VerifyFortran)
if(NOT VERIFY_CXX)
# The entry point (main) is defined in C; link with the C compiler.
set_property(TARGET VerifyFortranC PROPERTY LINKER_LANGUAGE C)
endif()

View File

@ -0,0 +1,5 @@
#include <stdio.h>
void VerifyC(void)
{
printf("VerifyC\n");
}

View File

@ -0,0 +1,4 @@
extern "C" void VerifyCXX(void)
{
delete new int;
}

View File

@ -0,0 +1,3 @@
subroutine VerifyFortran
print *, 'VerifyFortran'
end

View File

@ -0,0 +1,16 @@
extern void VerifyC(void);
#ifdef VERIFY_CXX
extern void VerifyCXX(void);
#endif
#include "VerifyFortran.h"
extern void VerifyFortran(void);
int main(void)
{
VerifyC();
#ifdef VERIFY_CXX
VerifyCXX();
#endif
VerifyFortran();
return 0;
}

View File

@ -0,0 +1,6 @@
subroutine call_mod
use mymodule
use my_module
call mysub()
call my_sub()
end subroutine call_mod

View File

@ -0,0 +1,4 @@
subroutine call_sub
call mysub()
call my_sub()
end

View File

@ -0,0 +1,6 @@
program main
call call_sub()
#ifdef CALL_MOD
call call_mod()
#endif
end

View File

@ -0,0 +1,8 @@
module my_module
interface my_interface
module procedure my_sub
end interface
contains
subroutine my_sub
end subroutine my_sub
end module my_module

View File

@ -0,0 +1,3 @@
void my_module_(void)
{
}

View File

@ -0,0 +1,2 @@
subroutine my_sub
end

View File

@ -0,0 +1,8 @@
module mymodule
interface myinterface
module procedure mysub
end interface
contains
subroutine mysub
end subroutine mysub
end module mymodule

View File

@ -0,0 +1,3 @@
void mymodule_(void)
{
}

View File

@ -0,0 +1,2 @@
subroutine mysub
end

View File

@ -0,0 +1,4 @@
const char* @symbol@(void)
{
return "INFO:symbol[@symbol@]";
}