99#include "cpbuild.h"
1010#include "utils.h"
1111const char cpb_default_option_list []= "cc\0c++" ;
12- const char cpb_accepted_extensions []= "c\0c++\0cpp\0cxx\0" ;
12+ const char cpb_accepted_extensions []= "c\0c++\0cc\ 0cpp\0cxx\0" ;
1313char cpb_cmd_option_list []= "-c\0-o\0-MM" ;
14+ struct option_and_files
15+ {
16+ cpbuild_options_t * opt ;
17+ struct program_args files ;
18+ struct program_args folders ;
19+ };
1420int timespec_compare (const struct timespec * a ,const struct timespec * b )
1521{
1622 long c [2 ]= {a -> tv_sec - b -> tv_sec ,a -> tv_nsec - b -> tv_nsec };
1723 int64_t result = c [c [0 ]== 0 ];
1824 return (result >=0 )+ (result > 0 )- 1 ;
1925}
20- void build_callback (const char * file ,void * arg ,int isdir )
26+ int build_callback (const char * file ,void * arg ,int info )
2127{
22- struct cpbuild_options * opt = arg ;
28+ struct option_and_files * oaf = arg ;
29+ struct cpbuild_options * opt = oaf -> opt ;
30+ int r = 0 ;
31+ int isdir = info & 1 ;
2332 char * periodptr = strrchr (file ,'.' );
2433 size_t len = strlen (file );
34+ info >>=1 ;
2535 if (isdir )
2636 {
27- struct stat objdat ,dirdat ;
28- int ores = stat (opt -> objdir ,& objdat );
29- int dres = stat (file ,& dirdat );
30- int same = ores == 0 && dres == 0 && objdat .st_dev == dirdat .st_dev && objdat .st_ino == dirdat .st_ino ;
31- if (!same )
37+ if (info == 3 )
3238 {
33- char * target = changeext_add_prefix (file + opt -> pathshift ,opt -> objdir ,"" );
34- mkdir (target ,0755 );
35- free (target );
39+ char * directory = changeext_add_prefix (file + opt -> pathshift ,opt -> objdir ,"" );
40+ if (directory == NULL )
41+ {
42+ perror ("directory to be created is NULL, malloc failed" );
43+ }
44+ else
45+ {
46+ r = append_program_arg (& oaf -> folders ,directory )== 0 ;
47+ }
3648 }
3749 }
3850 else if (strcontains (cpb_accepted_extensions ,periodptr + 1 ))
@@ -49,11 +61,12 @@ void build_callback(const char*file,void*arg,int isdir)
4961 else
5062 {
5163 memcpy (filename ,file ,len + 1 );
64+ append_program_arg (& oaf -> files ,filename );
5265 append_program_arg (& opt -> linkerargs ,objname );
53- buildfile (filename ,objname ,opt );
54- free (filename );
66+ r = 1 ;
5567 }
5668 }
69+ return r ;
5770}
5871int make_command_line (struct program_options * restrict d ,const struct program_options * restrict s ,char * compiler )
5972{
@@ -81,6 +94,9 @@ int cpbuild(char**targets,unsigned len,struct cpbuild_options*opt)
8194 if (!cfail && !cppfail )
8295 {
8396 size_t targetlen = len ;
97+ size_t currLinkerLen ;
98+ struct option_and_files oaf ;
99+ oaf .opt = opt ;
84100 init_program_args (& opt -> linkerargs ,opt -> linkerops .len + 3 );
85101 opt -> linkerargs .options [0 ]= opt -> compiler ;
86102 opt -> linkerargs .options [1 ]= cpb_cmd_option_list + 3 ;
@@ -97,10 +113,35 @@ int cpbuild(char**targets,unsigned len,struct cpbuild_options*opt)
97113 perror ("stat failed" );
98114 else if (S_ISDIR (fdat .st_mode ))
99115 {
100- target = changeext_add_prefix (* it ,opt -> objdir ,"" );
101- mkdir (target ,0755 );
102- free (target );
103- iterate_directory (* it ,& build_callback ,opt );
116+ currLinkerLen = opt -> linkerargs .len ;
117+ if (init_program_args (& oaf .files ,16 )== 0 && init_program_args (& oaf .folders ,4 )== 0 )
118+ {
119+ iterate_directory (* it ,& build_callback ,& oaf );
120+ for (size_t i = oaf .folders .len ;i > 0 ;-- i )
121+ {
122+ mkdir (oaf .folders .options [i - 1 ],0755 );
123+ free (oaf .folders .options [i - 1 ]);
124+ }
125+ free (oaf .folders .options );
126+ for (size_t i = 0 ;i < oaf .files .len ;++ i )
127+ {
128+ buildfile (oaf .files .options [i ],opt -> linkerargs .options [currLinkerLen + i ],opt );
129+ free (oaf .files .options [i ]);
130+ }
131+ free (oaf .files .options );
132+ }
133+ else
134+ {
135+ if (oaf .files .options != NULL )
136+ {
137+ free (oaf .files .options );
138+ }
139+ if (oaf .folders .options != NULL )
140+ {
141+ free (oaf .folders .options );
142+ }
143+ perror ("cpbuild: initializing array for files failed" );
144+ }
104145 }
105146 else
106147 {
0 commit comments