From 388f3289b39e4a78f188e2e7afbbaecc3575267b Mon Sep 17 00:00:00 2001
From: Vinzenz Schroeter <vinzenz.f.s@gmail.com>
Date: Thu, 24 Apr 2025 22:47:27 +0200
Subject: [PATCH] a bunch of options for the Makefile

---
 example/Makefile                      | 150 ++++++++++++++++----------
 example/{ => src}/announce.c          |  10 +-
 example/{ => src}/brightness_tester.c |   4 +-
 example/{ => src}/random_stuff.c      |   5 +-
 flake.nix                             |  20 ++--
 include/servicepoint.h                |  35 +++---
 src/lib.rs                            |   3 +
 7 files changed, 133 insertions(+), 94 deletions(-)
 rename example/{ => src}/announce.c (82%)
 rename example/{ => src}/brightness_tester.c (84%)
 rename example/{ => src}/random_stuff.c (72%)

diff --git a/example/Makefile b/example/Makefile
index 7e5bfe7..a35aa5c 100644
--- a/example/Makefile
+++ b/example/Makefile
@@ -1,85 +1,119 @@
-CC := gcc
-CARGO := rustup run nightly cargo
+CARGO ?= cargo
+STRIP ?= strip
 
-TARGET := x86_64-unknown-linux-musl
-PROFILE := size-optimized
-FEATURES := protocol_udp
+FEATURES :=
 
 THIS_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
-REPO_ROOT := $(THIS_DIR)/..
-RUST_TARGET_DIR := $(REPO_ROOT)/target/$(TARGET)/$(PROFILE)
+REPO_ROOT := $(realpath $(THIS_DIR)/..)
 export SERVICEPOINT_HEADER_OUT := $(REPO_ROOT)/include
 
-RUSTFLAGS := -Zlocation-detail=none \
-	-Zfmt-debug=none \
-	-C linker=musl-gcc \
-	-C link-arg=-s \
-	-C link-arg=--gc-sections \
-	-C link-arg=-z,norelro \
-	-C link-arg=--hash-style=gnu \
-	--crate-type=staticlib \
-	-C panic=abort
+override CFG_MUSL := $(if $(CFG_MUSL),$(CFG_MUSL),$(if $(MUSL),$(MUSL),0))
+override CFG_PROFILE := $(if $(CFG_PROFILE),$(CFG_PROFILE),$(if $(PROFILE),$(PROFILE),release))
 
-CARGOFLAGS := --manifest-path=$(REPO_ROOT)/Cargo.toml \
-	--profile=$(PROFILE) \
+CCFLAGS += -Wall -fwhole-program
+
+STRIPFLAGS := -s --strip-unneeded -R .comment -R .gnu.version -R .note -R .note.gnu.build-id -R .note.ABI-tag
+
+ifeq ($(CFG_MUSL), 1)
+	TARGET ?= x86_64-unknown-linux-musl
+	CC ?= musl-gcc
+	CCFLAGS += -static -lservicepoint_binding_c
+	RUSTFLAGS += --crate-type=staticlib
+else
+	TARGET ?= x86_64-unknown-linux-gnu
+	CC ?= gcc
+	#CCFLAGS += -shared
+	CCFLAGS += -Wl,-Bstatic -lservicepoint_binding_c -Wl,-Bdynamic
+endif
+
+#ifeq ($(CFG_PROFILE), size-optimized)
+#	CCFLAGS += -nodefaultlibs -lc
+#endif
+
+RUST_TARGET_DIR := $(REPO_ROOT)/target/$(TARGET)/$(CFG_PROFILE)
+OUT_DIR := $(realpath $(THIS_DIR)/out/)
+
+ifeq ($(CFG_PROFILE), size-optimized)
+	CARGO_PROFILE := size-optimized
+	CCFLAGS += -Oz \
+		-fwrapv -fomit-frame-pointer -fno-stack-protector\
+		-fno-unroll-loops \
+		-fno-unwind-tables -fno-asynchronous-unwind-tables \
+		-fmerge-all-constants \
+		-Wl,-z,norelro \
+		-Wl,--hash-style=gnu \
+		-fvisibility=hidden \
+		-Bsymbolic \
+		-Wl,--exclude-libs,ALL \
+		-fno-ident \
+		-fno-exceptions
+	CARGOFLAGS += -Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
+		-Zbuild-std-features="panic_immediate_abort"
+	RUSTFLAGS += -Zlocation-detail=none \
+		-Zfmt-debug=none \
+		-C link-arg=-z,norelro \
+		-C panic=abort
+		#-C link-arg=--hash-style=gnu
+else ifeq ($(CFG_PROFILE), release)
+	CARGO_PROFILE := release
+	CCFLAGS += -O2
+else ifeq ($(CFG_PROFILE), debug)
+	CCFLAGS += -Og
+	CARGO_PROFILE := dev
+else
+	CFG_PROFILE := $(error "PROFILE has to be set to one of: debug, release, size-optimized")
+endif
+
+CARGOFLAGS += --manifest-path=$(REPO_ROOT)/Cargo.toml \
+	--profile=$(CARGO_PROFILE) \
 	--no-default-features \
 	--features=$(FEATURES) \
