Compare commits
	
		
			2 commits
		
	
	
		
			13e6bd5689
			...
			c292c51c44
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c292c51c44 | |||
| 25a3169b85 | 
					 7 changed files with 92 additions and 19 deletions
				
			
		
							
								
								
									
										31
									
								
								.github/workflows/zig-build.yaml
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								.github/workflows/zig-build.yaml
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | ||||||
|  | name: Generic zig build | ||||||
|  | on: | ||||||
|  |   workflow_dispatch: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - '*' | ||||||
|  |       - '!zig-develop*' | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v4 | ||||||
|  |       - uses: elerch/setup-zig@v3 | ||||||
|  |         with: | ||||||
|  |           version: 0.12.0 | ||||||
|  |       - uses: Hanaasagi/zig-action-cache@v1.1.5 | ||||||
|  |       - name: Install fontconfig | ||||||
|  |         run: apt update && apt install libfontconfig1 && ln -s /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 /usr/local/lib/libfontconfig.so | ||||||
|  |       - name: Build project | ||||||
|  |         run: zig build --summary all | ||||||
|  |       - name: Run tests | ||||||
|  |         run: zig build test --summary all | ||||||
|  |       - name: Notify | ||||||
|  |         uses: elerch/action-notify-ntfy@v2.github | ||||||
|  |         if: env.GITEA_ACTIONS == 'true' | ||||||
|  |         with: | ||||||
|  |           host: ${{ secrets.NTFY_HOST }} | ||||||
|  |           topic: ${{ secrets.NTFY_TOPIC }} | ||||||
|  |           status: ${{ job.status }} | ||||||
|  |           user: ${{ secrets.NTFY_USER }} | ||||||
|  |           password: ${{ secrets.NTFY_PASSWORD }} | ||||||
|  | @ -6,7 +6,7 @@ RUN apt-get update \ | ||||||
|          ca-certificates \ |          ca-certificates \ | ||||||
|          curl \ |          curl \ | ||||||
|          xz-utils \ |          xz-utils \ | ||||||
|     && curl https://ziglang.org/download/0.11.0/zig-linux-x86_64-0.11.0.tar.xz | tar -C /usr/local/ -xJ \ |     && curl https://ziglang.org/download/0.12.0/zig-linux-x86_64-0.12.0.tar.xz | tar -C /usr/local/ -xJ \ | ||||||
|     && apt-get -y remove curl xz-utils  \ |     && apt-get -y remove curl xz-utils  \ | ||||||
|     && ln -s /usr/local/zig*/zig /usr/local/bin \ |     && ln -s /usr/local/zig*/zig /usr/local/bin \ | ||||||
|     && rm -rf /var/lib/apt/lists/* |     && rm -rf /var/lib/apt/lists/* | ||||||
|  |  | ||||||
|  | @ -19,8 +19,9 @@ Building | ||||||
| 
 | 
 | ||||||
| This is not fully `zig build` friendly, since it links to system libraries. | This is not fully `zig build` friendly, since it links to system libraries. | ||||||
| Specifically, you need to have [fontconfig](https://www.freedesktop.org/wiki/Software/fontconfig/) | Specifically, you need to have [fontconfig](https://www.freedesktop.org/wiki/Software/fontconfig/) | ||||||
| and dependencies installed. I initially went down that rabbit hole, but it's | and dependencies installed. The include files are pulled from fontconfig 2.14.1, | ||||||
| kind of a mess that I don't need for what is really a personal project. | which is the version in debian bullseye, but he system library still needs to | ||||||
|  | linked. | ||||||
| 
 | 
 | ||||||
| To help with the build, a Dockerfile exists in this repository that can be used | To help with the build, a Dockerfile exists in this repository that can be used | ||||||
| to create a docker image with the appropriate zig version and system libraries. | to create a docker image with the appropriate zig version and system libraries. | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								build.zig
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								build.zig
									
										
									
									
									
								
							|  | @ -24,7 +24,9 @@ pub fn build(b: *std.Build) void { | ||||||
|         .optimize = optimize, |         .optimize = optimize, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     configure(exe); |     const fontconfig = b.dependency("fontconfig", .{}); | ||||||
|  | 
 | ||||||
|  |     configure(b, fontconfig, exe); | ||||||
| 
 | 
 | ||||||
|     // This declares intent for the executable to be installed into the |     // This declares intent for the executable to be installed into the | ||||||
|     // standard location when the user invokes the "install" step (the default |     // standard location when the user invokes the "install" step (the default | ||||||
|  | @ -62,7 +64,7 @@ pub fn build(b: *std.Build) void { | ||||||
|         .optimize = optimize, |         .optimize = optimize, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     configure(unit_tests); |     configure(b, fontconfig, unit_tests); | ||||||
| 
 | 
 | ||||||
|     const run_unit_tests = b.addRunArtifact(unit_tests); |     const run_unit_tests = b.addRunArtifact(unit_tests); | ||||||
| 
 | 
 | ||||||
|  | @ -73,14 +75,17 @@ pub fn build(b: *std.Build) void { | ||||||
|     test_step.dependOn(&run_unit_tests.step); |     test_step.dependOn(&run_unit_tests.step); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn configure(object: anytype) void { | fn configure(b: *std.Build, fontconfig: *std.Build.Dependency, object: anytype) void { | ||||||
|     // object.linkage = .static; |     // object.linkage = .static; | ||||||
|     object.linkLibC(); |     object.linkLibC(); | ||||||
| 
 | 
 | ||||||
|     // Fontconfig must be installed. Docker can also be used (see Dockerfile) |     // Fontconfig must be installed. Docker can also be used (see Dockerfile) | ||||||
|     object.addSystemIncludePath("/usr/include"); |     object.addSystemIncludePath(fontconfig.path("")); | ||||||
|     object.linkSystemLibrary("fontconfig"); |     object.linkSystemLibrary("fontconfig"); | ||||||
|     // object.linkSystemLibrary("expat"); // fontconfig dependency - needed for static builds |     // object.linkSystemLibrary("expat"); // fontconfig dependency - needed for static builds | ||||||
|     object.addLibraryPath("/usr/lib"); |     object.addLibraryPath(.{ .cwd_relative = "/usr/lib" }); | ||||||
|     object.addCSourceFile("src/fontconfig.c", &[_][]const u8{"-std=c99"}); |     object.addCSourceFile(.{ | ||||||
|  |         .file = b.path("src/fontconfig.c"), | ||||||
|  |         .flags = &[_][]const u8{"-std=c99"}, | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								build.zig.zon
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								build.zig.zon
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | .{ | ||||||
|  |     .name = "fontfinder", | ||||||
|  |     // This is a [Semantic Version](https://semver.org/). | ||||||
|  |     // In a future version of Zig it will be used for package deduplication. | ||||||
|  |     .version = "0.0.0", | ||||||
|  | 
 | ||||||
|  |     // This field is optional. | ||||||
|  |     // This is currently advisory only; Zig does not yet do anything | ||||||
|  |     // with this value. | ||||||
|  |     //.minimum_zig_version = "0.11.0", | ||||||
|  | 
 | ||||||
|  |     // This field is optional. | ||||||
|  |     // Each dependency must either provide a `url` and `hash`, or a `path`. | ||||||
|  |     // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. | ||||||
|  |     // Once all dependencies are fetched, `zig build` no longer requires | ||||||
|  |     // internet connectivity. | ||||||
|  |     .dependencies = .{ | ||||||
|  |         .fontconfig = .{ | ||||||
|  |             .url = "https://gitlab.freedesktop.org/fontconfig/fontconfig/-/archive/2.14.1/fontconfig-2.14.1.tar.gz", | ||||||
|  |             .hash = "1220a54d89babad491b562dad3f2c73414c95ea2f46a4e7206f1e36be4632654458e", | ||||||
|  |         }, | ||||||
|  |     }, | ||||||
|  |     .paths = .{ | ||||||
|  |         // This makes *all* files, recursively, included in this package. It is generally | ||||||
|  |         // better to explicitly list the files and directories instead, to insure that | ||||||
|  |         // fetching from tarballs, file system paths, and version control all result | ||||||
|  |         // in the same contents hash. | ||||||
|  |         "", | ||||||
|  |         // For example... | ||||||
|  |         //"build.zig", | ||||||
|  |         //"build.zig.zon", | ||||||
|  |         //"src", | ||||||
|  |         //"LICENSE", | ||||||
|  |         //"README.md", | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | @ -35,7 +35,7 @@ pub const FontList = struct { | ||||||
| 
 | 
 | ||||||
|     const Self = @This(); |     const Self = @This(); | ||||||
|     pub fn initCapacity(allocator: std.mem.Allocator, num: usize, pattern: *c.FcPattern, fontset: *c.FcFontSet) std.mem.Allocator.Error!Self { |     pub fn initCapacity(allocator: std.mem.Allocator, num: usize, pattern: *c.FcPattern, fontset: *c.FcFontSet) std.mem.Allocator.Error!Self { | ||||||
|         var al = try std.ArrayList(Font).initCapacity(allocator, num); |         const al = try std.ArrayList(Font).initCapacity(allocator, num); | ||||||
|         return Self{ |         return Self{ | ||||||
|             .allocator = allocator, |             .allocator = allocator, | ||||||
|             .list = al, |             .list = al, | ||||||
|  | @ -192,7 +192,7 @@ pub const FontQuery = struct { | ||||||
|         var rc = std.ArrayList(RangeFont).init(self.allocator); |         var rc = std.ArrayList(RangeFont).init(self.allocator); | ||||||
|         defer rc.deinit(); |         defer rc.deinit(); | ||||||
| 
 | 
 | ||||||
|         var previously_supported = blk: { |         const previously_supported = blk: { | ||||||
|             if (!exclude_previous) break :blk null; |             if (!exclude_previous) break :blk null; | ||||||
|             var al = try std.ArrayList(bool).initCapacity(self.allocator, ending_codepoint - starting_codepoint); |             var al = try std.ArrayList(bool).initCapacity(self.allocator, ending_codepoint - starting_codepoint); | ||||||
|             defer al.deinit(); |             defer al.deinit(); | ||||||
|  | @ -267,7 +267,7 @@ test "Get fonts" { | ||||||
|     var fl = try fq.fontList(":regular:normal:spacing=100:slant=0"); |     var fl = try fq.fontList(":regular:normal:spacing=100:slant=0"); | ||||||
|     defer fl.deinit(); |     defer fl.deinit(); | ||||||
|     try std.testing.expect(fl.list.items.len > 0); |     try std.testing.expect(fl.list.items.len > 0); | ||||||
|     var matched = blk: { |     const matched = blk: { | ||||||
|         for (fl.list.items) |item| { |         for (fl.list.items) |item| { | ||||||
|             log.debug("full_name: '{s}'", .{item.full_name}); |             log.debug("full_name: '{s}'", .{item.full_name}); | ||||||
|             if (std.mem.eql(u8, "DejaVu Sans Mono", item.full_name)) |             if (std.mem.eql(u8, "DejaVu Sans Mono", item.full_name)) | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								src/main.zig
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/main.zig
									
										
									
									
									
								
							|  | @ -52,7 +52,7 @@ pub fn main() !u8 { | ||||||
|     if (options.list_fonts) { |     if (options.list_fonts) { | ||||||
|         var fq = fontconfig.FontQuery.init(allocator); |         var fq = fontconfig.FontQuery.init(allocator); | ||||||
|         defer fq.deinit(); |         defer fq.deinit(); | ||||||
|         var fl = try fq.fontList(options.pattern); |         const fl = try fq.fontList(options.pattern); | ||||||
|         var longest_family_name = @as(usize, 0); |         var longest_family_name = @as(usize, 0); | ||||||
|         var longest_style_name = @as(usize, 0); |         var longest_style_name = @as(usize, 0); | ||||||
|         for (fl.list.items) |f| { |         for (fl.list.items) |f| { | ||||||
|  | @ -81,7 +81,7 @@ pub fn main() !u8 { | ||||||
|         var si = std.mem.splitScalar(u8, fo, ','); |         var si = std.mem.splitScalar(u8, fo, ','); | ||||||
|         var fq = fontconfig.FontQuery.init(allocator); |         var fq = fontconfig.FontQuery.init(allocator); | ||||||
|         defer fq.deinit(); |         defer fq.deinit(); | ||||||
|         var fl = try fq.fontList(options.pattern); |         const fl = try fq.fontList(options.pattern); | ||||||
|         // This messes with data after, and we don't need to deinit anyway |         // This messes with data after, and we don't need to deinit anyway | ||||||
|         // defer fl.deinit(); |         // defer fl.deinit(); | ||||||
|         var al = try std.ArrayList(fontconfig.Font).initCapacity(allocator, std.mem.count(u8, fo, ",") + 2); |         var al = try std.ArrayList(fontconfig.Font).initCapacity(allocator, std.mem.count(u8, fo, ",") + 2); | ||||||
|  | @ -184,7 +184,7 @@ fn outputRange( | ||||||
| ) !void { | ) !void { | ||||||
|     var fq = fontconfig.FontQuery.init(allocator); |     var fq = fontconfig.FontQuery.init(allocator); | ||||||
|     defer fq.deinit(); |     defer fq.deinit(); | ||||||
|     var range_fonts = try fq.fontsForRange(starting_codepoint, ending_codepoint, fonts, exclude_previous); // do we want hard limits around this? |     const range_fonts = try fq.fontsForRange(starting_codepoint, ending_codepoint, fonts, exclude_previous); // do we want hard limits around this? | ||||||
|     defer allocator.free(range_fonts); |     defer allocator.free(range_fonts); | ||||||
| 
 | 
 | ||||||
|     std.log.debug("Got {d} range fonts back from query", .{range_fonts.len}); |     std.log.debug("Got {d} range fonts back from query", .{range_fonts.len}); | ||||||
|  | @ -323,7 +323,7 @@ test "command line parses with long name no equals" { | ||||||
|     try std.testing.expectEqualStrings("Latin-1", options.groups.?); |     try std.testing.expectEqualStrings("Latin-1", options.groups.?); | ||||||
| } | } | ||||||
| test "command line parses with long name equals" { | test "command line parses with long name equals" { | ||||||
|     var log_level = std.testing.log_level; |     const log_level = std.testing.log_level; | ||||||
|     defer std.testing.log_level = log_level; |     defer std.testing.log_level = log_level; | ||||||
|     // std.testing.log_level = .debug; |     // std.testing.log_level = .debug; | ||||||
|     var it = try std.process.ArgIteratorGeneral(.{}).init(std.testing.allocator, "--groups=Latin-1"); |     var it = try std.process.ArgIteratorGeneral(.{}).init(std.testing.allocator, "--groups=Latin-1"); | ||||||
|  | @ -339,7 +339,7 @@ test "Get ranges" { | ||||||
|     var fl = try fq.fontList(":regular:normal:spacing=100:slant=0"); |     var fl = try fq.fontList(":regular:normal:spacing=100:slant=0"); | ||||||
|     defer fl.deinit(); |     defer fl.deinit(); | ||||||
|     try std.testing.expect(fl.list.items.len > 0); |     try std.testing.expect(fl.list.items.len > 0); | ||||||
|     var matched = blk: { |     const matched = blk: { | ||||||
|         for (fl.list.items) |item| { |         for (fl.list.items) |item| { | ||||||
|             std.log.debug("full_name: '{s}'", .{item.full_name}); |             std.log.debug("full_name: '{s}'", .{item.full_name}); | ||||||
|             if (std.mem.eql(u8, "DejaVu Sans Mono", item.full_name)) |             if (std.mem.eql(u8, "DejaVu Sans Mono", item.full_name)) | ||||||
|  | @ -352,7 +352,7 @@ test "Get ranges" { | ||||||
|     var al = std.ArrayList(u8).init(std.testing.allocator); |     var al = std.ArrayList(u8).init(std.testing.allocator); | ||||||
|     defer al.deinit(); |     defer al.deinit(); | ||||||
|     const range_name = "Basic Latin"; |     const range_name = "Basic Latin"; | ||||||
|     var matched_range = try blk: { |     const matched_range = try blk: { | ||||||
|         var unicode_ranges = unicode.all_ranges(); |         var unicode_ranges = unicode.all_ranges(); | ||||||
|         while (unicode_ranges.next()) |range| { |         while (unicode_ranges.next()) |range| { | ||||||
|             var it = std.mem.splitScalar(u8, range_name, ','); |             var it = std.mem.splitScalar(u8, range_name, ','); | ||||||
|  | @ -364,7 +364,7 @@ test "Get ranges" { | ||||||
|         } |         } | ||||||
|         break :blk error.RangeNotFound; |         break :blk error.RangeNotFound; | ||||||
|     }; |     }; | ||||||
|     var log_level = std.testing.log_level; |     const log_level = std.testing.log_level; | ||||||
|     std.testing.log_level = .debug; |     std.testing.log_level = .debug; | ||||||
|     defer std.testing.log_level = log_level; |     defer std.testing.log_level = log_level; | ||||||
|     try outputRange( |     try outputRange( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue