-rw-r--r-- | include/sitecing/sitecing_exception.h | 29 | ||||
-rw-r--r-- | lib/component_factory.cc | 3 |
2 files changed, 30 insertions, 2 deletions
diff --git a/include/sitecing/sitecing_exception.h b/include/sitecing/sitecing_exception.h index bf475ac..cb5edd9 100644 --- a/include/sitecing/sitecing_exception.h +++ b/include/sitecing/sitecing_exception.h | |||
@@ -1,103 +1,132 @@ | |||
1 | #ifndef __SITECING_SITECING_EXCEPTION_H | 1 | #ifndef __SITECING_SITECING_EXCEPTION_H |
2 | #define __SITECING_SITECING_EXCEPTION_H | 2 | #define __SITECING_SITECING_EXCEPTION_H |
3 | 3 | ||
4 | #include <konforka/exception.h> | 4 | #include <konforka/exception.h> |
5 | 5 | ||
6 | /** | 6 | /** |
7 | * @file | 7 | * @file |
8 | * @brief The site-C-ing specific exception. | 8 | * @brief The site-C-ing specific exception. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | namespace sitecing { | 11 | namespace sitecing { |
12 | 12 | ||
13 | /** | 13 | /** |
14 | * The comonent failed to link. | ||
15 | */ | ||
16 | class link_error : public konforka::exception { | ||
17 | public: | ||
18 | /** | ||
19 | * The component path | ||
20 | */ | ||
21 | string component_path; | ||
22 | |||
23 | /** | ||
24 | * @param w the message. | ||
25 | * @param cp component path. | ||
26 | */ | ||
27 | link_error(const string& w,const string& cp) | ||
28 | : konforka::exception(NOCODEPOINT,w), component_path(cp) { } | ||
29 | /** | ||
30 | * @param fi the file name where the exception is thrown from. | ||
31 | * @param fu the function name where the exception originates from. | ||
32 | * @param l the line number where the exception originates from. | ||
33 | * @param w the message. | ||
34 | * @param cp component path. | ||
35 | */ | ||
36 | link_error(const string& fi,const string& fu,int l,const string& w,const string& cp) | ||
37 | : konforka::exception(fi,fu,l,w), component_path(cp) { } | ||
38 | ~link_error() throw() { } | ||
39 | }; | ||
40 | |||
41 | /** | ||
14 | * The component failed to compile. | 42 | * The component failed to compile. |
15 | */ | 43 | */ |
16 | class compile_error : public konforka::exception { | 44 | class compile_error : public konforka::exception { |
17 | public: | 45 | public: |
18 | /** | 46 | /** |
19 | * The component path | 47 | * The component path |
20 | */ | 48 | */ |
21 | string component_path; | 49 | string component_path; |
22 | 50 | ||
23 | /** | 51 | /** |
24 | * @param w the message. | 52 | * @param w the message. |
25 | * @param cp component path. | 53 | * @param cp component path. |
26 | */ | 54 | */ |
27 | compile_error(const string& w,const string& cp) | 55 | compile_error(const string& w,const string& cp) |
28 | : konforka::exception(NOCODEPOINT,w), component_path(cp) { } | 56 | : konforka::exception(NOCODEPOINT,w), component_path(cp) { } |
29 | /** | 57 | /** |
30 | * @param whe point in code. | 58 | * @param whe point in code. |
31 | * @param wha the message. | 59 | * @param wha the message. |
32 | * @param cp component path. | 60 | * @param cp component path. |
33 | */ | 61 | */ |
34 | compile_error(const string &whe,const string& wha,const string& cp) | 62 | compile_error(const string &whe,const string& wha,const string& cp) |
35 | : konforka::exception(whe,wha), component_path(cp) { } | 63 | : konforka::exception(whe,wha), component_path(cp) { } |
36 | /** | 64 | /** |
37 | * @param fi the file name where the exception is thrown from. | 65 | * @param fi the file name where the exception is thrown from. |
38 | * @param fu the function name where the exception originates from. | 66 | * @param fu the function name where the exception originates from. |
39 | * @param l the line number where the exception originates from. | 67 | * @param l the line number where the exception originates from. |
68 | * @param w the message. | ||
40 | * @param cp component path. | 69 | * @param cp component path. |
41 | */ | 70 | */ |
42 | compile_error(const string &fi,const string& fu,int l,const string& w,const string& cp) | 71 | compile_error(const string &fi,const string& fu,int l,const string& w,const string& cp) |
43 | : konforka::exception(fi,fu,l,w), component_path(cp) { } | 72 | : konforka::exception(fi,fu,l,w), component_path(cp) { } |
44 | ~compile_error() throw() { } | 73 | ~compile_error() throw() { } |
45 | }; | 74 | }; |
46 | 75 | ||
47 | /** | 76 | /** |
48 | * Failed to preprocess component source. | 77 | * Failed to preprocess component source. |
49 | */ | 78 | */ |
50 | class preprocessor_error : public konforka::exception { | 79 | class preprocessor_error : public konforka::exception { |
51 | public: | 80 | public: |
52 | /** | 81 | /** |
53 | * Component name. | 82 | * Component name. |
54 | */ | 83 | */ |
55 | string component_name; | 84 | string component_name; |
56 | /** | 85 | /** |
57 | * The line number of the source code where the error occured. | 86 | * The line number of the source code where the error occured. |
58 | */ | 87 | */ |
59 | int line_number; | 88 | int line_number; |
60 | 89 | ||
61 | /** | 90 | /** |
62 | * @param fi file name where the exception originates from. | 91 | * @param fi file name where the exception originates from. |
63 | * @param fu the function name where the exception originates from. | 92 | * @param fu the function name where the exception originates from. |
64 | * @param l the line number where the exception originate from. | 93 | * @param l the line number where the exception originate from. |
65 | * @param w the error message. | 94 | * @param w the error message. |
66 | * @param cn the component name. | 95 | * @param cn the component name. |
67 | * @param ln the line of the component source where the error occured. | 96 | * @param ln the line of the component source where the error occured. |
68 | */ | 97 | */ |
69 | preprocessor_error(const string& fi,const string& fu,int l,const string& w,const string& cn,int ln) | 98 | preprocessor_error(const string& fi,const string& fu,int l,const string& w,const string& cn,int ln) |
70 | : konforka::exception(fi,fu,l,w), component_name(cn), line_number(ln) { } | 99 | : konforka::exception(fi,fu,l,w), component_name(cn), line_number(ln) { } |
71 | /** | 100 | /** |
72 | * @param fi file name where the exception originates from. | 101 | * @param fi file name where the exception originates from. |
73 | * @param fu the function name where the exception originates from. | 102 | * @param fu the function name where the exception originates from. |
74 | * @param l the line number where the exception originate from. | 103 | * @param l the line number where the exception originate from. |
75 | * @param w the error message. | 104 | * @param w the error message. |
76 | * @param cn the component name. | 105 | * @param cn the component name. |
77 | */ | 106 | */ |
78 | preprocessor_error(const string& fi,const string& fu,int l,const string& w,const string& cn) | 107 | preprocessor_error(const string& fi,const string& fu,int l,const string& w,const string& cn) |
79 | : konforka::exception(fi,fu,l,w), component_name(cn), line_number(-1) { } | 108 | : konforka::exception(fi,fu,l,w), component_name(cn), line_number(-1) { } |
80 | /** | 109 | /** |
81 | * @param fi file name where the exception originates from. | 110 | * @param fi file name where the exception originates from. |
82 | * @param fu the function name where the exception originates from. | 111 | * @param fu the function name where the exception originates from. |
83 | * @param l the line number where the exception originate from. | 112 | * @param l the line number where the exception originate from. |
84 | * @param w the error message. | 113 | * @param w the error message. |
85 | * @param ln the line of the component source where the error occured. | 114 | * @param ln the line of the component source where the error occured. |
86 | */ | 115 | */ |
87 | preprocessor_error(const string& fi,const string& fu,int l,const string& w,int ln) | 116 | preprocessor_error(const string& fi,const string& fu,int l,const string& w,int ln) |
88 | : konforka::exception(fi,fu,l,w), line_number(ln) { } | 117 | : konforka::exception(fi,fu,l,w), line_number(ln) { } |
89 | /** | 118 | /** |
90 | * @param fi file name where the exception originates from. | 119 | * @param fi file name where the exception originates from. |
91 | * @param fu the function name where the exception originates from. | 120 | * @param fu the function name where the exception originates from. |
92 | * @param l the line number where the exception originate from. | 121 | * @param l the line number where the exception originate from. |
93 | * @param w the error message. | 122 | * @param w the error message. |
94 | */ | 123 | */ |
95 | preprocessor_error(const string& fi,const string& fu,int l,const string& w) | 124 | preprocessor_error(const string& fi,const string& fu,int l,const string& w) |
96 | : konforka::exception(fi,fu,l,w), line_number(-1) { } | 125 | : konforka::exception(fi,fu,l,w), line_number(-1) { } |
97 | 126 | ||
98 | ~preprocessor_error() throw() {} | 127 | ~preprocessor_error() throw() {} |
99 | }; | 128 | }; |
100 | 129 | ||
101 | } | 130 | } |
102 | 131 | ||
103 | #endif /* __SITECING_SITECING_EXCEPTION_H */ | 132 | #endif /* __SITECING_SITECING_EXCEPTION_H */ |
diff --git a/lib/component_factory.cc b/lib/component_factory.cc index a5ced6b..2a2eefe 100644 --- a/lib/component_factory.cc +++ b/lib/component_factory.cc | |||
@@ -1,322 +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", ".pp_stamp" }; | 22 | static const char *pp_targets[] = { ".cc", ".h", ".imports", ".classname", ".baseclassname", ".ancestors", ".pp_stamp" }; |
23 | static const char *cc_targets[] = { ".o", ".d" }; | 23 | static const char *cc_targets[] = { ".o", ".d" }; |
24 | 24 | ||
25 | component_factory::component_factory(configuration& c) | 25 | component_factory::component_factory(configuration& c) |
26 | : config(c), | 26 | : config(c), |
27 | root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), | 27 | root_source(normalize_path(c.root_source,strip_trailing_slash)+'/'), |
28 | root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), | 28 | root_intermediate(normalize_path(c.root_intermediate,strip_trailing_slash)+'/'), |
29 | root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { | 29 | root_so(normalize_path(c.root_so,strip_trailing_slash)+'/') { |
30 | } | 30 | } |
31 | 31 | ||
32 | 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) { |
33 | deps.clear(); | 33 | deps.clear(); |
34 | string dp = normalize_path(dst,strip_trailing_slash); | 34 | string dp = normalize_path(dst,strip_trailing_slash); |
35 | // source documents | 35 | // source documents |
36 | try { // XXX: or just compare it off? | 36 | try { // XXX: or just compare it off? |
37 | string noro = strip_prefix(dp,root_source); | 37 | string noro = strip_prefix(dp,root_source); |
38 | return; | 38 | return; |
39 | }catch(utility_no_affix& una) { } | 39 | }catch(utility_no_affix& una) { } |
40 | // .so binaries | 40 | // .so binaries |
41 | try { | 41 | try { |
42 | string noso = strip_suffix(dp,".so"); | 42 | string noso = strip_suffix(dp,".so"); |
43 | string noro = strip_prefix(noso,root_so); | 43 | string noro = strip_prefix(noso,root_so); |
44 | deps.push_back(root_intermediate+noro+".o"); | 44 | deps.push_back(root_intermediate+noro+".o"); |
45 | config_options *co_so_deps = config.lookup_config(noro,config_options::flag_so_deps); | 45 | config_options *co_so_deps = config.lookup_config(noro,config_options::flag_so_deps); |
46 | if(co_so_deps) { | 46 | if(co_so_deps) { |
47 | for(list<string>::const_iterator i=co_so_deps->so_deps.begin();i!=co_so_deps->so_deps.end();++i) | 47 | for(list<string>::const_iterator i=co_so_deps->so_deps.begin();i!=co_so_deps->so_deps.end();++i) |
48 | deps.push_back(*i); | 48 | deps.push_back(*i); |
49 | } | 49 | } |
50 | return; | 50 | return; |
51 | }catch(utility_no_prefix& unp) { | 51 | }catch(utility_no_prefix& unp) { |
52 | throw konforka::exception(CODEPOINT,"component is outside of component root"); | 52 | throw konforka::exception(CODEPOINT,"component is outside of component root"); |
53 | }catch(utility_no_suffix& uns) { } | 53 | }catch(utility_no_suffix& uns) { } |
54 | try { | 54 | try { |
55 | // preprocessor targets | 55 | // preprocessor targets |
56 | string noro = strip_prefix(dp,root_intermediate); | 56 | string noro = strip_prefix(dp,root_intermediate); |
57 | 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++) { |
58 | try { | 58 | try { |
59 | string nos = strip_suffix(noro,pp_targets[ppt]); | 59 | string nos = strip_suffix(noro,pp_targets[ppt]); |
60 | deps.push_back(root_source+nos); // depends on the source | 60 | deps.push_back(root_source+nos); // depends on the source |
61 | ifstream imports((root_intermediate+nos+".imports").c_str(),ios::in); | 61 | ifstream imports((root_intermediate+nos+".imports").c_str(),ios::in); |
62 | if(imports.good()) { | 62 | if(imports.good()) { |
63 | string str; | 63 | string str; |
64 | while(!imports.eof()) { | 64 | while(!imports.eof()) { |
65 | imports >> str; | 65 | imports >> str; |
66 | if(!str.empty()) | 66 | if(!str.empty()) |
67 | deps.push_back(root_intermediate+str+".classname"); | 67 | deps.push_back(root_intermediate+str+".classname"); |
68 | } | 68 | } |
69 | } | 69 | } |
70 | ifstream ancestors((root_intermediate+nos+".ancestors").c_str(),ios::in); | 70 | ifstream ancestors((root_intermediate+nos+".ancestors").c_str(),ios::in); |
71 | if(ancestors.good()) { | 71 | if(ancestors.good()) { |
72 | string str; | 72 | string str; |
73 | while(!ancestors.eof()) { | 73 | while(!ancestors.eof()) { |
74 | ancestors >> str; | 74 | ancestors >> str; |
75 | if(!str.empty()) | 75 | if(!str.empty()) |
76 | deps.push_back(root_intermediate+str+".classname"); | 76 | deps.push_back(root_intermediate+str+".classname"); |
77 | } | 77 | } |
78 | } | 78 | } |
79 | config_options *co_intermediate_deps = config.lookup_config(nos,config_options::flag_intermediate_deps); | 79 | config_options *co_intermediate_deps = config.lookup_config(nos,config_options::flag_intermediate_deps); |
80 | if(co_intermediate_deps) { | 80 | if(co_intermediate_deps) { |
81 | for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i) | 81 | for(list<string>::const_iterator i=co_intermediate_deps->intermediate_deps.begin();i!=co_intermediate_deps->intermediate_deps.end();++i) |
82 | deps.push_back(*i); | 82 | deps.push_back(*i); |
83 | } | 83 | } |
84 | return; | 84 | return; |
85 | }catch(utility_no_suffix& uns) { } | 85 | }catch(utility_no_suffix& uns) { } |
86 | } | 86 | } |
87 | // compiler targets | 87 | // compiler targets |
88 | for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { | 88 | for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { |
89 | try { | 89 | try { |
90 | string nos = strip_suffix(noro,cc_targets[cct]); | 90 | string nos = strip_suffix(noro,cc_targets[cct]); |
91 | deps.push_back(root_intermediate+nos+".cc"); | 91 | deps.push_back(root_intermediate+nos+".cc"); |
92 | config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); | 92 | config_options *co_cpp_deps = config.lookup_config(noro,config_options::flag_cpp_deps); |
93 | if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { | 93 | if( (!co_cpp_deps) || co_cpp_deps->cpp_deps) { |
94 | ifstream df((root_intermediate+noro+".d").c_str(),ios::in); | 94 | ifstream df((root_intermediate+noro+".d").c_str(),ios::in); |
95 | if(df.good()) { | 95 | if(df.good()) { |
96 | string str; | 96 | string str; |
97 | while(!df.eof()) { | 97 | while(!df.eof()) { |
98 | df >> str; | 98 | df >> str; |
99 | if(str.find_first_of("\\:")==string::npos) | 99 | if(str.find_first_of("\\:")==string::npos) |
100 | deps.push_back(combine_path(config.root_source+nos,str)); | 100 | deps.push_back(combine_path(config.root_source+nos,str)); |
101 | } | 101 | } |
102 | } | 102 | } |
103 | } | 103 | } |
104 | // XXX: extra deps like IntermediateDeps? | 104 | // XXX: extra deps like IntermediateDeps? |
105 | }catch(utility_no_suffix& uns) { } | 105 | }catch(utility_no_suffix& uns) { } |
106 | } | 106 | } |
107 | }catch(utility_no_prefix& unp) { } | 107 | }catch(utility_no_prefix& unp) { } |
108 | } | 108 | } |
109 | 109 | ||
110 | bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { | 110 | bool component_factory::is_uptodate(const string& dst,file_list_t *deps) { |
111 | string dp = normalize_path(dst,strip_trailing_slash); | 111 | string dp = normalize_path(dst,strip_trailing_slash); |
112 | // XXX: or just compare it off, instead of throwing things around. | 112 | // XXX: or just compare it off, instead of throwing things around. |
113 | try { | 113 | try { |
114 | string noro = strip_prefix(dp,root_intermediate); | 114 | string noro = strip_prefix(dp,root_intermediate); |
115 | for(int ppt=0;(ppt+1)<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { | 115 | for(int ppt=0;(ppt+1)<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { |
116 | try { | 116 | try { |
117 | string nos = strip_suffix(noro,pp_targets[ppt]); | 117 | string nos = strip_suffix(noro,pp_targets[ppt]); |
118 | return file_factory::is_uptodate(root_intermediate+nos+".pp_stamp",deps); | 118 | return file_factory::is_uptodate(root_intermediate+nos+".pp_stamp",deps); |
119 | }catch(utility_no_suffix& uns) { } | 119 | }catch(utility_no_suffix& uns) { } |
120 | } | 120 | } |
121 | bool rv = file_factory::is_uptodate(dst,deps); | 121 | bool rv = file_factory::is_uptodate(dst,deps); |
122 | return rv; | 122 | return rv; |
123 | }catch(utility_no_prefix& unp) { } | 123 | }catch(utility_no_prefix& unp) { } |
124 | try { | 124 | try { |
125 | strip_prefix(dp,root_so); | 125 | strip_prefix(dp,root_so); |
126 | return file_factory::is_uptodate(dst,deps); | 126 | return file_factory::is_uptodate(dst,deps); |
127 | }catch(utility_no_prefix& unp) { } | 127 | }catch(utility_no_prefix& unp) { } |
128 | return true; | 128 | return true; |
129 | } | 129 | } |
130 | 130 | ||
131 | void component_factory::build(const string& dst) { | 131 | void component_factory::build(const string& dst) { |
132 | string dp = normalize_path(dst,strip_trailing_slash); | 132 | string dp = normalize_path(dst,strip_trailing_slash); |
133 | // sources | 133 | // sources |
134 | try { | 134 | try { |
135 | string noro = strip_prefix(dp,root_source); | 135 | string noro = strip_prefix(dp,root_source); |
136 | // building the sources is left up to developer | 136 | // building the sources is left up to developer |
137 | return; | 137 | return; |
138 | }catch(utility_no_prefix& unp) { } | 138 | }catch(utility_no_prefix& unp) { } |
139 | // .so files | 139 | // .so files |
140 | try { | 140 | try { |
141 | string noso = strip_suffix(dp,".so"); | 141 | string noso = strip_suffix(dp,".so"); |
142 | string noro = strip_prefix(noso,root_so); | 142 | string noro = strip_prefix(noso,root_so); |
143 | string o = root_intermediate+noro+".o"; | 143 | string o = root_intermediate+noro+".o"; |
144 | if(access(o.c_str(),R_OK)) | 144 | if(access(o.c_str(),R_OK)) |
145 | throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")"); | 145 | throw konforka::exception(CODEPOINT,string("can't access compiled component code (")+o+")"); |
146 | make_path(dir_name(root_so+noro),0755); | 146 | make_path(dir_name(root_so+noro),0755); |
147 | file_lock lock_cc(root_intermediate+noro+".o.lock"); | 147 | file_lock lock_cc(root_intermediate+noro+".o.lock"); |
148 | file_lock lock_so(root_so+noro+".so.lock"); | 148 | file_lock lock_so(root_so+noro+".so.lock"); |
149 | int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | 149 | int stdO = open((root_intermediate+noro+".ld.stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); |
150 | if(stdO<0) | 150 | if(stdO<0) |
151 | throw konforka::exception(CODEPOINT,"failed to open/create linker stdout"); | 151 | throw konforka::exception(CODEPOINT,"failed to open/create linker stdout"); |
152 | int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | 152 | int stdE = open((root_intermediate+noro+".ld.stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); |
153 | if(stdE<0) { | 153 | if(stdE<0) { |
154 | close(stdO); | 154 | close(stdO); |
155 | throw konforka::exception(CODEPOINT,"failed to open/create linker stderr"); | 155 | throw konforka::exception(CODEPOINT,"failed to open/create linker stderr"); |
156 | } | 156 | } |
157 | list<string> args; | 157 | list<string> args; |
158 | config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags); | 158 | config_options *co_ld_flags = config.lookup_config(noro,config_options::flag_ld_flags); |
159 | if(co_ld_flags) { | 159 | if(co_ld_flags) { |
160 | args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end()); | 160 | args.insert(args.end(),co_ld_flags->ld_flags.begin(),co_ld_flags->ld_flags.end()); |
161 | } | 161 | } |
162 | args.push_back("-shared"); | 162 | args.push_back("-shared"); |
163 | args.push_back(o); | 163 | args.push_back(o); |
164 | file_list_t ancestors; | 164 | file_list_t ancestors; |
165 | get_ancestors(noro,ancestors); | 165 | get_ancestors(noro,ancestors); |
166 | for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) { | 166 | for(file_list_t::const_iterator i=ancestors.begin();i!=ancestors.end();++i) { |
167 | string aso=root_so+*i+".so"; | 167 | string aso=root_so+*i+".so"; |
168 | make(aso); | 168 | make(aso); |
169 | args.push_back(aso); | 169 | args.push_back(aso); |
170 | } | 170 | } |
171 | args.push_back("-o"); args.push_back(dp); | 171 | args.push_back("-o"); args.push_back(dp); |
172 | // TODO: "g++" configurable | 172 | // TODO: "g++" configurable |
173 | int rv = execute("g++",args,stdO,stdE); | 173 | int rv = execute("g++",args,stdO,stdE); |
174 | if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) | 174 | if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) |
175 | // TODO:TODO: linker_error | 175 | throw link_error(CODEPOINT,"failed to link component",noro); |
176 | throw compile_error(CODEPOINT,"failed to link component",noro); | ||
177 | return; | 176 | return; |
178 | }catch(utility_no_prefix& unp) { | 177 | }catch(utility_no_prefix& unp) { |
179 | throw konforka::exception(CODEPOINT,"component is outside of component root"); | 178 | throw konforka::exception(CODEPOINT,"component is outside of component root"); |
180 | }catch(utility_no_suffix& uns) { } | 179 | }catch(utility_no_suffix& uns) { } |
181 | try { | 180 | try { |
182 | string noro = strip_prefix(dp,root_intermediate); | 181 | string noro = strip_prefix(dp,root_intermediate); |
183 | // compiler targets | 182 | // compiler targets |
184 | for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { | 183 | for(int cct=0;cct<sizeof(cc_targets)/sizeof(*cc_targets);cct++) { |
185 | try { | 184 | try { |
186 | string nos = strip_suffix(noro,cc_targets[cct]); | 185 | string nos = strip_suffix(noro,cc_targets[cct]); |
187 | string cc = root_intermediate+nos+".cc"; | 186 | string cc = root_intermediate+nos+".cc"; |
188 | string o = root_intermediate+nos+".o"; | 187 | string o = root_intermediate+nos+".o"; |
189 | if(access(cc.c_str(),R_OK)) | 188 | if(access(cc.c_str(),R_OK)) |
190 | throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")"); | 189 | throw konforka::exception(CODEPOINT,string("can't access preprocessed component code (")+cc+")"); |
191 | make_path(dir_name(cc),0755); | 190 | make_path(dir_name(cc),0755); |
192 | string pwd = dir_name(root_source+nos); | 191 | string pwd = dir_name(root_source+nos); |
193 | auto_chdir dir_changer(pwd); | 192 | auto_chdir dir_changer(pwd); |
194 | file_lock lock_source(root_intermediate+nos+".lock"); | 193 | file_lock lock_source(root_intermediate+nos+".lock"); |
195 | file_lock lock_cc(root_intermediate+nos+".o.lock"); | 194 | file_lock lock_cc(root_intermediate+nos+".o.lock"); |
196 | int stdO = open((root_intermediate+nos+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | 195 | int stdO = open((root_intermediate+nos+".stdout").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); |
197 | if(stdO<0) | 196 | if(stdO<0) |
198 | throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout"); | 197 | throw konforka::exception(CODEPOINT,"failed to open/create compiler stdout"); |
199 | int stdE = open((root_intermediate+nos+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); | 198 | int stdE = open((root_intermediate+nos+".stderr").c_str(),O_CREAT|O_TRUNC|O_WRONLY,0664); |
200 | if(stdE<0) { | 199 | if(stdE<0) { |
201 | close(stdO); | 200 | close(stdO); |
202 | throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr"); | 201 | throw konforka::exception(CODEPOINT,"failed to open/create compiler's stderr"); |
203 | } | 202 | } |
204 | list<string> args; | 203 | list<string> args; |
205 | config_options *co_cpp_flags = config.lookup_config(nos,config_options::flag_cpp_flags); | 204 | config_options *co_cpp_flags = config.lookup_config(nos,config_options::flag_cpp_flags); |
206 | if(co_cpp_flags) { | 205 | if(co_cpp_flags) { |
207 | args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end()); | 206 | args.insert(args.end(),co_cpp_flags->cpp_flags.begin(),co_cpp_flags->cpp_flags.end()); |
208 | } | 207 | } |
209 | // TODO: maybe move it to separare config option like CoreCPPFLags? | 208 | // TODO: maybe move it to separare config option like CoreCPPFLags? |
210 | args.push_back("-I"+root_intermediate); | 209 | args.push_back("-I"+root_intermediate); |
211 | args.push_back("-I"+root_source); | 210 | args.push_back("-I"+root_source); |
212 | args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+nos+".d"); | 211 | args.push_back("-MD"); args.push_back("-MF"); args.push_back(root_intermediate+nos+".d"); |
213 | args.push_back("-c"); | 212 | args.push_back("-c"); |
214 | args.push_back(cc); | 213 | args.push_back(cc); |
215 | args.push_back("-o"); args.push_back(o); | 214 | args.push_back("-o"); args.push_back(o); |
216 | // TODO: "g++" configurable | 215 | // TODO: "g++" configurable |
217 | int rv = execute("g++",args,stdO,stdE); | 216 | int rv = execute("g++",args,stdO,stdE); |
218 | if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) | 217 | if(! (WIFEXITED(rv) && !WEXITSTATUS(rv)) ) |
219 | throw compile_error(CODEPOINT,"failed to compile component",nos); | 218 | throw compile_error(CODEPOINT,"failed to compile component",nos); |
220 | return; | 219 | return; |
221 | }catch(utility_no_suffix& uns) { } | 220 | }catch(utility_no_suffix& uns) { } |
222 | } | 221 | } |
223 | // preprocessor targets | 222 | // preprocessor targets |
224 | for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { | 223 | for(int ppt=0;ppt<sizeof(pp_targets)/sizeof(*pp_targets);ppt++) { |
225 | try { | 224 | try { |
226 | string nos = strip_suffix(noro,pp_targets[ppt]); | 225 | string nos = strip_suffix(noro,pp_targets[ppt]); |
227 | string src = root_source+nos; | 226 | string src = root_source+nos; |
228 | if(access(src.c_str(),R_OK)) | 227 | if(access(src.c_str(),R_OK)) |
229 | throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); | 228 | throw konforka::exception(CODEPOINT,string("can't access component source (")+src+")"); |
230 | make_path(dir_name(root_intermediate+nos),0755); | 229 | make_path(dir_name(root_intermediate+nos),0755); |
231 | file_lock lock(root_intermediate+nos+".lock"); | 230 | file_lock lock(root_intermediate+nos+".lock"); |
232 | sitecing_parser parser(*this); | 231 | sitecing_parser parser(*this); |
233 | config_options *co_skeleton = config.lookup_config(nos,config_options::flag_skeleton); | 232 | config_options *co_skeleton = config.lookup_config(nos,config_options::flag_skeleton); |
234 | if(co_skeleton) | 233 | if(co_skeleton) |
235 | parser.skeleton = co_skeleton->skeleton; | 234 | parser.skeleton = co_skeleton->skeleton; |
236 | static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | 235 | static const char *id_chars = "abcdefghijklmnopqrstuvwxyz0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ"; |
237 | parser.class_name = normalize_path(nos,strip_leading_slash|strip_trailing_slash); | 236 | parser.class_name = normalize_path(nos,strip_leading_slash|strip_trailing_slash); |
238 | 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)) { | 237 | 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)) { |
239 | string::size_type lc = parser.class_name.find_first_of(id_chars,illc); | 238 | string::size_type lc = parser.class_name.find_first_of(id_chars,illc); |
240 | int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; | 239 | int n = ((lc==string::npos)?parser.class_name.length():lc)-illc; |
241 | parser.class_name.replace(illc,n,n,'_'); | 240 | parser.class_name.replace(illc,n,n,'_'); |
242 | } | 241 | } |
243 | parser.class_name = "_SCC_"+parser.class_name; | 242 | parser.class_name = "_SCC_"+parser.class_name; |
244 | parser.output_basename = root_intermediate+nos; | 243 | parser.output_basename = root_intermediate+nos; |
245 | parser.component_basename = nos; | 244 | parser.component_basename = nos; |
246 | try { | 245 | try { |
247 | parser.preprocess(src); | 246 | parser.preprocess(src); |
248 | string sf = root_intermediate+nos+".pp_stamp"; | 247 | string sf = root_intermediate+nos+".pp_stamp"; |
249 | ofstream sfs(sf.c_str(),ios::trunc|ios::out); // touch .pp_stamp | 248 | ofstream sfs(sf.c_str(),ios::trunc|ios::out); // touch .pp_stamp |
250 | }catch(preprocessor_error& pe) { | 249 | }catch(preprocessor_error& pe) { |
251 | pe.component_name = nos; | 250 | pe.component_name = nos; |
252 | pe.see(CODEPOINT); | 251 | pe.see(CODEPOINT); |
253 | throw; | 252 | throw; |
254 | } | 253 | } |
255 | return; | 254 | return; |
256 | }catch(utility_no_suffix& uns) { } | 255 | }catch(utility_no_suffix& uns) { } |
257 | } | 256 | } |
258 | }catch(utility_no_prefix& unp) { } | 257 | }catch(utility_no_prefix& unp) { } |
259 | cerr << "ignoring build request for " << dp << endl; | 258 | cerr << "ignoring build request for " << dp << endl; |
260 | } | 259 | } |
261 | 260 | ||
262 | int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) { | 261 | int component_factory::execute(const string& cmd, const list<string>& args,int stdo,int stde) { |
263 | // XXX: is it right that we do stdio/stderr tricks outside of the function? | 262 | // XXX: is it right that we do stdio/stderr tricks outside of the function? |
264 | cerr << "executing: " << cmd; | 263 | cerr << "executing: " << cmd; |
265 | vector<const char*> argv(args.size()+2); | 264 | vector<const char*> argv(args.size()+2); |
266 | argv[0]=cmd.c_str(); | 265 | argv[0]=cmd.c_str(); |
267 | int an = 1; | 266 | int an = 1; |
268 | for(list<string>::const_iterator i=args.begin();i!=args.end();i++) { | 267 | for(list<string>::const_iterator i=args.begin();i!=args.end();i++) { |
269 | cerr << " " << *i ; | 268 | cerr << " " << *i ; |
270 | argv[an++] = i->c_str(); | 269 | argv[an++] = i->c_str(); |
271 | } | 270 | } |
272 | cerr << endl; | 271 | cerr << endl; |
273 | argv[an++]=NULL; | 272 | argv[an++]=NULL; |
274 | pid_t pid = vfork(); | 273 | pid_t pid = vfork(); |
275 | if(pid==-1) { | 274 | if(pid==-1) { |
276 | close(stdo); close(stde); | 275 | close(stdo); close(stde); |
277 | throw konforka::exception(CODEPOINT,"failed to vfork()"); | 276 | throw konforka::exception(CODEPOINT,"failed to vfork()"); |
278 | } | 277 | } |
279 | if(!pid) { | 278 | if(!pid) { |
280 | // child | 279 | // child |
281 | if(dup2(stdo,1)!=1) | 280 | if(dup2(stdo,1)!=1) |
282 | _exit(-1); | 281 | _exit(-1); |
283 | if(dup2(stde,2)!=2) | 282 | if(dup2(stde,2)!=2) |
284 | _exit(-1); | 283 | _exit(-1); |
285 | close(0); | 284 | close(0); |
286 | execvp(cmd.c_str(),(char**)&argv.front()); | 285 | execvp(cmd.c_str(),(char**)&argv.front()); |
287 | _exit(-1); | 286 | _exit(-1); |
288 | } | 287 | } |
289 | // parent | 288 | // parent |
290 | close(stdo); close(stde); | 289 | close(stdo); close(stde); |
291 | int rv; | 290 | int rv; |
292 | if(waitpid(pid,&rv,0)<0) | 291 | if(waitpid(pid,&rv,0)<0) |
293 | throw konforka::exception(CODEPOINT,"failed to waitpid()"); | 292 | throw konforka::exception(CODEPOINT,"failed to waitpid()"); |
294 | return rv; | 293 | return rv; |
295 | } | 294 | } |
296 | 295 | ||
297 | string component_factory::get_classname(const string& component) { | 296 | string component_factory::get_classname(const string& component) { |
298 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname"; | 297 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".classname"; |
299 | make(cn); | 298 | make(cn); |
300 | ifstream ifs(cn.c_str()); | 299 | ifstream ifs(cn.c_str()); |
301 | if(!ifs.good()) | 300 | if(!ifs.good()) |
302 | throw konforka::exception(CODEPOINT,"failed to access component .classname"); | 301 | throw konforka::exception(CODEPOINT,"failed to access component .classname"); |
303 | ifs >> cn; | 302 | ifs >> cn; |
304 | return cn; | 303 | return cn; |
305 | } | 304 | } |
306 | 305 | ||
307 | void component_factory::get_ancestors(const string& component,file_list_t& rv) { | 306 | void component_factory::get_ancestors(const string& component,file_list_t& rv) { |
308 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors"; | 307 | string cn = root_intermediate+normalize_path(component,strip_trailing_slash|strip_leading_slash)+".ancestors"; |
309 | make(cn); | 308 | make(cn); |
310 | ifstream ifs(cn.c_str()); | 309 | ifstream ifs(cn.c_str()); |
311 | if(!ifs.good()) | 310 | if(!ifs.good()) |
312 | throw konforka::exception(CODEPOINT,string("failed to access component '")+component+"' .ancestors"); | 311 | throw konforka::exception(CODEPOINT,string("failed to access component '")+component+"' .ancestors"); |
313 | rv.clear(); | 312 | rv.clear(); |
314 | while(!ifs.eof()) { | 313 | while(!ifs.eof()) { |
315 | string a; | 314 | string a; |
316 | ifs >> a; | 315 | ifs >> a; |
317 | if(!a.empty()) | 316 | if(!a.empty()) |
318 | rv.push_back(a); | 317 | rv.push_back(a); |
319 | } | 318 | } |
320 | } | 319 | } |
321 | 320 | ||
322 | } | 321 | } |