-	--target=$(TARGET) \
-	-Zbuild-std="core,std,alloc,proc_macro,panic_abort" \
-	-Zbuild-std-features="panic_immediate_abort" \
+	--target=$(TARGET)
 
-CCFLAGS := -static -Os \
-	-ffunction-sections -fdata-sections \
-	-fwrapv -fomit-frame-pointer -fno-stack-protector\
-	-fwhole-program \
-	-nodefaultlibs -lservicepoint_binding_c -lc \
-	-Wl,--gc-sections \
-	-fno-unroll-loops \
-	-fno-unwind-tables -fno-asynchronous-unwind-tables \
-	-fmerge-all-constants \
-	-Wl,-z,norelro \
-	-Wl,--hash-style=gnu \
-	-fvisibility=hidden \
-	-Bsymbolic \
-	-Wl,--exclude-libs,ALL \
-	-fno-ident \
-	-Wall
-	#-fuse-ld=gold \
-	-fno-exceptions
-	#-Wl,--icf=all \
+ifneq ($(CFG_PROFILE), debug)
+	CCFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections
+	RUSTFLAGS += -C link-arg=-s -C link-arg=-Wl,--gc-sections
+endif
 
-STRIPFLAGS := -s --strip-unneeded -R .comment -R .gnu.version -R .comment -R .note -R .note.gnu.build-id -R .note.ABI-tag
+ifeq ($(LTO), 1)
+	CCFLAGS += -flto
+endif
 
