Ninja: Fix Fortran module deps in files INCLUDEd by preprocessed sources
If a preprocessed source also uses the Fortran `INCLUDE` directive, search the original source file's directory. Fixes: #25792
This commit is contained in:
parent
8ebdee9314
commit
36dc8d6d50
@ -2327,7 +2327,8 @@ struct cmSourceInfo
|
||||
};
|
||||
|
||||
cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
|
||||
std::string const& arg_tdi, std::string const& arg_src);
|
||||
std::string const& arg_tdi, std::string const& arg_src,
|
||||
std::string const& arg_src_orig);
|
||||
}
|
||||
|
||||
int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
|
||||
@ -2335,6 +2336,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
|
||||
{
|
||||
std::string arg_tdi;
|
||||
std::string arg_src;
|
||||
std::string arg_src_orig;
|
||||
std::string arg_out;
|
||||
std::string arg_dep;
|
||||
std::string arg_obj;
|
||||
@ -2345,6 +2347,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
|
||||
arg_tdi = arg.substr(6);
|
||||
} else if (cmHasLiteralPrefix(arg, "--src=")) {
|
||||
arg_src = arg.substr(6);
|
||||
} else if (cmHasLiteralPrefix(arg, "--src-orig=")) {
|
||||
arg_src_orig = arg.substr(11);
|
||||
} else if (cmHasLiteralPrefix(arg, "--out=")) {
|
||||
arg_out = arg.substr(6);
|
||||
} else if (cmHasLiteralPrefix(arg, "--dep=")) {
|
||||
@ -2396,7 +2400,7 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
|
||||
|
||||
cm::optional<cmSourceInfo> info;
|
||||
if (arg_lang == "Fortran") {
|
||||
info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_src);
|
||||
info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_src, arg_src_orig);
|
||||
} else {
|
||||
cmSystemTools::Error(
|
||||
cmStrCat("-E cmake_ninja_depends does not understand the ", arg_lang,
|
||||
@ -2431,13 +2435,24 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
|
||||
namespace {
|
||||
|
||||
cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
|
||||
std::string const& arg_tdi, std::string const& arg_src)
|
||||
std::string const& arg_tdi, std::string const& arg_src,
|
||||
std::string const& arg_src_orig)
|
||||
{
|
||||
cm::optional<cmSourceInfo> info;
|
||||
cmFortranCompiler fc;
|
||||
std::vector<std::string> includes;
|
||||
std::string dir_top_bld;
|
||||
std::string module_dir;
|
||||
|
||||
if (!arg_src_orig.empty()) {
|
||||
// Prepend the original source file's directory as an include directory
|
||||
// so Fortran INCLUDE statements can look for files in it.
|
||||
std::string src_orig_dir = cmSystemTools::GetParentDirectory(arg_src_orig);
|
||||
if (!src_orig_dir.empty()) {
|
||||
includes.push_back(src_orig_dir);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Json::Value tdio;
|
||||
Json::Value const& tdi = tdio;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include <cm/memory>
|
||||
#include <cm/optional>
|
||||
#include <cm/string_view>
|
||||
#include <cmext/algorithm>
|
||||
#include <cmext/string_view>
|
||||
@ -589,13 +590,15 @@ void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language,
|
||||
|
||||
namespace {
|
||||
// Create the command to run the dependency scanner
|
||||
std::string GetScanCommand(cm::string_view cmakeCmd, cm::string_view tdi,
|
||||
cm::string_view lang, cm::string_view srcFile,
|
||||
cm::string_view ddiFile)
|
||||
std::string GetScanCommand(
|
||||
cm::string_view cmakeCmd, cm::string_view tdi, cm::string_view lang,
|
||||
cm::string_view srcFile, cm::string_view ddiFile,
|
||||
cm::optional<cm::string_view> srcOrigFile = cm::nullopt)
|
||||
{
|
||||
return cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi,
|
||||
" --lang=", lang, " --src=", srcFile, " --out=$out",
|
||||
" --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile);
|
||||
" --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile,
|
||||
srcOrigFile ? cmStrCat(" --src-orig=", *srcOrigFile) : "");
|
||||
}
|
||||
|
||||
// Helper function to create dependency scanning rule that may or may
|
||||
@ -759,8 +762,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
|
||||
for (auto& i : scanCommands) {
|
||||
i = cmStrCat(launcher, i);
|
||||
}
|
||||
scanCommands.emplace_back(GetScanCommand(cmakeCmd, tdi, lang, "$out",
|
||||
"$DYNDEP_INTERMEDIATE_FILE"));
|
||||
scanCommands.emplace_back(GetScanCommand(
|
||||
cmakeCmd, tdi, lang, "$out", "$DYNDEP_INTERMEDIATE_FILE", "$in"));
|
||||
}
|
||||
|
||||
auto scanRule = GetScanRule(
|
||||
|
@ -67,7 +67,7 @@ add_definitions(-DFOO -DBAR=1)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
add_executable(test_preprocess test_preprocess.F90 test_preprocess_module.F90)
|
||||
|
||||
add_executable(test_non_pp_include test_non_pp_include_main.f90)
|
||||
add_executable(test_non_pp_include test_non_pp_include_main.f90 test_non_pp_include_module.f90)
|
||||
|
||||
# Build the external project separately using a custom target.
|
||||
# Make sure it uses the same build configuration as this test.
|
||||
|
@ -1,3 +1,4 @@
|
||||
SUBROUTINE NON_PP_INCLUDE_SUBROUTINE
|
||||
PRINT *, "Hello World!"
|
||||
END SUBROUTINE NON_PP_INCLUDE_SUBROUTINE
|
||||
subroutine non_pp_include_subroutine
|
||||
use non_pp_include_module
|
||||
call non_pp_include_module_subroutine
|
||||
end subroutine
|
||||
|
@ -1,5 +1,5 @@
|
||||
INCLUDE "non_pp_include.f90"
|
||||
include "non_pp_include.f90"
|
||||
|
||||
PROGRAM MAINF90
|
||||
CALL NON_PP_INCLUDE_SUBROUTINE
|
||||
END PROGRAM MAINF90
|
||||
program test_non_pp_include_main
|
||||
call non_pp_include_subroutine
|
||||
end program
|
||||
|
6
Tests/FortranModules/test_non_pp_include_module.f90
Normal file
6
Tests/FortranModules/test_non_pp_include_module.f90
Normal file
@ -0,0 +1,6 @@
|
||||
module non_pp_include_module
|
||||
contains
|
||||
subroutine non_pp_include_module_subroutine
|
||||
print *, "Hello World!"
|
||||
end subroutine
|
||||
end module
|
Loading…
Reference in New Issue
Block a user