@@ -132,37 +132,127 @@ pub fn build(b: *std.Build) void {
132132 break :blk config ;
133133 };
134134
135+ const config_header = b .addConfigHeader (.{
136+ .style = .blank ,
137+ .include_path = "ffconf.h" ,
138+ }, .{
139+ .FFCONF_DEF = 5380 ,
140+ });
141+
142+ switch (config .volumes ) {
143+ .count = > | count | {
144+ config_header .addValues (.{
145+ .FF_VOLUMES = count ,
146+ .FF_STR_VOLUME_ID = 0 ,
147+ });
148+ },
149+ .named = > | strings | {
150+ var list = std .ArrayList (u8 ).init (b .allocator );
151+ for (strings ) | name | {
152+ if (list .items .len > 0 ) {
153+ list .appendSlice (", " ) catch @panic ("out of memory" );
154+ }
155+ list .writer ().print ("\" {}\" " , .{
156+ std .fmt .fmtSliceHexUpper (name ),
157+ }) catch @panic ("out of memory" );
158+ }
159+ config_header .addValues (.{
160+ .FF_VOLUMES = @as (i64 , @intCast (strings .len )),
161+ .FF_STR_VOLUME_ID = 1 ,
162+ .FF_VOLUME_STRS = list .items ,
163+ });
164+ },
165+ }
166+
167+ switch (config .sector_size ) {
168+ .static = > | size | {
169+ config_header .addValues (.{
170+ .FF_MIN_SS = size ,
171+ .FF_MAX_SS = size ,
172+ });
173+ },
174+ .dynamic = > | range | {
175+ config_header .addValues (.{
176+ .FF_MIN_SS = range .minimum ,
177+ .FF_MAX_SS = range .maximum ,
178+ });
179+ },
180+ }
181+
182+ inline for (comptime std .meta .fields (Config )) | fld | {
183+ add_config_field (config_header , config , fld .name );
184+ }
185+
186+ switch (config .rtc ) {
187+ .dynamic = > {
188+ config_header .addValue ("FF_FS_NORTC" , bool , false );
189+ },
190+ .static = > | date | {
191+ config_header .addValues (.{
192+ .FF_FS_NORTC = 1 ,
193+ .FF_NORTC_MON = date .month .numeric (),
194+ .FF_NORTC_MDAY = date .day ,
195+ .FF_NORTC_YEAR = date .year ,
196+ });
197+ },
198+ }
199+
135200 // module:
201+ const upstream = b .dependency ("fatfs" , .{});
136202
137203 const mod_options = b .addOptions ();
138204 mod_options .addOption (bool , "has_rtc" , (config .rtc != .static ));
139205
140- const zfat_lib = b .addStaticLibrary (.{
141- .name = "zfat" ,
206+ // create copy of the upstream without ffconf.h
207+ const upstream_copy = b .addWriteFiles ();
208+ _ = upstream_copy .addCopyFile (upstream .path ("source/ff.c" ), "ff.c" );
209+ _ = upstream_copy .addCopyFile (upstream .path ("source/ff.h" ), "ff.h" );
210+ _ = upstream_copy .addCopyFile (upstream .path ("source/diskio.h" ), "diskio.h" );
211+ _ = upstream_copy .addCopyFile (upstream .path ("source/ffunicode.c" ), "ffunicode.c" );
212+ _ = upstream_copy .addCopyFile (upstream .path ("source/ffsystem.c" ), "ffsystem.c" );
213+ const upstream_copy_dir = upstream_copy .getDirectory ();
214+
215+ const zfat_lib_mod = b .createModule (.{
142216 .target = target ,
143217 .optimize = optimize ,
218+ .link_libc = link_libc ,
144219 });
145- zfat_lib .installHeader (b .path ("src/fatfs/ff.h" ), "ff.h" );
146- zfat_lib .installHeader (b .path ("src/fatfs/diskio.h" ), "diskio.h" );
147- initialize_mod (b , zfat_lib .root_module , config , link_libc );
220+ zfat_lib_mod .addCSourceFiles (.{
221+ .root = upstream_copy_dir ,
222+
223+ .files = &.{
224+ "ff.c" ,
225+ "ffunicode.c" ,
226+ "ffsystem.c" ,
227+ },
228+ .flags = &.{"-std=c99" },
229+ });
230+ zfat_lib_mod .addConfigHeader (config_header );
231+
232+ const zfat = b .addLibrary (.{
233+ .linkage = .static ,
234+ .name = "zfat" ,
235+ .root_module = zfat_lib_mod ,
236+ });
237+ zfat .installHeader (upstream_copy_dir .path (b , "ff.h" ), "ff.h" );
238+ zfat .installHeader (upstream_copy_dir .path (b , "diskio.h" ), "diskio.h" );
239+ zfat .installConfigHeader (config_header );
148240
149241 const zfat_mod = b .addModule ("zfat" , .{
150242 .root_source_file = b .path ("src/fatfs.zig" ),
151243 .target = target ,
152244 .optimize = optimize ,
153245 });
154- initialize_mod ( b , zfat_mod , config , link_libc );
246+ zfat_mod . linkLibrary ( zfat );
155247 zfat_mod .addOptions ("config" , mod_options );
156248
157249 // usage demo:
158-
159250 const exe = b .addExecutable (.{
160251 .name = "zfat-demo" ,
161252 .root_source_file = b .path ("demo/main.zig" ),
162253 .target = target ,
163254 .optimize = optimize ,
164255 });
165-
166256 exe .root_module .addImport ("zfat" , zfat_mod );
167257
168258 const demo_exe = b .addInstallArtifact (exe , .{});
@@ -178,101 +268,26 @@ pub fn build(b: *std.Build) void {
178268 run_step .dependOn (& run_cmd .step );
179269}
180270
181- fn initialize_mod (b : * std.Build , mod : * std.Build.Module , config : Config , link_libc : bool ) void {
182- mod .addIncludePath (b .path ("src/fatfs" ));
183- mod .addCSourceFiles (.{
184- .root = b .path ("src/fatfs" ),
185- .files = &.{
186- "ff.c" ,
187- "ffunicode.c" ,
188- "ffsystem.c" ,
189- },
190- .flags = &.{"-std=c99" },
191- });
192- apply_public_config (b , mod , config );
193- apply_private_config (b , mod , config );
194- mod .link_libc = link_libc ;
195- }
196-
197- fn apply_public_config (b : * std.Build , module : * std.Build.Module , config : Config ) void {
198- switch (config .volumes ) {
199- .count = > | count | {
200- module .addCMacro ("FF_VOLUMES" , b .fmt ("{d}" , .{count }));
201- module .addCMacro ("FF_STR_VOLUME_ID" , "0" );
202- },
203- .named = > | strings | {
204- var list = std .ArrayList (u8 ).init (b .allocator );
205- for (strings ) | name | {
206- if (list .items .len > 0 ) {
207- list .appendSlice (", " ) catch @panic ("out of memory" );
208- }
209- list .writer ().print ("\" {}\" " , .{
210- std .fmt .fmtSliceHexUpper (name ),
211- }) catch @panic ("out of memory" );
212- }
213-
214- module .addCMacro ("FF_VOLUMES" , b .fmt ("{d}" , .{strings .len }));
215- module .addCMacro ("FF_STR_VOLUME_ID" , "1" );
216- module .addCMacro ("FF_VOLUME_STRS" , list .items );
217- },
218- }
219-
220- switch (config .sector_size ) {
221- .static = > | size | {
222- const str = b .fmt ("{d}" , .{@intFromEnum (size )});
223- module .addCMacro ("FF_MIN_SS" , str );
224- module .addCMacro ("FF_MAX_SS" , str );
225- },
226- .dynamic = > | range | {
227- module .addCMacro ("FF_MIN_SS" , b .fmt ("{d}" , .{@intFromEnum (range .minimum )}));
228- module .addCMacro ("FF_MAX_SS" , b .fmt ("{d}" , .{@intFromEnum (range .maximum )}));
229- },
230- }
231- }
232-
233- fn apply_private_config (b : * std.Build , module : * std.Build.Module , config : Config ) void {
234- inline for (comptime std .meta .fields (Config )) | fld | {
235- add_config_field (b , module , config , fld .name );
236- }
237-
238- switch (config .rtc ) {
239- .dynamic = > module .addCMacro ("FF_FS_NORTC" , "0" ),
240- .static = > | date | {
241- module .addCMacro ("FF_FS_NORTC" , "1" );
242- module .addCMacro ("FF_NORTC_MON" , b .fmt ("{d}" , .{date .month .numeric ()}));
243- module .addCMacro ("FF_NORTC_MDAY" , b .fmt ("{d}" , .{date .day }));
244- module .addCMacro ("FF_NORTC_YEAR" , b .fmt ("{d}" , .{date .year }));
245- },
246- }
247- }
248-
249- fn add_config_field (b : * std.Build , module : * std.Build.Module , config : Config , comptime field_name : []const u8 ) void {
271+ fn add_config_field (config_header : * std.Build.Step.ConfigHeader , config : Config , comptime field_name : []const u8 ) void {
250272 const value = @field (config , field_name );
251273 const Type = @TypeOf (value );
252274 const type_info = @typeInfo (Type );
253275
254- const str_value : [] const u8 = if (Type == VolumeKind or Type == SectorSize or Type == RtcConfig )
276+ if (Type == VolumeKind or Type == SectorSize or Type == RtcConfig )
255277 return // we don't emit these automatically
256- else if (type_info == .@"enum" )
257- b .fmt ("{d}" , .{@intFromEnum (value )})
258- else if (type_info == .int )
259- b .fmt ("{d}" , .{value })
260- else if (Type == bool )
261- b .fmt ("{d}" , .{@intFromBool (value )})
262- else if (Type == []const u8 )
263- value
264- else {
265- @compileError ("Unsupported config type: " ++ @typeName (Type ));
266- };
267-
268- const macro_name = @field (macro_names , field_name );
269- module .addCMacro (macro_name , str_value );
278+ else if (type_info == .@"enum" ) {
279+ const macro_name = @field (macro_names , field_name );
280+ config_header .addValue (macro_name , i64 , @intFromEnum (value ));
281+ } else {
282+ const macro_name = @field (macro_names , field_name );
283+ config_header .addValue (macro_name , Type , value );
284+ }
270285}
271286
272287fn add_config_option (b : * std.Build , config : * Config , comptime field : @TypeOf (.tag ), desc : []const u8 ) void {
273288 const T = std .meta .FieldType (Config , field );
274-
275- @field ( config , @tagName ( field )) = b . option ( T , @tagName ( field ), desc ) orelse @field (config , @tagName (field ));
289+ if ( b . option ( T , @tagName ( field ), desc )) | value |
290+ @ field (config , @tagName (field )) = value ;
276291}
277292
278293pub const Config = struct {
0 commit comments