1 // Copyright 2015 The Shaderc Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "dependency_info.h"
16
17 #include <fstream>
18 #include <iostream>
19 #include <sstream>
20
21 #include "file.h"
22 #include "libshaderc_util/io.h"
23
24 namespace glslc {
25
DependencyInfoDumpingHandler()26 DependencyInfoDumpingHandler::DependencyInfoDumpingHandler() : mode_(not_set) {}
27
DumpDependencyInfo(std::string compilation_output_file_name,std::string source_file_name,std::string * compilation_output_ptr,const std::unordered_set<std::string> & dependent_files)28 bool DependencyInfoDumpingHandler::DumpDependencyInfo(
29 std::string compilation_output_file_name, std::string source_file_name,
30 std::string* compilation_output_ptr,
31 const std::unordered_set<std::string>& dependent_files) {
32 std::string dep_target_label = GetTarget(compilation_output_file_name);
33 std::string dep_file_name =
34 GetDependencyFileName(compilation_output_file_name);
35
36 // Dump everything to a string stream first, then dump its content to either
37 // a file or compilation output string, depends on current dumping mode.
38 std::stringstream dep_string_stream;
39 // dump target label and the source_file_name.
40 dep_string_stream << dep_target_label << ": " << source_file_name;
41 // dump the dependent file names.
42 for (auto& dependent_file_name : dependent_files) {
43 dep_string_stream << " " << dependent_file_name;
44 }
45 dep_string_stream << std::endl;
46
47 if (mode_ == dump_as_compilation_output) {
48 compilation_output_ptr->assign(dep_string_stream.str());
49 } else if (mode_ == dump_as_extra_file) {
50 std::ofstream potential_file_stream_for_dep_info_dump;
51 std::ostream* dep_file_stream = shaderc_util::GetOutputStream(
52 dep_file_name, &potential_file_stream_for_dep_info_dump, &std::cerr);
53 *dep_file_stream << dep_string_stream.str();
54 if (dep_file_stream->fail()) {
55 std::cerr << "glslc: error: error writing dependent_files info to output "
56 "file: '"
57 << dep_file_name << "'" << std::endl;
58 return false;
59 }
60 } else {
61 // mode_ should not be 'not_set', we should never be here.
62 return false;
63 }
64 return true;
65 }
66
GetTarget(const std::string & compilation_output_file_name)67 std::string DependencyInfoDumpingHandler::GetTarget(
68 const std::string& compilation_output_file_name) {
69 if (!user_specified_dep_target_label_.empty()) {
70 return user_specified_dep_target_label_;
71 }
72
73 return compilation_output_file_name;
74 }
75
GetDependencyFileName(const std::string & compilation_output_file_name)76 std::string DependencyInfoDumpingHandler::GetDependencyFileName(
77 const std::string& compilation_output_file_name) {
78 if (!user_specified_dep_file_name_.empty()) {
79 return user_specified_dep_file_name_;
80 }
81
82 return compilation_output_file_name + ".d";
83 }
84
IsValid(std::string * error_msg_ptr,size_t num_files)85 bool DependencyInfoDumpingHandler::IsValid(std::string* error_msg_ptr,
86 size_t num_files) {
87 if (DumpingModeNotSet()) {
88 *error_msg_ptr =
89 "to generate dependencies you must specify either -M (-MM) or -MD";
90 return false;
91 }
92
93 if (!user_specified_dep_file_name_.empty() ||
94 !user_specified_dep_target_label_.empty()) {
95 if (num_files > 1) {
96 *error_msg_ptr =
97 "to specify dependency info file name or dependency info target, "
98 "only one input file is allowed.";
99 return false;
100 }
101 }
102 return true;
103 }
104 }
105