compiler: Correct depfile generation when there are no outputs

Prevents the compiler from generating a malformed depfile if an inpout file did not lead to any meaningful generation. This is an edge case that is not exercised often.

PiperOrigin-RevId: 542354842
pull/13111/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent b0b926a141
commit a44fc2b063
  1. 47
      src/google/protobuf/compiler/command_line_interface.cc

@ -2520,6 +2520,7 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
output_filenames.push_back(descriptor_set_out_name_);
}
// Create the depfile, even if it will be empty.
int fd;
do {
fd = open(dependency_out_name_.c_str(),
@ -2531,30 +2532,34 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
return false;
}
io::FileOutputStream out(fd);
io::Printer printer(&out, '$');
// Only write to the depfile if there is at least one output_filename.
// Otherwise, the depfile will be malformed.
if (!output_filenames.empty()) {
io::FileOutputStream out(fd);
io::Printer printer(&out, '$');
for (int i = 0; i < output_filenames.size(); i++) {
printer.Print(output_filenames[i]);
if (i == output_filenames.size() - 1) {
printer.Print(":");
} else {
printer.Print(" \\\n");
for (size_t i = 0; i < output_filenames.size(); i++) {
printer.Print(output_filenames[i]);
if (i == output_filenames.size() - 1) {
printer.Print(":");
} else {
printer.Print(" \\\n");
}
}
}
for (int i = 0; i < file_set.file_size(); i++) {
const FileDescriptorProto& file = file_set.file(i);
const std::string& virtual_file = file.name();
std::string disk_file;
if (source_tree &&
source_tree->VirtualFileToDiskFile(virtual_file, &disk_file)) {
printer.Print(" $disk_file$", "disk_file", disk_file);
if (i < file_set.file_size() - 1) printer.Print("\\\n");
} else {
std::cerr << "Unable to identify path for file " << virtual_file
<< std::endl;
return false;
for (int i = 0; i < file_set.file_size(); i++) {
const FileDescriptorProto& file = file_set.file(i);
const std::string& virtual_file = file.name();
std::string disk_file;
if (source_tree &&
source_tree->VirtualFileToDiskFile(virtual_file, &disk_file)) {
printer.Print(" $disk_file$", "disk_file", disk_file);
if (i < file_set.file_size() - 1) printer.Print("\\\n");
} else {
std::cerr << "Unable to identify path for file " << virtual_file
<< std::endl;
return false;
}
}
}

Loading…
Cancel
Save