summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--lib/component_factory.cc114
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 @@
20namespace sitecing { 20namespace 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 {