-rw-r--r-- | lib/component_factory.cc | 114 |
1 files changed, 80 insertions, 34 deletions
diff --git a/lib/component_factory.cc b/lib/component_factory.cc index bcf19f2..f8666dc 100644 --- a/lib/component_factory.cc +++ b/lib/component_factory.cc | |||
@@ -20,6 +20,7 @@ | |||
20 | namespace sitecing { | 20 | namespace sitecing { |
21 | 21 | ||
22 | static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors" }; | 22 | static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors" }; |
23 | static const char *cc_targets[] = { ".o", ".d" }; | ||
23 | 24 | ||
24 | component_factory::component_factory(configuration& c) | 25 | component_factory::component_factory(configuration& c) |
25 | : config(c), | 26 | : config(c), |
@@ -41,19 +42,7 @@ namespace sitecing { | |||
41 | try { | 42 | try { |
42 | string noso = strip_suffix(dp,".so"); | 43 | string noso = strip_suffix(dp,".so"); |
43 | string noro = strip_prefix(noso,root_so); | 44 | string noro = strip_prefix(noso,root_so); |
44 | deps.push_back(root_intermediate+noro+".cc"); | 45 | deps.push_back(root_intermediate+noro+".o"); |
45 | config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); | ||
46 | if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { | ||
47 | ifstream df((root_intermediate+noro+".d").c_str(),ios::in); | ||
48 | if(df.good()) { | ||
49 | string str; | ||
50 | while(!df.eof()) { | ||
51 | df >> str; | ||
52 | if(str.find_first_of("\\:")==string::npos) | ||
53 | deps.push_back(combine_path(config.root_source+noro,str)); | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | config_options *co_so_deps = config.lookup_config(noro,config_options::flag_so_deps); | 46 | config_options *co_so_deps = config.lookup_config(noro,config_options::flag_so_deps); |
58 | if(co_so_deps) { | 47 | if(co_so_deps) { |
59 | for(list<string>::const_iterator i=co_so_deps->so_deps.begin();i!=co_so_deps->so_deps.end();++i) | 48 | for(list<string>::const_iterator i=co_so_deps->so_deps.begin();i!=co_so_deps->so_deps.end();++i) |
@@ -98,6 +87,29 @@ namespace sitecing { | |||
98 | // do nothing. must be a cpp dependency. | 87 | // do nothing. must be a cpp dependency. |
99 | } | 88 | } |
100 | } | 89 | } |
90 | // compiler targets | ||
91 | for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { | ||
92 | try { | ||
93 | string nos = strip_suffix(dp,cc_targets[cct]); | ||
94 | string noro = strip_prefix(nos,root_intermediate); | ||
95 | deps.push_back(root_intermediate+noro+".cc"); | ||
96 | config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); | ||
97 | if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { | ||
98 | ifstream df((root_intermediate+noro+".d").c_str(),ios::in); | ||
99 | if(df.good()) { | ||
100 | string str; | ||
101 | while(!df.eof()) { | ||
102 | df >> str; | ||
103 | if(str.find_first_of("\\:")==string::npos) | ||
104 | deps.push_back(combine_path(config.root_source+noro,str)); | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | // XXX: extra deps like IntermediateDeps? | ||
109 | }catch(utility_no_affix& una) { | ||
110 | // do nothing. | ||
111 | } | ||
112 | } | ||
101 | } | 113 | } |
102 | 114 | ||
103 | bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { | 115 | bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { |
@@ -129,38 +141,27 @@ namespace sitecing { | |||
129 | try { | 141 | try { |
130 | string noso = strip_suffix(dp,".so"); | 142 | string noso = strip_suffix(dp,".so"); |
131 | string noro = strip_prefix(noso,root_so); | 143 | string noro = strip_prefix(noso,root_so); |
132 | string cc = root_intermediate+noro+".cc"; | 144 | string o = root_intermediate+noro+".o"; |
133 | if(access(cc.c_str(),R_OK)) | 145 | if(access(o.c_str(),R_OK)) |
134 | throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")"); | 146 | throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")"); |
135 | make_path(dir_name(root_so+noro),0755); | 147 | make_path(dir_name(root_so+noro),0755); |
136 | string pwd = dir_name(root_source+noro); | 148 | file_lock lock_cc(root_intermediate+noro+".o.lock"); |
137 | auto_chdir dir_changer(pwd); | ||
138 | file_lock lock_source(root_intermediate+noro+".lock"); | ||
139 | file_lock lock_so(root_so+noro+".so.lock"); | 149 | file_lock lock_so(root_so+noro+".so.lock"); |
140 | int stdO = open((root_intermediate+noro+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | 150 | int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); |
141 | if(stdO<0) | 151 | if(stdO<0) |
142 | throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout"); | 152 | throw konforka::exception(CODEPOINT,"failed to open/create linker stdout"); |
143 | int stdE = open((root_intermediate+noro+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | 153 | int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); |
144 | if(stdE<0) { | 154 | if(stdE<0) { |
145 | close(stdO); | 155 | close(stdO); |
146 | throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr"); | 156 | throw konforka::exception(CODEPOINT,"failed to open/create linker stderr"); |
147 | } | 157 | } |
148 | list<string> args; | 158 | list<string> args; |
149 | config_options *co_cpp_flags = config.lookup_config(noro,config_options::flag_cpp_flags); | ||
150 | if(co_cpp_flags) { | ||
151 | args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end()); | ||
152 | } | ||
153 | config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags); | 159 | config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags); |
154 | if(co_ld_flags) { | 160 | if(co_ld_flags) { |
155 | args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end()); | 161 | args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end()); |
156 | } | 162 | } |
157 | // TODO: maybe move it to separare config option like CoreCPPFLags? | ||
158 | args.push_back("-I"+root_intermediate); | ||
159 | args.push_back("-I"+root_source); | ||
160 | args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+noro+".d"); | ||
161 | args.push_back("-shared"); | 163 | args.push_back("-shared"); |
162 | args.push_back("-o"); args.push_back(dp); | 164 | args.push_back(o); |
163 | args.push_back(cc); | ||
164 | file_list_t ancestors; | 165 | file_list_t ancestors; |
165 | get_ancestors(noro,ancestors); | 166 | get_ancestors(noro,ancestors); |
166 | for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) { | 167 | for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) { |
@@ -168,15 +169,60 @@ namespace sitecing { | |||
168 | make(aso); | 169 | make(aso); |
169 | args.push_back(aso); | 170 | args.push_back(aso); |
170 | } | 171 | } |
172 | args.push_back("-o"); args.push_back(dp); | ||
171 | // TODO: "g++" configurable | 173 | // TODO: "g++" configurable |
172 | int rv = execute("g++",args,stdO,stdE); | 174 | int rv = execute("g++",args,stdO,stdE); |
173 | if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) | 175 | if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) |
174 | throw compile_error(CODEPOINT,"failed to compile component",noro); | 176 | // TODO:TODO: linker_error |
177 | throw compile_error(CODEPOINT,"failed to link component",noro); | ||
175 | return; | 178 | return; |
176 | }catch(utility_no_prefix& unp) { | 179 | }catch(utility_no_prefix& unp) { |
177 | throw konforka::exception(CODEPOINT,"component is outside of component root"); | 180 | throw konforka::exception(CODEPOINT,"component is outside of component root"); |
178 | }catch(utility_no_suffix& uns) { | 181 | }catch(utility_no_suffix& uns) { |
179 | } | 182 | } |
183 | // compiler targets | ||
184 | for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { | ||
185 | try { | ||
186 | string nos = strip_suffix(dp,cc_targets[cct]); | ||
187 | string noro = strip_prefix(nos,root_intermediate); | ||
188 | string cc = root_intermediate+noro+".cc"; | ||
189 | string o = root_intermediate+noro+".o"; | ||
190 | if(access(cc.c_str(),R_OK)) | ||
191 | throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")"); | ||
192 | make_path(dir_name(cc),0755); | ||
193 | string pwd = dir_name(root_source+noro); | ||
194 | auto_chdir dir_changer(pwd); | ||
195 | file_lock lock_source(root_intermediate+noro+".lock"); | ||
196 | file_lock lock_cc(root_intermediate+noro+".o.lock"); | ||
197 | int stdO = open((root_intermediate+noro+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | ||
198 | if(stdO<0) | ||
199 | throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout"); | ||
200 | int stdE = open((root_intermediate+noro+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | ||
201 | if(stdE<0) { | ||
202 | close(stdO); | ||
203 | throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr"); | ||
204 | } | ||
205 | list<string> args; | ||
206 | config_options *co_cpp_flags = config.lookup_config(noro,config_options::flag_cpp_flags); | ||
207 | if(co_cpp_flags) { | ||
208 | args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end()); | ||
209 | } | ||
210 | // TODO: maybe move it to separare config option like CoreCPPFLags? | ||
211 | args.push_back("-I"+root_intermediate); | ||
212 | args.push_back("-I"+root_source); | ||
213 | args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+noro+".d"); | ||
214 | args.push_back("-c"); | ||
215 | args.push_back(cc); | ||
216 | args.push_back("-o"); args.push_back(o); | ||
217 | // TODO: "g++" configurable | ||
218 | int rv = execute("g++",args,stdO,stdE); | ||
219 | if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) | ||
220 | throw compile_error(CODEPOINT,"failed to compile component",noro); | ||
221 | return; | ||
222 | }catch(utility_no_affix& una) { | ||
223 | // do nothing, not a compiler target | ||
224 | } | ||
225 | } | ||
180 | // preprocessor targets | 226 | // preprocessor targets |
181 | for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { | 227 | for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { |
182 | try { | 228 | try { |