-_c_src := $(wildcard *.c)
-_programs := $(basename $(_c_src))
+_c_src := $(wildcard ./src/*.c)
+_programs := $(basename $(notdir $(_c_src)))
 _bins := $(addprefix out/, $(_programs))
 _unstripped_bins := $(addsuffix _unstripped, $(_bins))
 _run_programs := $(addprefix run_, $(_programs))
 _rs_src := $(wildcard ../src/**.rs) ../Cargo.lock ../Cargo.toml ../cbindgen.toml
+_sp_artifacts := $(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(RUST_TARGET_DIR)/libservicepoint_binding_c.a $(RUST_TARGET_DIR)/libservicepoint_binding_c.so
 
 all: $(_bins)
 
-clean:
-	rm -r out || true
-	rm include/servicepoint.h || true
+clean: clean-c clean-rust
+
+clean-c:
+	rm -r $(OUT_DIR) || true
+
+clean-rust:
+	rm $(SERVICEPOINT_HEADER_OUT)/servicepoint.h || true
 	cargo clean
 
-PHONY: all clean sizes $(_run_programs)
+.PHONY: all clean sizes $(_run_programs) clean-c clean-rust
 
-$(_unstripped_bins): out/%_unstripped: %.c $(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(RUST_TARGET_DIR)/libservicepoint_binding_c.a
+$(_unstripped_bins): out/%_unstripped: src/%.c $(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(_sp_artifacts)
 	mkdir -p out || true
-	${CC} $^ \
+	${CC} $< \
 		-I $(SERVICEPOINT_HEADER_OUT) \
-		-L $(RUST_TARGET_DIR)\
+		-L $(RUST_TARGET_DIR) \
 		$(CCFLAGS) \
 		-o $@
 
 $(_bins): out/%: out/%_unstripped
-	strip $(STRIPFLAGS) $^ -o $@
+	$(STRIP) $(STRIPFLAGS) $^ -o $@
 
-$(SERVICEPOINT_HEADER_OUT)/servicepoint.h $(RUST_TARGET_DIR)/libservicepoint_binding_c.a: $(_rs_src)
-	mkdir -p include || true
-	# generate servicepoint header and binary to link against
+$(_sp_artifacts): $(_rs_src)
+	mkdir -p $(SERVICEPOINT_HEADER_OUT) || true
+	# generate servicepoint header and library to link against
 	${CARGO} rustc $(CARGOFLAGS) -- $(RUSTFLAGS)
 
 $(_run_programs): run_%: out/% FORCE
@@ -88,9 +122,9 @@ $(_run_programs): run_%: out/% FORCE
 sizes: $(_bins)
 	ls -lB out
 
-#analyze-size: out/example_unstripped
-#	nm --print-size --size-sort --reverse-sort --radix=d --demangle out/example_unstripped \
-#		| awk '{size=$$2+0; print size "\t" $$4}' \
-#		| less
+analyze-size: out/$(BIN)_unstripped
+	nm --print-size --size-sort --reverse-sort --radix=d --demangle $(OUT_DIR)/$(BIN)_unstripped \
+		| awk '{size=$$2+0; print size "\t" $$4}' \
+		| less
 
 FORCE: ;
diff --git a/example/announce.c b/example/src/announce.c
similarity index 82%
rename from example/announce.c
rename to example/src/announce.c
index 737eff5..d256cff 100644
--- a/example/announce.c
+++ b/example/src/announce.c
@@ -1,8 +1,12 @@
+#include <stdio.h>
 #include "servicepoint.h"
 
+
 int main(void) {
-    //UdpConnection *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
-    UdpConnection *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
+    printf("test\n");
+
+    UdpSocket *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
+    //UdpSocket *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
     if (connection == NULL)
         return 1;
 
@@ -11,7 +15,7 @@ int main(void) {
     CharGrid *grid = sp_char_grid_new(5, 2);
     if (grid == NULL)
         return 1;
-    
+
     sp_char_grid_set(grid, 0, 0, 'H');
     sp_char_grid_set(grid, 1, 0, 'e');
     sp_char_grid_set(grid, 2, 0, 'l');
diff --git a/example/brightness_tester.c b/example/src/brightness_tester.c
similarity index 84%
rename from example/brightness_tester.c
rename to example/src/brightness_tester.c
index d06d30d..c3e42ba 100644
--- a/example/brightness_tester.c
+++ b/example/src/brightness_tester.c
@@ -1,8 +1,8 @@
 #include "servicepoint.h"
 
 int main(void) {
-    // UdpConnection *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
-    UdpConnection *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
+    UdpSocket *connection = sp_udp_open_ipv4(172, 23, 42, 29, 2342);
+    //UdpSocket *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
     if (connection == NULL)
         return -1;
 
diff --git a/example/random_stuff.c b/example/src/random_stuff.c
similarity index 72%
rename from example/random_stuff.c
rename to example/src/random_stuff.c
index ca5a14d..96beefb 100644
--- a/example/random_stuff.c
+++ b/example/src/random_stuff.c
@@ -1,8 +1,7 @@
-#include <stdio.h>
 #include "servicepoint.h"
 
 int main(void) {
-    UdpConnection *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
+    UdpSocket *connection = sp_udp_open_ipv4(127, 0, 0, 1, 2342);
     if (connection == NULL)
         return 1;
 
@@ -17,7 +16,7 @@ int main(void) {
         return 1;
 
     Header *header = sp_packet_get_header(packet);
-    printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d);
+    // printf("[%d, %d, %d, %d, %d]\n", header->command_code, header->a, header->b, header->c, header->d);
 
     sp_udp_send_packet(connection, packet);
 
diff --git a/flake.nix b/flake.nix
index b4f874f..9d67ae9 100644
--- a/flake.nix
+++ b/flake.nix
@@ -33,16 +33,17 @@
         { pkgs, system }:
         {
           default = pkgs.mkShell rec {
-            buildInputs = with pkgs;[
+            buildInputs = with pkgs; [
               xe
               xz
-              libgcc
-              #glibc.static
-              musl
-              libunwind
-              ];
+              #libgcc
+              #glibc
+              pkgsStatic.musl
+              # libunwind
 
-            nativeBuildInputs = with pkgs;[
+            ];
+
+            nativeBuildInputs = with pkgs; [
               (pkgs.symlinkJoin {
                 name = "rust-toolchain";
                 paths = with pkgs; [
@@ -57,11 +58,14 @@
                 ];
               })
               gcc
+              gdb
+              pkgsStatic.gcc
               gnumake
               pkg-config
             ];
 
-            RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
+            #RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
+            CARGO = "rustup run nightly cargo";
           };
         }
       );
diff --git a/include/servicepoint.h b/include/servicepoint.h
index 77d2e36..5863ef5 100644
--- a/include/servicepoint.h
+++ b/include/servicepoint.h
@@ -226,13 +226,9 @@ typedef struct SPBitVec SPBitVec;
 typedef struct TypedCommand TypedCommand;
 
 /**
- * A connection using the UDP protocol.
- *
- * Use this when sending commands directly to the display.
- *
- * Requires the feature "`protocol_udp`" which is enabled by default.
+ * This is a type only used by cbindgen to have a type for pointers.
  */
-typedef struct UdpConnection UdpConnection;
+typedef struct UdpSocket UdpSocket;
 
 /**
  * A 2D grid of values.
@@ -298,7 +294,7 @@ typedef struct {
  * grid.set(1, 1, Brightness::MIN);
  *
  * # let connection = FakeConnection;
- * connection.send(BrightnessGridCommand {
+ * connection.send_command(BrightnessGridCommand {
  *     origin: Origin::new(3, 7),
  *     grid
  * }).unwrap()
@@ -318,7 +314,7 @@ typedef ValueGrid_Brightness BrightnessGrid;
  *
  * let b = Brightness::try_from(7).unwrap();
  * # let connection = FakeConnection;
- * let result = connection.send(GlobalBrightnessCommand::from(b));
+ * let result = connection.send_command(GlobalBrightnessCommand::from(b));
  * ```
  */
 typedef uint8_t Brightness;
@@ -347,7 +343,7 @@ typedef uint8_t Brightness;
  *
  * # let connection = FakeConnection;
  * let command = CharGridCommand { origin: Origin::ZERO, grid };
- * connection.send(command).unwrap()
+ * connection.send_command(command).unwrap()
  * ```
  */
 typedef ValueGrid_char CharGrid;
@@ -1220,7 +1216,7 @@ bool sp_u16_to_command_code(uint16_t code,
 /**
  * Closes and deallocates a [UdpConnection].
  */
-void sp_udp_free(UdpConnection */*notnull*/ connection);
+void sp_udp_free(UdpSocket */*notnull*/ connection);
 
 /**
  * Creates a new instance of [UdpConnection].
@@ -1235,7 +1231,7 @@ void sp_udp_free(UdpConnection */*notnull*/ connection);
  *     sp_udp_send_command(connection, sp_command_clear());
  * ```
  */
-UdpConnection *sp_udp_open(char */*notnull*/ host);
+UdpSocket *sp_udp_open(char */*notnull*/ host);
 
 /**
  * Creates a new instance of [UdpConnection].
@@ -1250,11 +1246,11 @@ UdpConnection *sp_udp_open(char */*notnull*/ host);
  *     sp_udp_send_command(connection, sp_command_clear());
  * ```
  */
-UdpConnection *sp_udp_open_ipv4(uint8_t ip1,
-                                uint8_t ip2,
-                                uint8_t ip3,
-                                uint8_t ip4,
-                                uint16_t port);
+UdpSocket *sp_udp_open_ipv4(uint8_t ip1,
+                            uint8_t ip2,
+                            uint8_t ip3,
+                            uint8_t ip4,
+                            uint16_t port);
 
 /**
  * Sends a [TypedCommand] to the display using the [UdpConnection].
@@ -1269,7 +1265,7 @@ UdpConnection *sp_udp_open_ipv4(uint8_t ip1,
  * sp_udp_send_command(connection, sp_command_brightness(5));
  * ```
  */
