From c78be340ba110366f59ccfd4dc140e5ac31191d9 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 9 May 2023 09:04:56 -0400 Subject: Tests: Teach RunCMake to ignore Intel Fortran remark 10440 The Intel Fortran compiler may remark: ifx: remark #10440: Note that use of a debug option without any optimization-level option will turnoff most compiler optimizations similar to use of '-O0' Teach RunCMake to drop such incidental lines before matching against expected output. This extends commit b2d030e8fe (Tests: Teach RunCMake to ignore Intel -Rdebug-disables-optimization remarks, 2022-06-14, v3.26.0-rc1~395^2) to cover the `ifx` Fortran compiler too. --- Tests/RunCMake/RunCMake.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 18dde94..9e5f531 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -168,6 +168,7 @@ function(run_cmake test) "|[a-z]+\\([0-9]+\\) malloc:" "|clang[^:]*: warning: the object size sanitizer has no effect at -O0, but is explicitly enabled:" "|icp?x: remark: Note that use of .-g. without any optimization-level option will turn off most compiler optimizations" + "|ifx: remark #10440: Note that use of a debug option without any optimization-level option will turnoff most compiler optimizations" "|lld-link: warning: procedure symbol record for .* refers to PDB item index [0-9A-Fa-fx]+ which is not a valid function ID record" "|Error kstat returned" "|Hit xcodebuild bug" -- cgit v0.12 From efadf839be97687f8797a95a0c888febf0e3b05f Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 9 May 2023 09:19:54 -0400 Subject: Tests: Teach RunCMake to ignore LLVMFlang -flang-experimental-exec warning This flag is needed for now to tell `flang-new` to support creating executables. In our CI job we always pass this flag, but it is not always used. The compiler may warn: flang-new: warning: argument unused during compilation: '-flang-experimental-exec' Teach RunCMake to drop such incidental lines before matching against expected output. --- Tests/RunCMake/RunCMake.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 9e5f531..bc4a330 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -167,6 +167,7 @@ function(run_cmake test) "|BullseyeCoverage" "|[a-z]+\\([0-9]+\\) malloc:" "|clang[^:]*: warning: the object size sanitizer has no effect at -O0, but is explicitly enabled:" + "|flang-new: warning: argument unused during compilation: .-flang-experimental-exec." "|icp?x: remark: Note that use of .-g. without any optimization-level option will turn off most compiler optimizations" "|ifx: remark #10440: Note that use of a debug option without any optimization-level option will turnoff most compiler optimizations" "|lld-link: warning: procedure symbol record for .* refers to PDB item index [0-9A-Fa-fx]+ which is not a valid function ID record" -- cgit v0.12 From 266634bce5defda08d51682a5d99782b4ebd044e Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 9 May 2023 09:54:01 -0400 Subject: Fortran: Teach lexer to recognize LLVMFlang preprocessor dependencies The line directives have the form `#line `, and do not have the line number before the path as other compilers do. --- Source/LexerParser/cmFortranLexer.cxx | 142 +++++++++++++++++---------------- Source/LexerParser/cmFortranLexer.in.l | 1 + 2 files changed, 74 insertions(+), 69 deletions(-) diff --git a/Source/LexerParser/cmFortranLexer.cxx b/Source/LexerParser/cmFortranLexer.cxx index 5703de1..df65472 100644 --- a/Source/LexerParser/cmFortranLexer.cxx +++ b/Source/LexerParser/cmFortranLexer.cxx @@ -548,8 +548,8 @@ static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 54 -#define YY_END_OF_BUFFER 55 +#define YY_NUM_RULES 55 +#define YY_END_OF_BUFFER 56 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -560,29 +560,29 @@ struct yy_trans_info static const flex_int16_t yy_accept[216] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 49, 51, 50, 53, 1, 49, 33, 2, 47, - 48, 35, 37, 50, 39, 49, 46, 46, 46, 46, - 46, 46, 49, 46, 51, 49, 50, 51, 49, 46, - 9, 8, 9, 9, 4, 3, 49, 0, 10, 0, - 0, 0, 0, 0, 33, 33, 34, 36, 39, 49, - 46, 46, 46, 46, 46, 46, 0, 52, 0, 46, + 56, 50, 52, 51, 54, 1, 50, 34, 2, 48, + 49, 36, 38, 51, 40, 50, 47, 47, 47, 47, + 47, 47, 50, 47, 52, 50, 51, 52, 50, 47, + 9, 8, 9, 9, 4, 3, 50, 0, 10, 0, + 0, 0, 0, 0, 34, 34, 35, 37, 40, 50, + 47, 47, 47, 47, 47, 47, 0, 53, 0, 47, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, - 0, 49, 0, 11, 46, 0, 0, 0, 5, 0, - 0, 0, 0, 0, 29, 0, 33, 33, 33, 33, + 0, 50, 0, 11, 47, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 30, 0, 34, 34, 34, 34, - 0, 0, 40, 46, 46, 46, 46, 45, 12, 12, - 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, + 0, 0, 41, 47, 47, 47, 47, 46, 12, 12, + 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 46, 46, 46, 46, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 30, 31, 0, - 0, 0, 0, 0, 46, 46, 46, 46, 0, 24, - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 32, 27, 0, 0, 0, 46, 46, 43, 46, - 0, 26, 21, 0, 0, 0, 19, 0, 0, 18, - 28, 0, 0, 41, 46, 46, 17, 22, 0, 7, - - 38, 7, 15, 0, 46, 46, 14, 16, 42, 44, - 0, 0, 0, 13, 0 + 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 32, 0, + 0, 0, 0, 0, 47, 47, 47, 47, 0, 25, + 26, 0, 0, 0, 0, 13, 0, 0, 0, 0, + 21, 33, 28, 0, 0, 0, 47, 47, 44, 47, + 0, 27, 22, 0, 0, 13, 20, 0, 0, 19, + 29, 0, 0, 42, 47, 47, 18, 23, 0, 7, + + 39, 7, 16, 0, 47, 47, 15, 17, 43, 45, + 0, 0, 0, 14, 0 } ; static const YY_CHAR yy_ec[256] = @@ -1252,7 +1252,11 @@ YY_RULE_SETUP { return CPP_LINE_DIRECTIVE; } YY_BREAK case 13: -/* rule 13 can match eol */ +YY_RULE_SETUP +{ return CPP_LINE_DIRECTIVE; } + YY_BREAK +case 14: +/* rule 14 can match eol */ YY_RULE_SETUP { yytext[yyleng-1] = 0; @@ -1260,172 +1264,172 @@ YY_RULE_SETUP return CPP_INCLUDE_ANGLE; } YY_BREAK -case 14: +case 15: YY_RULE_SETUP { return CPP_INCLUDE; } YY_BREAK -case 15: +case 16: YY_RULE_SETUP { return F90PPR_INCLUDE; } YY_BREAK -case 16: +case 17: YY_RULE_SETUP { return COCO_INCLUDE; } YY_BREAK -case 17: +case 18: YY_RULE_SETUP { return CPP_DEFINE; } YY_BREAK -case 18: +case 19: YY_RULE_SETUP { return F90PPR_DEFINE; } YY_BREAK -case 19: +case 20: YY_RULE_SETUP { return CPP_UNDEF; } YY_BREAK -case 20: +case 21: YY_RULE_SETUP { return F90PPR_UNDEF; } YY_BREAK -case 21: +case 22: YY_RULE_SETUP { return CPP_IFDEF; } YY_BREAK -case 22: +case 23: YY_RULE_SETUP { return CPP_IFNDEF; } YY_BREAK -case 23: +case 24: YY_RULE_SETUP { return CPP_IF; } YY_BREAK -case 24: +case 25: YY_RULE_SETUP { return CPP_ELIF; } YY_BREAK -case 25: +case 26: YY_RULE_SETUP { return CPP_ELSE; } YY_BREAK -case 26: +case 27: YY_RULE_SETUP { return CPP_ENDIF; } YY_BREAK -case 27: +case 28: YY_RULE_SETUP { return F90PPR_IFDEF; } YY_BREAK -case 28: +case 29: YY_RULE_SETUP { return F90PPR_IFNDEF; } YY_BREAK -case 29: +case 30: YY_RULE_SETUP { return F90PPR_IF; } YY_BREAK -case 30: +case 31: YY_RULE_SETUP { return F90PPR_ELIF; } YY_BREAK -case 31: +case 32: YY_RULE_SETUP { return F90PPR_ELSE; } YY_BREAK -case 32: +case 33: YY_RULE_SETUP { return F90PPR_ENDIF; } YY_BREAK /* Line continuations, possible involving comments. */ -case 33: -/* rule 33 can match eol */ -YY_RULE_SETUP - - YY_BREAK case 34: /* rule 34 can match eol */ YY_RULE_SETUP YY_BREAK case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -{ return COMMA; } + YY_BREAK case 36: YY_RULE_SETUP -{ return DCOLON; } +{ return COMMA; } YY_BREAK case 37: YY_RULE_SETUP -{ return COLON; } +{ return DCOLON; } YY_BREAK case 38: -/* rule 38 can match eol */ YY_RULE_SETUP -{ return GARBAGE; } +{ return COLON; } YY_BREAK case 39: +/* rule 39 can match eol */ YY_RULE_SETUP -{ return ASSIGNMENT_OP; } +{ return GARBAGE; } YY_BREAK case 40: YY_RULE_SETUP -{ return END; } +{ return ASSIGNMENT_OP; } YY_BREAK case 41: YY_RULE_SETUP -{ return INCLUDE; } +{ return END; } YY_BREAK case 42: YY_RULE_SETUP -{ return INTERFACE; } +{ return INCLUDE; } YY_BREAK case 43: YY_RULE_SETUP -{ return MODULE; } +{ return INTERFACE; } YY_BREAK case 44: YY_RULE_SETUP -{ return SUBMODULE; } +{ return MODULE; } YY_BREAK case 45: YY_RULE_SETUP -{ return USE; } +{ return SUBMODULE; } YY_BREAK case 46: YY_RULE_SETUP +{ return USE; } + YY_BREAK +case 47: +YY_RULE_SETUP { yylvalp->string = strdup(yytext); return WORD; } YY_BREAK -case 47: +case 48: YY_RULE_SETUP { return LPAREN; } YY_BREAK -case 48: +case 49: YY_RULE_SETUP { return RPAREN; } YY_BREAK -case 49: +case 50: YY_RULE_SETUP { return GARBAGE; } YY_BREAK -case 50: -/* rule 50 can match eol */ +case 51: +/* rule 51 can match eol */ YY_RULE_SETUP { return EOSTMT; } YY_BREAK -case 51: +case 52: YY_RULE_SETUP /* Ignore */ YY_BREAK -case 52: -/* rule 52 can match eol */ +case 53: +/* rule 53 can match eol */ YY_RULE_SETUP /* Ignore line-endings preceded by \ */ YY_BREAK -case 53: +case 54: YY_RULE_SETUP { return *yytext; } YY_BREAK @@ -1441,7 +1445,7 @@ case YY_STATE_EOF(str_dq): } } YY_BREAK -case 54: +case 55: YY_RULE_SETUP ECHO; YY_BREAK diff --git a/Source/LexerParser/cmFortranLexer.in.l b/Source/LexerParser/cmFortranLexer.in.l index fac3181..7d97699 100644 --- a/Source/LexerParser/cmFortranLexer.in.l +++ b/Source/LexerParser/cmFortranLexer.in.l @@ -102,6 +102,7 @@ Modify cmFortranLexer.cxx: ^[cC*dD].*\n { return EOSTMT; } /* empty lines */ ^[ \t]*#([ \t]*line)?[ \t]*[0-9]+[ \t]* { return CPP_LINE_DIRECTIVE; } +^[ \t]*#[ \t]*line[ \t]* { return CPP_LINE_DIRECTIVE; } ^[ \t]*#[ \t]*include[ \t]*<[^>]+> { yytext[yyleng-1] = 0; yylvalp->string = strdup(strchr(yytext, '<')+1); -- cgit v0.12 From 9075ebda60922d8d11dd15d15c714c36ec3874cd Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 8 May 2023 16:56:25 -0400 Subject: Ninja: Rename internal Fortran scanner flag from --pp= to --src= The value represents the source file to be scanned. It is not always preprocessor output. --- Source/cmGlobalNinjaGenerator.cxx | 31 +++++++++++++++++-------------- Source/cmNinjaTargetGenerator.cxx | 8 ++++---- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 84c85e0..f3927b4 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2226,9 +2226,9 @@ Compilation of source files within a target is split into the following steps: depfile = $DEP_FILE command = gfortran -cpp $DEFINES $INCLUDES $FLAGS -E $in -o $out && cmake -E cmake_ninja_depends \ - --tdi=FortranDependInfo.json --pp=$out --dep=$DEP_FILE \ - --obj=$OBJ_FILE --ddi=$DYNDEP_INTERMEDIATE_FILE \ - --lang=Fortran + --tdi=FortranDependInfo.json --lang=Fortran \ + --src=$out --dep=$DEP_FILE --obj=$OBJ_FILE \ + --ddi=$DYNDEP_INTERMEDIATE_FILE build src.f90-pp.f90 | src.f90.o.ddi: Fortran_PREPROCESS src.f90 OBJ_FILE = src.f90.o @@ -2296,14 +2296,14 @@ struct cmSourceInfo }; cm::optional cmcmd_cmake_ninja_depends_fortran( - std::string const& arg_tdi, std::string const& arg_pp); + std::string const& arg_tdi, std::string const& arg_src); } int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, std::vector::const_iterator argEnd) { std::string arg_tdi; - std::string arg_pp; + std::string arg_src; std::string arg_dep; std::string arg_obj; std::string arg_ddi; @@ -2311,8 +2311,8 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, for (std::string const& arg : cmMakeRange(argBeg, argEnd)) { if (cmHasLiteralPrefix(arg, "--tdi=")) { arg_tdi = arg.substr(6); - } else if (cmHasLiteralPrefix(arg, "--pp=")) { - arg_pp = arg.substr(5); + } else if (cmHasLiteralPrefix(arg, "--src=")) { + arg_src = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--dep=")) { arg_dep = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--obj=")) { @@ -2321,6 +2321,9 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, arg_ddi = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--lang=")) { arg_lang = arg.substr(7); + } else if (cmHasLiteralPrefix(arg, "--pp=")) { + // CMake 3.26 and below used '--pp=' instead of '--src='. + arg_src = arg.substr(5); } else { cmSystemTools::Error( cmStrCat("-E cmake_ninja_depends unknown argument: ", arg)); @@ -2331,8 +2334,8 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, cmSystemTools::Error("-E cmake_ninja_depends requires value for --tdi="); return 1; } - if (arg_pp.empty()) { - cmSystemTools::Error("-E cmake_ninja_depends requires value for --pp="); + if (arg_src.empty()) { + cmSystemTools::Error("-E cmake_ninja_depends requires value for --src="); return 1; } if (arg_dep.empty()) { @@ -2354,7 +2357,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, cm::optional info; if (arg_lang == "Fortran") { - info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_pp); + info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_src); } else { cmSystemTools::Error( cmStrCat("-E cmake_ninja_depends does not understand the ", arg_lang, @@ -2371,7 +2374,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, { cmGeneratedFileStream depfile(arg_dep); - depfile << cmSystemTools::ConvertToUnixOutputPath(arg_pp) << ":"; + depfile << cmSystemTools::ConvertToUnixOutputPath(arg_src) << ":"; for (std::string const& include : info->Includes) { depfile << " \\\n " << cmSystemTools::ConvertToUnixOutputPath(include); } @@ -2389,7 +2392,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, namespace { cm::optional cmcmd_cmake_ninja_depends_fortran( - std::string const& arg_tdi, std::string const& arg_pp) + std::string const& arg_tdi, std::string const& arg_src) { cm::optional info; cmFortranCompiler fc; @@ -2441,9 +2444,9 @@ cm::optional cmcmd_cmake_ninja_depends_fortran( cmFortranSourceInfo finfo; std::set defines; cmFortranParser parser(fc, includes, defines, finfo); - if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) { + if (!cmFortranParser_FilePush(&parser, arg_src.c_str())) { cmSystemTools::Error( - cmStrCat("-E cmake_ninja_depends failed to open ", arg_pp)); + cmStrCat("-E cmake_ninja_depends failed to open ", arg_src)); return info; } if (cmFortran_yyparse(parser.Scanner) != 0) { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 4ed491d..f035c1e 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -540,12 +540,12 @@ void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language, namespace { // Create the command to run the dependency scanner -std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi, - const std::string& lang, const std::string& ppFile, - const std::string& ddiFile) +std::string GetScanCommand(cm::string_view cmakeCmd, cm::string_view tdi, + cm::string_view lang, cm::string_view srcFile, + cm::string_view ddiFile) { return cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, - " --lang=", lang, " --pp=", ppFile, + " --lang=", lang, " --src=", srcFile, " --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile); } -- cgit v0.12 From 1f1894af1fb263762c062c55fce28b5f9678dc5e Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 8 May 2023 17:04:46 -0400 Subject: Ninja: Fix Fortran INCLUDE directive dependencies when not preprocessing Since commit b0a6161190 (Fortran: Add Fortran_PREPROCESS property, 2020-04-24, v3.18.0-rc1~116^2~3), if `Fortran_PREPROCESS` is `OFF`, the Ninja generator does not properly detect dependencies on sources loaded via the Fortran INCLUDE directive. Fix this and add a test. --- Source/cmGlobalNinjaGenerator.cxx | 14 +++++++++++--- Source/cmNinjaTargetGenerator.cxx | 15 ++++++++++++--- .../BuildDepends/FortranInclude-build1-stderr.txt | 1 + .../BuildDepends/FortranInclude-build2-stderr.txt | 1 + Tests/RunCMake/BuildDepends/FortranInclude.cmake | 20 ++++++++++++++++++++ .../RunCMake/BuildDepends/FortranInclude.step1.cmake | 2 ++ .../RunCMake/BuildDepends/FortranInclude.step2.cmake | 2 ++ .../BuildDepends/FortranIncludeNoPreprocess.f | 3 +++ .../RunCMake/BuildDepends/FortranIncludePreprocess.F | 3 +++ Tests/RunCMake/BuildDepends/RunCMakeTest.cmake | 4 ++++ Tests/RunCMake/CMakeLists.txt | 4 ++++ 11 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 Tests/RunCMake/BuildDepends/FortranInclude-build1-stderr.txt create mode 100644 Tests/RunCMake/BuildDepends/FortranInclude-build2-stderr.txt create mode 100644 Tests/RunCMake/BuildDepends/FortranInclude.cmake create mode 100644 Tests/RunCMake/BuildDepends/FortranInclude.step1.cmake create mode 100644 Tests/RunCMake/BuildDepends/FortranInclude.step2.cmake create mode 100644 Tests/RunCMake/BuildDepends/FortranIncludeNoPreprocess.f create mode 100644 Tests/RunCMake/BuildDepends/FortranIncludePreprocess.F diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index f3927b4..7626fa3 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -2227,7 +2227,7 @@ Compilation of source files within a target is split into the following steps: command = gfortran -cpp $DEFINES $INCLUDES $FLAGS -E $in -o $out && cmake -E cmake_ninja_depends \ --tdi=FortranDependInfo.json --lang=Fortran \ - --src=$out --dep=$DEP_FILE --obj=$OBJ_FILE \ + --src=$out --out=$out --dep=$DEP_FILE --obj=$OBJ_FILE \ --ddi=$DYNDEP_INTERMEDIATE_FILE build src.f90-pp.f90 | src.f90.o.ddi: Fortran_PREPROCESS src.f90 @@ -2304,6 +2304,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, { std::string arg_tdi; std::string arg_src; + std::string arg_out; std::string arg_dep; std::string arg_obj; std::string arg_ddi; @@ -2313,6 +2314,8 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, arg_tdi = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--src=")) { arg_src = arg.substr(6); + } else if (cmHasLiteralPrefix(arg, "--out=")) { + arg_out = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--dep=")) { arg_dep = arg.substr(6); } else if (cmHasLiteralPrefix(arg, "--obj=")) { @@ -2322,8 +2325,9 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, } else if (cmHasLiteralPrefix(arg, "--lang=")) { arg_lang = arg.substr(7); } else if (cmHasLiteralPrefix(arg, "--pp=")) { - // CMake 3.26 and below used '--pp=' instead of '--src='. + // CMake 3.26 and below used '--pp=' instead of '--src=' and '--out='. arg_src = arg.substr(5); + arg_out = arg_src; } else { cmSystemTools::Error( cmStrCat("-E cmake_ninja_depends unknown argument: ", arg)); @@ -2338,6 +2342,10 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, cmSystemTools::Error("-E cmake_ninja_depends requires value for --src="); return 1; } + if (arg_out.empty()) { + cmSystemTools::Error("-E cmake_ninja_depends requires value for --out="); + return 1; + } if (arg_dep.empty()) { cmSystemTools::Error("-E cmake_ninja_depends requires value for --dep="); return 1; @@ -2374,7 +2382,7 @@ int cmcmd_cmake_ninja_depends(std::vector::const_iterator argBeg, { cmGeneratedFileStream depfile(arg_dep); - depfile << cmSystemTools::ConvertToUnixOutputPath(arg_src) << ":"; + depfile << cmSystemTools::ConvertToUnixOutputPath(arg_out) << ":"; for (std::string const& include : info->Includes) { depfile << " \\\n " << cmSystemTools::ConvertToUnixOutputPath(include); } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index f035c1e..5bf6a2b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -545,7 +545,7 @@ std::string GetScanCommand(cm::string_view cmakeCmd, cm::string_view tdi, cm::string_view ddiFile) { return cmStrCat(cmakeCmd, " -E cmake_ninja_depends --tdi=", tdi, - " --lang=", lang, " --src=", srcFile, + " --lang=", lang, " --src=", srcFile, " --out=$out", " --dep=$DEP_FILE --obj=$OBJ_FILE --ddi=", ddiFile); } @@ -1258,6 +1258,7 @@ namespace { cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, const std::string& ppFileName, bool compilePP, bool compilePPWithDefines, + bool compilationPreprocesses, cmNinjaBuild& objBuild, cmNinjaVars& vars, const std::string& objectFileName, cmLocalGenerator* lg) @@ -1314,6 +1315,13 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, } else { scanBuild.Outputs.push_back(ddiFile); scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName; + if (!compilationPreprocesses) { + // Compilation does not preprocess and we are not compiling an + // already-preprocessed source. Make compilation depend on the scan + // results to honor implicit dependencies discovered during scanning + // (such as Fortran INCLUDE directives). + objBuild.ImplicitDeps.emplace_back(ddiFile); + } } // Scanning always provides a depfile for preprocessor dependencies. This @@ -1520,8 +1528,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } cmNinjaBuild ppBuild = GetScanBuildStatement( - scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild, - vars, objectFileName, this->LocalGenerator); + scanRuleName, ppFileName, compilePP, compilePPWithDefines, + compilationPreprocesses, objBuild, vars, objectFileName, + this->LocalGenerator); if (compilePP) { // In case compilation requires flags that are incompatible with diff --git a/Tests/RunCMake/BuildDepends/FortranInclude-build1-stderr.txt b/Tests/RunCMake/BuildDepends/FortranInclude-build1-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/BuildDepends/FortranInclude-build1-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/BuildDepends/FortranInclude-build2-stderr.txt b/Tests/RunCMake/BuildDepends/FortranInclude-build2-stderr.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/BuildDepends/FortranInclude-build2-stderr.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/BuildDepends/FortranInclude.cmake b/Tests/RunCMake/BuildDepends/FortranInclude.cmake new file mode 100644 index 0000000..fa9f399 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/FortranInclude.cmake @@ -0,0 +1,20 @@ +enable_language(Fortran) + +set(check_pairs "") + +add_executable(preprocess FortranIncludePreprocess.F) +set_property(TARGET preprocess PROPERTY Fortran_PREPROCESS ON) +target_include_directories(preprocess PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +list(APPEND check_pairs "$|${CMAKE_CURRENT_BINARY_DIR}/preprocess.inc") + +# LCC < 1.24 has no way to disable Fortran preprocessor +if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL "LCC" OR CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL "1.24.00") + add_executable(no_preprocess FortranIncludeNoPreprocess.f) + set_property(TARGET no_preprocess PROPERTY Fortran_PREPROCESS OFF) + target_include_directories(no_preprocess PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + list(APPEND check_pairs "$|${CMAKE_CURRENT_BINARY_DIR}/no_preprocess.inc") +endif() + +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$>.cmake CONTENT " +set(check_pairs \"${check_pairs}\") +") diff --git a/Tests/RunCMake/BuildDepends/FortranInclude.step1.cmake b/Tests/RunCMake/BuildDepends/FortranInclude.step1.cmake new file mode 100644 index 0000000..53fdc2f --- /dev/null +++ b/Tests/RunCMake/BuildDepends/FortranInclude.step1.cmake @@ -0,0 +1,2 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/preprocess.inc" "\tPRINT *, 'FortranIncludePreprocess 1'\n") +file(WRITE "${RunCMake_TEST_BINARY_DIR}/no_preprocess.inc" "\tPRINT *, 'FortranIncludeNoPreprocess 1'\n") diff --git a/Tests/RunCMake/BuildDepends/FortranInclude.step2.cmake b/Tests/RunCMake/BuildDepends/FortranInclude.step2.cmake new file mode 100644 index 0000000..05a9f11 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/FortranInclude.step2.cmake @@ -0,0 +1,2 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/preprocess.inc" "\tPRINT *, 'FortranIncludePreprocess 2'\n") +file(WRITE "${RunCMake_TEST_BINARY_DIR}/no_preprocess.inc" "\tPRINT *, 'FortranIncludeNoPreprocess 2'\n") diff --git a/Tests/RunCMake/BuildDepends/FortranIncludeNoPreprocess.f b/Tests/RunCMake/BuildDepends/FortranIncludeNoPreprocess.f new file mode 100644 index 0000000..00b04dc --- /dev/null +++ b/Tests/RunCMake/BuildDepends/FortranIncludeNoPreprocess.f @@ -0,0 +1,3 @@ + PROGRAM FortranIncludeNoPreprocess + INCLUDE 'no_preprocess.inc' + END diff --git a/Tests/RunCMake/BuildDepends/FortranIncludePreprocess.F b/Tests/RunCMake/BuildDepends/FortranIncludePreprocess.F new file mode 100644 index 0000000..680313a --- /dev/null +++ b/Tests/RunCMake/BuildDepends/FortranIncludePreprocess.F @@ -0,0 +1,3 @@ + PROGRAM FortranIncludePreprocess +#include "preprocess.inc" + END diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index b527580..dfa4f49 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -68,6 +68,10 @@ if(NOT RunCMake_GENERATOR STREQUAL "Xcode") unset(run_BuildDepends_skip_step_2) endif() +if(CMake_TEST_Fortran) + run_BuildDepends(FortranInclude) +endif() + run_BuildDepends(Custom-Symbolic-and-Byproduct) run_BuildDepends(Custom-Always) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 3007660..75f2d35 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -292,6 +292,10 @@ if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS endif() endif() +if(CMAKE_Fortran_COMPILER) + list(APPEND BuildDepends_ARGS -DCMake_TEST_Fortran=1) +endif() + add_RunCMake_test(BuildDepends -DMSVC_VERSION=${MSVC_VERSION} -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} -- cgit v0.12