|
|
@@ -153,7 +153,7 @@ auto const TryCompileBaseArgParser =
|
|
|
.Bind("__CMAKE_INTERNAL"_s, &Arguments::CMakeInternal)
|
|
|
/* keep semicolon on own line */;
|
|
|
|
|
|
-auto const TryCompileBaseNonProjectArgParser =
|
|
|
+auto const TryCompileBaseSourcesArgParser =
|
|
|
cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
|
|
|
.Bind("SOURCES"_s, &Arguments::Sources)
|
|
|
.Bind("COMPILE_DEFINITIONS"_s, TryCompileCompileDefs,
|
|
|
@@ -170,6 +170,12 @@ auto const TryCompileBaseNonProjectArgParser =
|
|
|
.BIND_LANG_PROPS(OBJCXX)
|
|
|
/* keep semicolon on own line */;
|
|
|
|
|
|
+auto const TryCompileBaseNewSourcesArgParser =
|
|
|
+ cmArgumentParser<Arguments>{ TryCompileBaseSourcesArgParser }
|
|
|
+ .Bind("SOURCE_FROM_ARG"_s, &Arguments::SourceFromArg)
|
|
|
+ .Bind("SOURCE_FROM_VAR"_s, &Arguments::SourceFromVar)
|
|
|
+ /* keep semicolon on own line */;
|
|
|
+
|
|
|
auto const TryCompileBaseProjectArgParser =
|
|
|
cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
|
|
|
.Bind("PROJECT"_s, &Arguments::ProjectName)
|
|
|
@@ -182,10 +188,10 @@ auto const TryCompileProjectArgParser =
|
|
|
makeTryCompileParser(TryCompileBaseProjectArgParser);
|
|
|
|
|
|
auto const TryCompileSourcesArgParser =
|
|
|
- makeTryCompileParser(TryCompileBaseNonProjectArgParser);
|
|
|
+ makeTryCompileParser(TryCompileBaseNewSourcesArgParser);
|
|
|
|
|
|
auto const TryCompileOldArgParser =
|
|
|
- makeTryCompileParser(TryCompileBaseNonProjectArgParser)
|
|
|
+ makeTryCompileParser(TryCompileBaseSourcesArgParser)
|
|
|
.Bind(1, &Arguments::BinaryDirectory)
|
|
|
.Bind(2, &Arguments::SourceDirectoryOrFile)
|
|
|
.Bind(3, &Arguments::ProjectName)
|
|
|
@@ -196,7 +202,7 @@ auto const TryRunProjectArgParser =
|
|
|
makeTryRunParser(TryCompileBaseProjectArgParser);
|
|
|
|
|
|
auto const TryRunSourcesArgParser =
|
|
|
- makeTryRunParser(TryCompileBaseNonProjectArgParser);
|
|
|
+ makeTryRunParser(TryCompileBaseNewSourcesArgParser);
|
|
|
|
|
|
auto const TryRunOldArgParser = makeTryRunParser(TryCompileOldArgParser);
|
|
|
|
|
|
@@ -397,8 +403,21 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- // only valid for srcfile signatures
|
|
|
- if (!this->SrcFileSignature) {
|
|
|
+ if (this->SrcFileSignature) {
|
|
|
+ if (arguments.SourceFromArg && arguments.SourceFromArg->size() % 2) {
|
|
|
+ this->Makefile->IssueMessage(
|
|
|
+ MessageType::FATAL_ERROR,
|
|
|
+ "SOURCE_FROM_ARG requires exactly two arguments");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (arguments.SourceFromVar && arguments.SourceFromVar->size() % 2) {
|
|
|
+ this->Makefile->IssueMessage(
|
|
|
+ MessageType::FATAL_ERROR,
|
|
|
+ "SOURCE_FROM_VAR requires exactly two arguments");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // only valid for srcfile signatures
|
|
|
if (!arguments.LangProps.empty()) {
|
|
|
this->Makefile->IssueMessage(
|
|
|
MessageType::FATAL_ERROR,
|
|
|
@@ -419,6 +438,7 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
// make sure the binary directory exists
|
|
|
if (useUniqueBinaryDirectory) {
|
|
|
this->BinaryDirectory =
|
|
|
@@ -449,10 +469,35 @@ bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
|
|
|
std::vector<std::string> sources;
|
|
|
if (arguments.Sources) {
|
|
|
sources = std::move(*arguments.Sources);
|
|
|
- } else {
|
|
|
- // TODO: ensure SourceDirectoryOrFile has a value
|
|
|
+ } else if (arguments.SourceDirectoryOrFile) {
|
|
|
sources.emplace_back(*arguments.SourceDirectoryOrFile);
|
|
|
}
|
|
|
+ if (arguments.SourceFromArg) {
|
|
|
+ auto const k = arguments.SourceFromArg->size();
|
|
|
+ for (auto i = decltype(k){ 0 }; i < k; i += 2) {
|
|
|
+ const auto& name = (*arguments.SourceFromArg)[i + 0];
|
|
|
+ const auto& content = (*arguments.SourceFromArg)[i + 1];
|
|
|
+ auto out = this->WriteSource(name, content, "SOURCES_FROM_ARG");
|
|
|
+ if (out.empty()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ sources.emplace_back(std::move(out));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (arguments.SourceFromVar) {
|
|
|
+ auto const k = arguments.SourceFromVar->size();
|
|
|
+ for (auto i = decltype(k){ 0 }; i < k; i += 2) {
|
|
|
+ const auto& name = (*arguments.SourceFromVar)[i + 0];
|
|
|
+ const auto& var = (*arguments.SourceFromVar)[i + 1];
|
|
|
+ const auto& content = this->Makefile->GetDefinition(var);
|
|
|
+ auto out = this->WriteSource(name, content, "SOURCES_FROM_VAR");
|
|
|
+ if (out.empty()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ sources.emplace_back(std::move(out));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // TODO: ensure sources is not empty
|
|
|
|
|
|
// Detect languages to enable.
|
|
|
cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
|
|
|
@@ -1132,3 +1177,34 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName)
|
|
|
|
|
|
this->OutputFile = cmSystemTools::CollapseFullPath(outputFileLocation);
|
|
|
}
|
|
|
+
|
|
|
+std::string cmCoreTryCompile::WriteSource(std::string const& filename,
|
|
|
+ std::string const& content,
|
|
|
+ char const* command) const
|
|
|
+{
|
|
|
+ if (!cmSystemTools::GetFilenamePath(filename).empty()) {
|
|
|
+ const auto& msg =
|
|
|
+ cmStrCat(command, " given invalid filename \"", filename, "\"");
|
|
|
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ auto filepath = cmStrCat(this->BinaryDirectory, "/", filename);
|
|
|
+ cmsys::ofstream file{ filepath.c_str(), std::ios::out };
|
|
|
+ if (!file) {
|
|
|
+ const auto& msg =
|
|
|
+ cmStrCat(command, " failed to open \"", filename, "\" for writing");
|
|
|
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ file << content;
|
|
|
+ if (!file) {
|
|
|
+ const auto& msg = cmStrCat(command, " failed to write \"", filename, "\"");
|
|
|
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, msg);
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ file.close();
|
|
|
+ return filepath;
|
|
|
+}
|