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 #ifndef GLSLC_DEPENDENCY_INFO_H
16 #define GLSLC_DEPENDENCY_INFO_H
17 
18 #include <unordered_set>
19 #include <string>
20 #include <string>
21 
22 namespace glslc {
23 
24 // An object to handle everything about dumping dependency info. Internally it
25 // has two valid dumping mode: 1) Dump to extra dependency info files, such as
26 // *.d files. This mode is used when we want to generate dependency info and
27 // also compile. 2) Overwrite the original compilation output and dump
28 // dependency info as compilation output. This mode is used when we do not want
29 // to compile the source code and want the dependency info only.
30 class DependencyInfoDumpingHandler {
31  public:
32   DependencyInfoDumpingHandler();
33 
34   // Sets the dependency target explicitly. It's the same as the argument to
35   // -MT.
SetTarget(const std::string & target_label)36   void SetTarget(const std::string& target_label) {
37     user_specified_dep_target_label_ = target_label;
38   }
39 
40   // Sets the name of the file where dependency info will be written.
SetDependencyFileName(const std::string & dep_file_name)41   void SetDependencyFileName(const std::string& dep_file_name) {
42     user_specified_dep_file_name_ = dep_file_name;
43   }
44 
45   // Dump depdendency info to a) an extra dependency info file, b) an string
46   // which holds the compilation output. The choice depends on the dump
47   // mode of the handler. Returns true if dumping is succeeded, false otherwise.
48   //
49   // The dependency file name and target are deduced based on 1) user
50   // specified dependency file name and target name, 2) the output filename when
51   // the compiler is in 'does not need linking' and 'not preprocessing-only'
52   // mode. It is passed through compilation_output_file_name.
53   //
54   // When the handler is set to dump dependency info as extra dependency info
55   // files, this method will open a file with the dependency file name and write
56   // the dependency info to it. Error messages caused by writing to the file are
57   // emitted to stderr.
58   //
59   // When the handler is set to dump dependency info as compilation output, the
60   // compilation output string, which is passed through compilation_output_ptr,
61   // will be cleared and this method will write dependency info to it. Then the
62   // dependency info should be emitted as normal compilation output.
63   //
64   // If the dump mode is not set when this method is called, return false.
65   bool DumpDependencyInfo(std::string compilation_output_file_name,
66                           std::string source_file_name,
67                           std::string* compilation_output_ptr,
68                           const std::unordered_set<std::string>& dependent_files);
69 
70   // Sets to always dump dependency info as an extra file, instead of the normal
71   // compilation output. This means the output name specified by -o options
72   // won't be used for the dependency info file.
SetDumpToExtraDependencyInfoFiles()73   void SetDumpToExtraDependencyInfoFiles() { mode_ = dump_as_extra_file; }
74 
75   // Sets to dump dependency info as normal compilation output. The dependency
76   // info will be either saved in a file with -o option specified file, or, if
77   // no output file name specified, to stdout.
SetDumpAsNormalCompilationOutput()78   void SetDumpAsNormalCompilationOutput() {
79     mode_ = dump_as_compilation_output;
80   }
81 
82   // Returns true if the handler's dumping mode is set to dump dependency info
83   // as extra dependency info files.
DumpingToExtraDependencyInfoFiles()84   bool DumpingToExtraDependencyInfoFiles() {
85     return mode_ == dump_as_extra_file;
86   }
87 
88   // Returns true if the handler's dumping mode is set to dump dependency info
89   // as normal compilation output.
DumpingAsCompilationOutput()90   bool DumpingAsCompilationOutput() {
91     return mode_ == dump_as_compilation_output;
92   }
93 
94   // Returns true if the handler's dumping mode is not set.
DumpingModeNotSet()95   bool DumpingModeNotSet() { return mode_ == not_set; }
96 
97   // Returns true if the handler is at valid state for dumping dependency info.
98   bool IsValid(std::string* error_msg_ptr, size_t num_files);
99 
100  private:
101   typedef enum {
102     // not_set mode tells that the dumping mode is not set yet, so the handler
103     // is not ready for dumping dependency info. Calling DumpDependencyInfo when
104     // the handler is in this mode will cause failure.
105     not_set = 0,
106     // Dumping dependency info as normal compilation output mode.  In this mode,
107     // the dependency info will be dumped as compilation output by overwriting
108     // the string which holds the compilation output.
109     dump_as_compilation_output,
110     // Dumping dependency info as extra dependency info files mode. In this
111     // mode, dependency info will be dumped to a user specified dependency info
112     // file or a *.d file. Compilation output will still be generated along with
113     // the dependency info.
114     dump_as_extra_file,
115   } dump_mode;
116 
117   // Returns the target file label to be used in depdendency info file. If -MT
118   // defined a label, use that string as the label. Otherwise returns the
119   // compilation output filename deduced in 'doesn't need linking' and 'not
120   // preprocessing-only' mode.
121   std::string GetTarget(const std::string& compilation_output_file_name);
122 
123   // Returns the dependency file name to be used. If -MF defined a file name
124   // before, use it. Othwise, returns a filename formed by appending .d to the
125   // output filename deduced in 'doesn't need linking' and 'no
126   // preprocessing-only' mode.
127   std::string GetDependencyFileName(
128       const std::string& compilation_output_file_name);
129 
130   std::string user_specified_dep_file_name_;
131   std::string user_specified_dep_target_label_;
132   dump_mode mode_;
133 };
134 }
135 
136 #endif  // GLSLC_DEPENDENCY_INFO_H
137