[flang-rt][openmp] Add file-level dependencies for builtin mod files (#204260)
CMake currently intentionally ignores intrinsic dependencies. flang-rt already had a workaround using target-level dependencies, but it does not know about dependencies between .mod files created within the same add_library that CMake ignores. As a result, as reported in #203549, updating a .mod did not trigger rebuilding the .mod files that depend on it. Specifically, .mod files store the checksum of used .mod files which need to be updated and therefore require transitive rebuidling. As mentioned, CMake already adds this file-level dependency itself for non-intrinsic modules dependencies. In this PR we are injecting the additional dependencies that CMake does not add via OBJECT_DEPENDS. Three caveats: 1. Using OBJECT_DEPENDS for dependencies between modules of the same OBJECT library makes Ninja complain about circular dependencies. To avoid, split __fortran_builtins.f90 and __cuda_builtins.f90 into their own OBJECT libraries each. 2. The dependency cannot be on the .mod files. Because of how CMake's dependency mechanism works, the dependency scanning runs only after ensuring that the OBJECT_DEPENDS files exist. So if they don't exist yet, we get a missing dependency error. To avoid, we depend on the .o file instead. 3. Generator expressions do not work in OBJECT_DEPENDS. That is, we cannot use `$<TARGET_FILES:flang_rt.mod.fortran.builtins>`, but fortunately we can use OBJECT_OUTPUTS to make the location predictable. At some point in the future, https://gitlab.kitware.com/cmake/cmake/-/issues/26803 should be resolved and become the minimum required version to build LLVM, in which case these workarounds can be removed.
This commit is contained in:
parent
63862a2d80
commit
a92039c3e4
2 changed files with 38 additions and 7 deletions
|
|
@ -266,7 +266,7 @@ endif ()
|
|||
|
||||
# When a target depends on an object library, CMake seems to try to only build
|
||||
# the object files that the target actual needs. If we are only interested
|
||||
# in the module files, nothing get is built at all. To ensure that the module
|
||||
# in the module files, nothing gets built at all. To ensure that the module
|
||||
# files are built, insert a custom target that is opaque to CMake so it cannot
|
||||
# apply this optimization. Dependees on module files must depend on this
|
||||
# barrier instead. An actual COMMAND (that does nothing) seems to be necessary
|
||||
|
|
@ -291,18 +291,43 @@ if (FLANG_RT_FORTRAN_MODULES)
|
|||
# to disable this behavior, unfortunately it does not work with Ninja
|
||||
# (https://gitlab.kitware.com/cmake/cmake/-/issues/26803)
|
||||
# As a workaround, we build those intrinsic modules first such that the main
|
||||
# runtime can depend on it.
|
||||
add_flangrt_library(flang_rt.mod.intrinsics OBJECT
|
||||
${intrinsics_sources}
|
||||
# runtime can depend on it. To ensure that modules files are also transitively
|
||||
# updated if a USE'd .mod file changes (a .mod stores the checksums of all
|
||||
# .mod files it depends on and therefore needs to be updated as well), inject
|
||||
# an file-level dependency via OBJECT_DEPENDS.
|
||||
|
||||
add_flangrt_library(flang_rt.mod.fortran.builtins OBJECT
|
||||
__fortran_builtins.f90
|
||||
)
|
||||
flang_module_target(flang_rt.mod.intrinsics PUBLIC)
|
||||
add_module_barrier(flang_rt.mod.intrinsics.barrier flang_rt.mod.intrinsics)
|
||||
set_property(SOURCE __fortran_builtins.f90 PROPERTY OBJECT_OUTPUTS "${CMAKE_BINARY_DIR}/modules/${CMAKE_CFG_INTDIR}/__fortran_builtins${CMAKE_Fortran_OUTPUT_EXTENSION}")
|
||||
flang_module_target(flang_rt.mod.fortran.builtins PUBLIC)
|
||||
add_module_barrier(flang_rt.mod.fortran.builtins.barrier flang_rt.mod.fortran.builtins)
|
||||
|
||||
add_flangrt_library(flang_rt.mod.cuda.builtins OBJECT
|
||||
__cuda_builtins.f90
|
||||
)
|
||||
set_property(SOURCE __cuda_builtins.f90 PROPERTY OBJECT_OUTPUTS "${CMAKE_BINARY_DIR}/modules/${CMAKE_CFG_INTDIR}/__cuda_builtins${CMAKE_Fortran_OUTPUT_EXTENSION}")
|
||||
add_dependencies(flang_rt.mod.cuda.builtins flang_rt.mod.fortran.builtins.barrier)
|
||||
set_property(SOURCE __cuda_builtins.f90
|
||||
APPEND PROPERTY OBJECT_DEPENDS
|
||||
"${CMAKE_BINARY_DIR}/modules/${CMAKE_CFG_INTDIR}/__fortran_builtins${CMAKE_Fortran_OUTPUT_EXTENSION}"
|
||||
)
|
||||
flang_module_target(flang_rt.mod.cuda.builtins PUBLIC)
|
||||
add_module_barrier(flang_rt.mod.cuda.builtins.barrier flang_rt.mod.cuda.builtins)
|
||||
|
||||
# The modules themselves
|
||||
add_flangrt_library(flang_rt.mod OBJECT
|
||||
${module_sources}
|
||||
)
|
||||
add_dependencies(flang_rt.mod flang_rt.mod.intrinsics.barrier)
|
||||
add_dependencies(flang_rt.mod flang_rt.mod.fortran.builtins.barrier flang_rt.mod.cuda.builtins.barrier)
|
||||
foreach(_srcfile IN LISTS module_sources)
|
||||
set_property(SOURCE ${_srcfile}
|
||||
APPEND PROPERTY OBJECT_DEPENDS
|
||||
"${CMAKE_BINARY_DIR}/modules/${CMAKE_CFG_INTDIR}/__fortran_builtins${CMAKE_Fortran_OUTPUT_EXTENSION}"
|
||||
"${CMAKE_BINARY_DIR}/modules/${CMAKE_CFG_INTDIR}/__cuda_builtins${CMAKE_Fortran_OUTPUT_EXTENSION}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
flang_module_target(flang_rt.mod PUBLIC)
|
||||
add_module_barrier(flang-rt-mod flang_rt.mod)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,12 @@ endif ()
|
|||
|
||||
flang_module_target(libomp-mod PUBLIC)
|
||||
add_dependencies(libomp-mod ${RUNTIMES_FORTRAN_BUILD_DEPS})
|
||||
if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
|
||||
set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/omp_lib.F90"
|
||||
APPEND PROPERTY OBJECT_DEPENDS
|
||||
"${CMAKE_BINARY_DIR}/modules/${CMAKE_CFG_INTDIR}/__fortran_builtins${CMAKE_Fortran_OUTPUT_EXTENSION}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
install(FILES
|
||||
"${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}/omp_lib.h"
|
||||
|
|
|
|||
Loading…
Reference in a new issue