author | Michael Krelin <hacker@klever.net> | 2005-03-29 21:03:31 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2005-03-29 21:03:31 (UTC) |
commit | 642dc685bd0a3f1526e22827a4539aa0e06aeff7 (patch) (unidiff) | |
tree | f796be7c3093982f18dfd630a3f95c0a2c769eb3 /lib | |
parent | b0e2dda829db4560e2c0ed7556803124a396b89f (diff) | |
download | sitecing-642dc685bd0a3f1526e22827a4539aa0e06aeff7.zip sitecing-642dc685bd0a3f1526e22827a4539aa0e06aeff7.tar.gz sitecing-642dc685bd0a3f1526e22827a4539aa0e06aeff7.tar.bz2 |
split .so generation into compile and link stage
-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 | |||
@@ -1,275 +1,321 @@ | |||
1 | #ifdef USE_PCH | 1 | #ifdef USE_PCH |
2 | #include "pch.h" | 2 | #include "pch.h" |
3 | #else | 3 | #else |
4 | #include <sys/types.h> | 4 | #include <sys/types.h> |
5 | #include <sys/stat.h> | 5 | #include <sys/stat.h> |
6 | #include <unistd.h> | 6 | #include <unistd.h> |
7 | #include <sys/wait.h> | 7 | #include <sys/wait.h> |
8 | #include <fcntl.h> | 8 | #include <fcntl.h> |
9 | #include <iostream> | 9 | #include <iostream> |
10 | #include <fstream> | 10 | #include <fstream> |
11 | #include <stdexcept> | 11 | #include <stdexcept> |
12 | #include <vector> | 12 | #include <vector> |
13 | using namespace std; | 13 | using namespace std; |
14 | #include "sitecing/component_factory.h" | 14 | #include "sitecing/component_factory.h" |
15 | #include "sitecing/sitecing_util.h" | 15 | #include "sitecing/sitecing_util.h" |
16 | #include "sitecing/sitecing_parser.h" | 16 | #include "sitecing/sitecing_parser.h" |
17 | #include "sitecing/sitecing_exception.h" | 17 | #include "sitecing/sitecing_exception.h" |
18 | #endif | 18 | #endif |
19 | 19 | ||
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), |
26 | root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), | 27 | root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), |
27 | root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), | 28 | root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), |
28 | root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { | 29 | root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { |
29 | } | 30 | } |
30 | 31 | ||
31 | void component_factory::get_dependencies(const string& dst,file_list_t& deps) { | 32 | void component_factory::get_dependencies(const string& dst,file_list_t& deps) { |
32 | deps.clear(); | 33 | deps.clear(); |
33 | string dp = normalize_path(dst,strip_trailing_slash); | 34 | string dp = normalize_path(dst,strip_trailing_slash); |
34 | // source documents | 35 | // source documents |
35 | try { // XXX: or just compare it off? | 36 | try { // XXX: or just compare it off? |
36 | string noro = strip_prefix(dp,root_source); | 37 | string noro = strip_prefix(dp,root_source); |
37 | return; | 38 | return; |
38 | }catch(utility_no_affix& una) { | 39 | }catch(utility_no_affix& una) { |
39 | } | 40 | } |
40 | // .so binaries | 41 | // .so binaries |
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) |
60 | deps.push_back(*i); | 49 | deps.push_back(*i); |
61 | } | 50 | } |
62 | return; | 51 | return; |
63 | }catch(utility_no_prefix& unp) { | 52 | }catch(utility_no_prefix& unp) { |
64 | throw konforka::exception(CODEPOINT,"component is outside of component root"); | 53 | throw konforka::exception(CODEPOINT,"component is outside of component root"); |
65 | }catch(utility_no_suffix& uns) { | 54 | }catch(utility_no_suffix& uns) { |
66 | } | 55 | } |
67 | // preprocessor targets | 56 | // preprocessor targets |
68 | for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { | 57 | for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { |
69 | try { | 58 | try { |
70 | string nos = strip_suffix(dp,pp_targets[ppt]); | 59 | string nos = strip_suffix(dp,pp_targets[ppt]); |
71 | string noro = strip_prefix(nos,root_intermediate); | 60 | string noro = strip_prefix(nos,root_intermediate); |
72 | deps.push_back(root_source+noro); | 61 | deps.push_back(root_source+noro); |
73 | ifstream imports((root_intermediate+noro+".imports").c_str(),ios::in); | 62 | ifstream imports((root_intermediate+noro+".imports").c_str(),ios::in); |
74 | if(imports.good()) { | 63 | if(imports.good()) { |
75 | string str; | 64 | string str; |
76 | while(!imports.eof()) { | 65 | while(!imports.eof()) { |
77 | imports >> str; | 66 | imports >> str; |
78 | if(!str.empty()) | 67 | if(!str.empty()) |
79 | deps.push_back(root_intermediate+str+".classname"); | 68 | deps.push_back(root_intermediate+str+".classname"); |
80 | } | 69 | } |
81 | } | 70 | } |
82 | ifstream ancestors((root_intermediate+noro+".ancestors").c_str(),ios::in); | 71 | ifstream ancestors((root_intermediate+noro+".ancestors").c_str(),ios::in); |
83 | if(ancestors.good()) { | 72 | if(ancestors.good()) { |
84 | string str; | 73 | string str; |
85 | while(!ancestors.eof()) { | 74 | while(!ancestors.eof()) { |
86 | ancestors >> str; | 75 | ancestors >> str; |
87 | if(!str.empty()) | 76 | if(!str.empty()) |
88 | deps.push_back(root_intermediate+str+".classname"); | 77 | deps.push_back(root_intermediate+str+".classname"); |
89 | } | 78 | } |
90 | } | 79 | } |
91 | config_options *co_intermediate_deps = config.lookup_config(noro,config_options::flag_intermediate_deps); | 80 | config_options *co_intermediate_deps = config.lookup_config(noro,config_options::flag_intermediate_deps); |
92 | if(co_intermediate_deps) { | 81 | if(co_intermediate_deps) { |
93 | for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i) | 82 | for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i) |
94 | deps.push_back(*i); | 83 | deps.push_back(*i); |
95 | } | 84 | } |
96 | return; | 85 | return; |
97 | }catch(utility_no_affix& una) { | 86 | }catch(utility_no_affix& una) { |
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) { |
104 | string dp = normalize_path(dst,strip_trailing_slash); | 116 | string dp = normalize_path(dst,strip_trailing_slash); |
105 | // XXX: or just compare it off, instead of throwing things around. | 117 | // XXX: or just compare it off, instead of throwing things around. |
106 | try { | 118 | try { |
107 | strip_prefix(dp,root_intermediate); | 119 | strip_prefix(dp,root_intermediate); |
108 | return file_factory::is_uptodate(dst,deps); | 120 | return file_factory::is_uptodate(dst,deps); |
109 | }catch(utility_no_prefix& unp) { | 121 | }catch(utility_no_prefix& unp) { |
110 | } | 122 | } |
111 | try { | 123 | try { |
112 | strip_prefix(dp,root_so); | 124 | strip_prefix(dp,root_so); |
113 | return file_factory::is_uptodate(dst,deps); | 125 | return file_factory::is_uptodate(dst,deps); |
114 | }catch(utility_no_prefix& unp) { | 126 | }catch(utility_no_prefix& unp) { |
115 | } | 127 | } |
116 | return true; | 128 | return true; |
117 | } | 129 | } |
118 | 130 | ||
119 | void component_factory::build(const string& dst) { | 131 | void component_factory::build(const string& dst) { |
120 | string dp = normalize_path(dst,strip_trailing_slash); | 132 | string dp = normalize_path(dst,strip_trailing_slash); |
121 | // sources | 133 | // sources |
122 | try { | 134 | try { |
123 | string noro = strip_prefix(dp,root_source); | 135 | string noro = strip_prefix(dp,root_source); |
124 | // building the sources is left up to developer | 136 | // building the sources is left up to developer |
125 | return; | 137 | return; |
126 | }catch(utility_no_prefix& unp) { | 138 | }catch(utility_no_prefix& unp) { |
127 | } | 139 | } |
128 | // .so files | 140 | // .so files |
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) { |
167 | string aso=root_so+*i+".so"; | 168 | string aso=root_so+*i+".so"; |
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 { |
183 | string nos = strip_suffix(dp,pp_targets[ppt]); | 229 | string nos = strip_suffix(dp,pp_targets[ppt]); |
184 | string noro = strip_prefix(nos,root_intermediate); | 230 | string noro = strip_prefix(nos,root_intermediate); |
185 | string src = root_source+noro; | 231 | string src = root_source+noro; |
186 | if(access(src.c_str(),R_OK)) | 232 | if(access(src.c_str(),R_OK)) |
187 | throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); | 233 | throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); |
188 | make_path(dir_name(root_intermediate+noro),0755); | 234 | make_path(dir_name(root_intermediate+noro),0755); |
189 | file_lock lock(root_intermediate+noro+".lock"); | 235 | file_lock lock(root_intermediate+noro+".lock"); |
190 | sitecing_parser parser(*this); | 236 | sitecing_parser parser(*this); |
191 | config_options *co_skeleton = config.lookup_config(noro,config_options::flag_skeleton); | 237 | config_options *co_skeleton = config.lookup_config(noro,config_options::flag_skeleton); |
192 | if(co_skeleton) | 238 | if(co_skeleton) |
193 | parser.skeleton = co_skeleton->skeleton; | 239 | parser.skeleton = co_skeleton->skeleton; |
194 | static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | 240 | static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
195 | parser.class_name = normalize_path(noro,strip_leading_slash|strip_trailing_slash); | 241 | parser.class_name = normalize_path(noro,strip_leading_slash|strip_trailing_slash); |
196 | for(string::size_type illc = parser.class_name.find_first_not_of(id_chars);illc!=string::npos;illc=parser.class_name.find_first_not_of(id_chars,illc)) { | 242 | for(string::size_type illc = parser.class_name.find_first_not_of(id_chars);illc!=string::npos;illc=parser.class_name.find_first_not_of(id_chars,illc)) { |
197 | string::size_type lc = parser.class_name.find_first_of(id_chars,illc); | 243 | string::size_type lc = parser.class_name.find_first_of(id_chars,illc); |
198 | int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; | 244 | int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; |
199 | parser.class_name.replace(illc,n,n,'_'); | 245 | parser.class_name.replace(illc,n,n,'_'); |
200 | } | 246 | } |
201 | parser.class_name = "_SCC_"+parser.class_name; | 247 | parser.class_name = "_SCC_"+parser.class_name; |
202 | parser.output_basename = nos; | 248 | parser.output_basename = nos; |
203 | parser.component_basename = noro; | 249 | parser.component_basename = noro; |
204 | try { | 250 | try { |
205 | parser.preprocess(src); | 251 | parser.preprocess(src); |
206 | }catch(preprocessor_error& pe) { | 252 | }catch(preprocessor_error& pe) { |
207 | pe.component_name = noro; | 253 | pe.component_name = noro; |
208 | pe.see(CODEPOINT); | 254 | pe.see(CODEPOINT); |
209 | throw; | 255 | throw; |
210 | } | 256 | } |
211 | return; | 257 | return; |
212 | }catch(utility_no_affix& una) { | 258 | }catch(utility_no_affix& una) { |
213 | // must be a crap from .d file | 259 | // must be a crap from .d file |
214 | } | 260 | } |
215 | } | 261 | } |
216 | cerr << "ignoring build request for " << dp << endl; | 262 | cerr << "ignoring build request for " << dp << endl; |
217 | } | 263 | } |
218 | 264 | ||
219 | int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) { | 265 | int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) { |
220 | // XXX: is it right that we do stdio/stderr tricks outside of the function? | 266 | // XXX: is it right that we do stdio/stderr tricks outside of the function? |
221 | cerr << "executing: " << cmd; | 267 | cerr << "executing: " << cmd; |
222 | vector<const char*> argv(args.size()+2); | 268 | vector<const char*> argv(args.size()+2); |
223 | argv[0]=cmd.c_str(); | 269 | argv[0]=cmd.c_str(); |
224 | int an = 1; | 270 | int an = 1; |
225 | for(list<string>::const_iterator i=args.begin();i!=args.end();i++) { | 271 | for(list<string>::const_iterator i=args.begin();i!=args.end();i++) { |
226 | cerr << " " << *i ; | 272 | cerr << " " << *i ; |
227 | argv[an++] = i->c_str(); | 273 | argv[an++] = i->c_str(); |
228 | } | 274 | } |
229 | cerr << endl; | 275 | cerr << endl; |
230 | argv[an++]=NULL; | 276 | argv[an++]=NULL; |
231 | pid_t pid = vfork(); | 277 | pid_t pid = vfork(); |
232 | if(pid==-1) { | 278 | if(pid==-1) { |
233 | close(stdo); close(stde); | 279 | close(stdo); close(stde); |
234 | throw konforka::exception(CODEPOINT,"failed to vfork()"); | 280 | throw konforka::exception(CODEPOINT,"failed to vfork()"); |
235 | } | 281 | } |
236 | if(!pid) { | 282 | if(!pid) { |
237 | // child | 283 | // child |
238 | if(dup2(stdo,1)!=1) | 284 | if(dup2(stdo,1)!=1) |
239 | _exit(-1); | 285 | _exit(-1); |
240 | if(dup2(stde,2)!=2) | 286 | if(dup2(stde,2)!=2) |
241 | _exit(-1); | 287 | _exit(-1); |
242 | close(0); | 288 | close(0); |
243 | execvp(cmd.c_str(),(char**)&argv.front()); | 289 | execvp(cmd.c_str(),(char**)&argv.front()); |
244 | _exit(-1); | 290 | _exit(-1); |
245 | } | 291 | } |
246 | // parent | 292 | // parent |
247 | close(stdo); close(stde); | 293 | close(stdo); close(stde); |
248 | int rv; | 294 | int rv; |
249 | if(waitpid(pid,&rv,0)<0) | 295 | if(waitpid(pid,&rv,0)<0) |
250 | throw konforka::exception(CODEPOINT,"failed to waitpid()"); | 296 | throw konforka::exception(CODEPOINT,"failed to waitpid()"); |
251 | return rv; | 297 | return rv; |
252 | } | 298 | } |
253 | 299 | ||
254 | string component_factory::get_classname(const string& component) { | 300 | string component_factory::get_classname(const string& component) { |
255 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname"; | 301 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname"; |
256 | make(cn); | 302 | make(cn); |
257 | ifstream ifs(cn.c_str()); | 303 | ifstream ifs(cn.c_str()); |
258 | if(!ifs.good()) | 304 | if(!ifs.good()) |
259 | throw konforka::exception(CODEPOINT,"failed to access component .classname"); | 305 | throw konforka::exception(CODEPOINT,"failed to access component .classname"); |
260 | ifs >> cn; | 306 | ifs >> cn; |
261 | return cn; | 307 | return cn; |
262 | } | 308 | } |
263 | 309 | ||
264 | void component_factory::get_ancestors(const string& component,file_list_t& rv) { | 310 | void component_factory::get_ancestors(const string& component,file_list_t& rv) { |
265 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors"; | 311 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors"; |
266 | make(cn); | 312 | make(cn); |
267 | ifstream ifs(cn.c_str()); | 313 | ifstream ifs(cn.c_str()); |
268 | if(!ifs.good()) | 314 | if(!ifs.good()) |
269 | throw konforka::exception(CODEPOINT,"filed to access component .ancestors"); | 315 | throw konforka::exception(CODEPOINT,"filed to access component .ancestors"); |
270 | rv.clear(); | 316 | rv.clear(); |
271 | while(!ifs.eof()) { | 317 | while(!ifs.eof()) { |
272 | string a; | 318 | string a; |
273 | ifs >> a; | 319 | ifs >> a; |
274 | if(!a.empty()) | 320 | if(!a.empty()) |
275 | rv.push_back(a); | 321 | rv.push_back(a); |