CMakeLists.txt 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. cmake_minimum_required(VERSION 3.10...3.25) # Enable CMP0091 and CMP0141.
  2. cmake_policy(SET CMP0184 NEW)
  3. project(FortranOnly Fortran)
  4. message("CTEST_FULL_OUTPUT ")
  5. if("${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" MATCHES "^Intel(LLVM)?;MSVC$")
  6. string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -Z7")
  7. string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO " -Z7")
  8. endif()
  9. if(CMAKE_Fortran_COMPILER_ID STREQUAL "LFortran")
  10. add_compile_options(--implicit-interface --generate-object-code)
  11. endif()
  12. # create a library with hello and world functions
  13. add_library(FortranOnlylib hello.f world.f)
  14. set_property(TARGET FortranOnlylib PROPERTY Fortran_FORMAT FIXED)
  15. set_property(SOURCE world.f PROPERTY Fortran_FORMAT FREE)
  16. # create an executable that calls hello and world
  17. add_executable(FortranOnly1 testf.f)
  18. set_property(TARGET FortranOnly1 PROPERTY OUTPUT_NAME FortranOnly)
  19. target_link_libraries(FortranOnly1 FortranOnlylib)
  20. # Test that Fortran+RC work together.
  21. # FIXME: Add .rc in more cases.
  22. if(CMAKE_GENERATOR MATCHES "Visual Studio")
  23. set(test_rc testRC.rc)
  24. endif()
  25. # create a custom command that runs FortranOnly1 and puts
  26. # the output into the file testfhello.txt
  27. add_custom_command(OUTPUT ${FortranOnly_BINARY_DIR}/testfhello.txt
  28. COMMAND FortranOnly1
  29. > testfhello.txt)
  30. # create a second executable FortranOnly2 that has
  31. # testfhello.txt has an source file so that it will
  32. # run the above custom command.
  33. add_executable(FortranOnly2 testfhello.txt testf.f ${test_rc})
  34. target_link_libraries(FortranOnly2 FortranOnlylib)
  35. # create a custom target to check the content of testfhello.txt
  36. # by running the cmake script checktestf2.cmake
  37. add_custom_target(checktestf2 ALL
  38. COMMAND ${CMAKE_COMMAND}
  39. -P ${FortranOnly_SOURCE_DIR}/checktestf2.cmake)
  40. # create a custom target that runs FortranOnly1 executable and creates
  41. # a file out.txt that should have hello world in it.
  42. add_custom_target(sayhello ALL
  43. COMMAND FortranOnly1 > out.txt
  44. )
  45. # make sure stuff is built in the right order
  46. add_dependencies(checktestf2 FortranOnly2)
  47. add_dependencies(sayhello FortranOnly1)
  48. add_dependencies(FortranOnly2 FortranOnly1)
  49. # add a custom target that checks that out.txt has the correct
  50. # content
  51. add_custom_target(checksayhello ALL
  52. COMMAND ${CMAKE_COMMAND} -P ${FortranOnly_SOURCE_DIR}/checksayhello.cmake
  53. )
  54. add_dependencies(checksayhello sayhello)
  55. include(CheckFortranSourceCompiles)
  56. unset(HAVE_PRINT CACHE)
  57. CHECK_Fortran_SOURCE_COMPILES([[
  58. PROGRAM TEST_HAVE_PRINT
  59. PRINT *, 'Hello'
  60. END
  61. ]] HAVE_PRINT)
  62. if(NOT HAVE_PRINT)
  63. set(configure_log "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeConfigureLog.yaml")
  64. if(EXISTS "${configure_log}")
  65. file(READ "${configure_log}" log_content)
  66. else()
  67. set(log_content "")
  68. endif()
  69. if(log_content MATCHES [[( -
  70. kind: "try_compile-v1"(
  71. + [^
  72. ]+)+
  73. checks:
  74. - "Performing Test HAVE_PRINT"(
  75. + [^
  76. ]+)+)]])
  77. set(err "${CMAKE_MATCH_1}")
  78. else()
  79. set(err "")
  80. endif()
  81. message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
  82. "${err}")
  83. endif()
  84. unset(Fortran_BOGUS_FLAG CACHE)
  85. include(CheckFortranCompilerFlag)
  86. CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
  87. if (Fortran_BOGUS_FLAG)
  88. message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
  89. endif()
  90. unset(Fortran_RUN_FLAG CACHE)
  91. include(CheckFortranSourceRuns)
  92. check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90)
  93. if(NOT Fortran_RUN_FLAG)
  94. message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed")
  95. endif()
  96. # Test generation of preprocessed sources.
  97. if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
  98. if(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
  99. # Skip running this part of the test on certain platforms
  100. # until they are fixed.
  101. set(MAYBE_ALL ALL)
  102. list(LENGTH CMAKE_OSX_ARCHITECTURES ARCH_COUNT)
  103. if(ARCH_COUNT GREATER 1)
  104. # OSX does not support preprocessing more than one architecture.
  105. set(MAYBE_ALL)
  106. endif()
  107. add_executable(preprocess preprocess.F)
  108. # Custom target to try preprocessing invocation.
  109. add_custom_target(test_preprocess ${MAYBE_ALL}
  110. COMMAND ${CMAKE_COMMAND} -E rm -f CMakeFiles/preprocess.dir/preprocess.F.i
  111. COMMAND ${CMAKE_MAKE_PROGRAM} preprocess.i
  112. COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
  113. # Remove bogus file some compilers leave behind.
  114. COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_SOURCE_DIR}/preprocess.s
  115. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  116. )
  117. endif()
  118. endif()
  119. # Test that with Intel Fortran we always compile with preprocessor
  120. # defines even if splitting the preprocessing and compilation steps.
  121. if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
  122. add_executable(IntelIfDef IntelIfDef.f)
  123. set_property(TARGET IntelIfDef PROPERTY Fortran_FORMAT FIXED)
  124. target_compile_definitions(IntelIfDef PRIVATE SOME_DEF)
  125. endif()
  126. # Skip these tests if compiler/version does enable and disable preprocessing
  127. if(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON AND
  128. CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF)
  129. # Test that we can always preprocess a target
  130. add_executable(preprocess_target preprocess2.f)
  131. set_property(TARGET preprocess_target PROPERTY Fortran_PREPROCESS ON)
  132. if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
  133. # gfortran might report spurious warnings if we include the
  134. # preprocessing flags at the compilation stage
  135. target_compile_options(preprocess_target PRIVATE -Wall -Werror)
  136. endif()
  137. # Test that we can preprocess a single source file
  138. add_executable(preprocess_source preprocess3.f)
  139. set_property(SOURCE preprocess3.f PROPERTY Fortran_PREPROCESS ON)
  140. endif()
  141. # LCC < 1.24 has no way to disable Fortran preprocessor
  142. if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "LCC" OR CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL "1.24.00")
  143. # Test that neither the compiler nor CMake performs unnecessary preprocessing.
  144. add_library(no_preprocess_target_lower STATIC no_preprocess_target_lower.f)
  145. target_compile_options(no_preprocess_target_lower PRIVATE -DINTEGER=nonsense)
  146. set_property(TARGET no_preprocess_target_lower PROPERTY Fortran_PREPROCESS OFF)
  147. add_library(no_preprocess_source_lower STATIC no_preprocess_source_lower.f)
  148. target_compile_options(no_preprocess_source_lower PRIVATE -DINTEGER=nonsense)
  149. set_property(SOURCE no_preprocess_source_lower.f PROPERTY Fortran_PREPROCESS OFF)
  150. endif()
  151. # Test that we can explicitly not preprocess a target or source.
  152. # This will not work on certain compilers due to either missing a
  153. # "don't preprocess" flag, or due to the flags being ignored for
  154. # extensions like '.F' and '.fpp'.
  155. if(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF AND
  156. NOT CMAKE_Fortran_COMPILER_ID MATCHES "(Flang|NAG|PGI|NVHPC|SunPro|XL)")
  157. set(CMAKE_Fortran_PREPROCESS OFF)
  158. add_library(no_preprocess_target STATIC no_preprocess_target_upper.F)
  159. target_compile_options(no_preprocess_target PRIVATE -DINTEGER=nonsense)
  160. unset(CMAKE_Fortran_PREPROCESS)
  161. add_library(no_preprocess_source STATIC no_preprocess_source_upper.F)
  162. target_compile_options(no_preprocess_source PRIVATE -DINTEGER=nonsense)
  163. if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "Cray"
  164. AND NOT "${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" MATCHES "Intel(LLVM)?;MSVC")
  165. target_sources(no_preprocess_target PRIVATE no_preprocess_target_fpp.fpp)
  166. target_sources(no_preprocess_source PRIVATE no_preprocess_source_fpp.fpp)
  167. endif()
  168. set_property(SOURCE no_preprocess_source_upper.F no_preprocess_source_fpp.fpp PROPERTY Fortran_PREPROCESS OFF)
  169. endif()