-bool sp_udp_send_command(UdpConnection */*notnull*/ connection,
+bool sp_udp_send_command(UdpSocket */*notnull*/ connection,
                          TypedCommand */*notnull*/ command);
 
 /**
@@ -1283,8 +1279,7 @@ bool sp_udp_send_command(UdpConnection */*notnull*/ connection,
  * sp_udp_send_header(connection, sp_command_brightness(5));
  * ```
  */
-bool sp_udp_send_header(UdpConnection */*notnull*/ udp_connection,
-                        Header header);
+bool sp_udp_send_header(UdpSocket */*notnull*/ udp_connection, Header header);
 
 /**
  * Sends a [Packet] to the display using the [UdpConnection].
@@ -1293,7 +1288,7 @@ bool sp_udp_send_header(UdpConnection */*notnull*/ udp_connection,
  *
  * returns: true in case of success
  */
-bool sp_udp_send_packet(UdpConnection */*notnull*/ connection,
+bool sp_udp_send_packet(UdpSocket */*notnull*/ connection,
                         Packet */*notnull*/ packet);
 
 #ifdef __cplusplus
diff --git a/src/lib.rs b/src/lib.rs
index db6361b..47b21d5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -67,3 +67,6 @@ pub(crate) unsafe fn heap_drop<T>(x: NonNull<T>) {
 pub(crate) unsafe fn heap_remove<T>(x: NonNull<T>) -> T {
     unsafe { *Box::from_raw(x.as_ptr()) }
 }
+
+/// This is a type only used by cbindgen to have a type for pointers.
+pub struct UdpSocket;
\ No newline at end of file