1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmIncludeCommand.h"
9 #include "cmExecutionStatus.h"
10 #include "cmGlobalGenerator.h"
11 #include "cmMakefile.h"
12 #include "cmMessageType.h"
13 #include "cmPolicies.h"
14 #include "cmStringAlgorithms.h"
15 #include "cmSystemTools.h"
18 bool cmIncludeCommand(std::vector
<std::string
> const& args
,
19 cmExecutionStatus
& status
)
21 static std::map
<std::string
, cmPolicies::PolicyID
> DeprecatedModules
;
22 if (DeprecatedModules
.empty()) {
23 DeprecatedModules
["Dart"] = cmPolicies::CMP0145
;
24 DeprecatedModules
["Documentation"] = cmPolicies::CMP0106
;
25 DeprecatedModules
["FindCUDA"] = cmPolicies::CMP0146
;
26 DeprecatedModules
["FindDart"] = cmPolicies::CMP0145
;
27 DeprecatedModules
["FindPythonInterp"] = cmPolicies::CMP0148
;
28 DeprecatedModules
["FindPythonLibs"] = cmPolicies::CMP0148
;
29 DeprecatedModules
["WriteCompilerDetectionHeader"] = cmPolicies::CMP0120
;
32 if (args
.empty() || args
.size() > 4) {
33 status
.SetError("called with wrong number of arguments. "
34 "include() only takes one file.");
37 bool optional
= false;
38 bool noPolicyScope
= false;
39 std::string fname
= args
[0];
40 std::string resultVarName
;
42 for (unsigned int i
= 1; i
< args
.size(); i
++) {
43 if (args
[i
] == "OPTIONAL") {
45 status
.SetError("called with invalid arguments: OPTIONAL used twice");
49 } else if (args
[i
] == "RESULT_VARIABLE") {
50 if (!resultVarName
.empty()) {
51 status
.SetError("called with invalid arguments: "
52 "only one result variable allowed");
55 if (++i
< args
.size()) {
56 resultVarName
= args
[i
];
58 status
.SetError("called with no value for RESULT_VARIABLE.");
61 } else if (args
[i
] == "NO_POLICY_SCOPE") {
63 } else if (i
> 1) // compat.: in previous cmake versions the second
64 // parameter was ignored if it wasn't "OPTIONAL"
66 std::string errorText
=
67 cmStrCat("called with invalid argument: ", args
[i
]);
68 status
.SetError(errorText
);
74 status
.GetMakefile().IssueMessage(
75 MessageType::AUTHOR_WARNING
,
76 "include() given empty file name (ignored).");
80 if (!cmSystemTools::FileIsFullPath(fname
)) {
82 // Not a path. Maybe module.
83 std::string module
= cmStrCat(fname
, ".cmake");
84 std::string mfile
= status
.GetMakefile().GetModulesFile(module
, system
);
87 auto ModulePolicy
= DeprecatedModules
.find(fname
);
88 if (ModulePolicy
!= DeprecatedModules
.end()) {
89 cmPolicies::PolicyStatus PolicyStatus
=
90 status
.GetMakefile().GetPolicyStatus(ModulePolicy
->second
);
91 switch (PolicyStatus
) {
92 case cmPolicies::WARN
: {
93 status
.GetMakefile().IssueMessage(
94 MessageType::AUTHOR_WARNING
,
95 cmStrCat(cmPolicies::GetPolicyWarning(ModulePolicy
->second
),
101 case cmPolicies::REQUIRED_IF_USED
:
102 case cmPolicies::REQUIRED_ALWAYS
:
103 case cmPolicies::NEW
:
110 if (!mfile
.empty()) {
115 std::string fname_abs
= cmSystemTools::CollapseFullPath(
116 fname
, status
.GetMakefile().GetCurrentSourceDirectory());
118 cmGlobalGenerator
* gg
= status
.GetMakefile().GetGlobalGenerator();
119 if (gg
->IsExportedTargetsFile(fname_abs
)) {
120 const char* modal
= nullptr;
121 std::ostringstream e
;
122 MessageType messageType
= MessageType::AUTHOR_WARNING
;
124 switch (status
.GetMakefile().GetPolicyStatus(cmPolicies::CMP0024
)) {
125 case cmPolicies::WARN
:
126 e
<< cmPolicies::GetPolicyWarning(cmPolicies::CMP0024
) << "\n";
129 case cmPolicies::OLD
:
131 case cmPolicies::REQUIRED_IF_USED
:
132 case cmPolicies::REQUIRED_ALWAYS
:
133 case cmPolicies::NEW
:
135 messageType
= MessageType::FATAL_ERROR
;
138 e
<< "The file\n " << fname_abs
139 << "\nwas generated by the export() "
142 << " not be used as the argument to the "
143 "include() command. Use ALIAS targets instead to refer to targets "
144 "by alternative names.\n";
145 status
.GetMakefile().IssueMessage(messageType
, e
.str());
146 if (messageType
== MessageType::FATAL_ERROR
) {
150 gg
->CreateGenerationObjects();
151 gg
->GenerateImportFile(fname_abs
);
154 std::string listFile
= cmSystemTools::CollapseFullPath(
155 fname
, status
.GetMakefile().GetCurrentSourceDirectory());
157 const bool fileDoesnotExist
= !cmSystemTools::FileExists(listFile
);
158 const bool fileIsDirectory
= cmSystemTools::FileIsDirectory(listFile
);
159 if (fileDoesnotExist
|| fileIsDirectory
) {
160 if (!resultVarName
.empty()) {
161 status
.GetMakefile().AddDefinition(resultVarName
, "NOTFOUND");
166 if (fileDoesnotExist
) {
167 status
.SetError(cmStrCat("could not find requested file:\n ", fname
));
170 if (fileIsDirectory
) {
171 status
.SetError(cmStrCat("requested file is a directory:\n ", fname
));
177 status
.GetMakefile().ReadDependentFile(listFile
, noPolicyScope
);
179 // add the location of the included file if a result variable was given
180 if (!resultVarName
.empty()) {
181 status
.GetMakefile().AddDefinition(
182 resultVarName
, readit
? fname_abs
.c_str() : "NOTFOUND");
185 if (!optional
&& !readit
&& !cmSystemTools::GetFatalErrorOccurred()) {
186 std::string m
= cmStrCat("could not load requested file:\n ", fname
);