# NOSTR Core Library Makefile # Standalone library build system CC = gcc AR = ar CFLAGS = -Wall -Wextra -std=c99 -fPIC -O2 DEBUG_CFLAGS = -Wall -Wextra -std=c99 -fPIC -g -DDEBUG STATIC_CFLAGS = -Wall -Wextra -std=c99 -O2 -static # Logging compile flags LOGGING_FLAGS ?= -DENABLE_FILE_LOGGING -DENABLE_WEBSOCKET_LOGGING -DENABLE_DEBUG_LOGGING ifneq ($(ENABLE_LOGGING),) LOGGING_FLAGS += -DENABLE_FILE_LOGGING -DENABLE_WEBSOCKET_LOGGING -DENABLE_DEBUG_LOGGING endif # Include paths INCLUDES = -I. -Inostr_core -Icjson -Isecp256k1/include -Inostr_websocket -I./openssl-install/include # Library source files LIB_SOURCES = nostr_core/core.c nostr_core/core_relays.c nostr_core/nostr_crypto.c nostr_core/nostr_secp256k1.c nostr_core/nostr_aes.c nostr_core/nostr_chacha20.c nostr_websocket/nostr_websocket_openssl.c cjson/cJSON.c LIB_OBJECTS = $(LIB_SOURCES:.c=.o) ARM64_LIB_OBJECTS = $(LIB_SOURCES:.c=.arm64.o) # secp256k1 library paths SECP256K1_LIB = ./secp256k1/.libs/libsecp256k1.a SECP256K1_PRECOMPUTED_LIB = ./secp256k1/.libs/libsecp256k1_precomputed.a # ARM64 secp256k1 library paths SECP256K1_ARM64_LIB = ./secp256k1/.libs/libsecp256k1_arm64.a SECP256K1_ARM64_PRECOMPUTED_LIB = ./secp256k1/.libs/libsecp256k1_precomputed_arm64.a # Library outputs (static only) STATIC_LIB = libnostr_core.a ARM64_STATIC_LIB = libnostr_core_arm64.a # Example files EXAMPLE_SOURCES = $(wildcard examples/*.c) EXAMPLE_TARGETS = $(EXAMPLE_SOURCES:.c=) # Default target - build both x64 and ARM64 static libraries default: $(STATIC_LIB) $(ARM64_STATIC_LIB) # Build all targets (static only) all: $(STATIC_LIB) $(ARM64_STATIC_LIB) examples # Static library - includes secp256k1 and OpenSSL objects for self-contained library $(STATIC_LIB): $(LIB_OBJECTS) $(SECP256K1_LIB) @echo "Creating self-contained static library: $@" @echo "Extracting secp256k1 objects..." @mkdir -p .tmp_secp256k1 @cd .tmp_secp256k1 && $(AR) x ../$(SECP256K1_LIB) @if [ -f $(SECP256K1_PRECOMPUTED_LIB) ]; then \ echo "Extracting secp256k1_precomputed objects..."; \ cd .tmp_secp256k1 && $(AR) x ../$(SECP256K1_PRECOMPUTED_LIB); \ fi @echo "Extracting OpenSSL objects..." @mkdir -p .tmp_openssl @cd .tmp_openssl && $(AR) x ../openssl-install/lib64/libssl.a @cd .tmp_openssl && $(AR) x ../openssl-install/lib64/libcrypto.a @echo "Combining all objects into $@..." $(AR) rcs $@ $(LIB_OBJECTS) .tmp_secp256k1/*.o .tmp_openssl/*.o @rm -rf .tmp_secp256k1 .tmp_openssl @echo "Self-contained static library created: $@" # ARM64 cross-compilation settings ARM64_CC = aarch64-linux-gnu-gcc ARM64_AR = aarch64-linux-gnu-ar ARM64_INCLUDES = -I. -Inostr_core -Icjson -Isecp256k1/include -Inostr_websocket -I./openssl-install/include -I./curl-install/include # ARM64 static library - includes secp256k1 objects for self-contained library (OpenSSL handled separately for cross-compile) $(ARM64_STATIC_LIB): $(ARM64_LIB_OBJECTS) $(SECP256K1_ARM64_LIB) @echo "Creating self-contained ARM64 static library: $@" @echo "Extracting ARM64 secp256k1 objects..." @mkdir -p .tmp_secp256k1_arm64 @cd .tmp_secp256k1_arm64 && $(ARM64_AR) x ../$(SECP256K1_ARM64_LIB) @if [ -f $(SECP256K1_ARM64_PRECOMPUTED_LIB) ]; then \ echo "Extracting ARM64 secp256k1_precomputed objects..."; \ cd .tmp_secp256k1_arm64 && $(ARM64_AR) x ../$(SECP256K1_ARM64_PRECOMPUTED_LIB); \ fi @echo "Note: ARM64 users need to link with OpenSSL separately: -lssl -lcrypto" @echo "Combining all ARM64 objects into $@..." $(ARM64_AR) rcs $@ $(ARM64_LIB_OBJECTS) .tmp_secp256k1_arm64/*.o @rm -rf .tmp_secp256k1_arm64 @echo "Self-contained ARM64 static library created: $@" # Build secp256k1 for ARM64 $(SECP256K1_ARM64_LIB): secp256k1/configure @echo "Building secp256k1 for ARM64..." @echo "Cleaning secp256k1 source directory first..." @cd secp256k1 && make distclean 2>/dev/null || true @mkdir -p secp256k1/build_arm64 @cd secp256k1/build_arm64 && \ CC=$(ARM64_CC) AR=$(ARM64_AR) \ ../configure --host=aarch64-linux-gnu \ --enable-module-schnorrsig \ --enable-module-ecdh \ --enable-experimental \ --disable-shared \ --enable-static \ --with-pic \ --prefix=$(PWD)/secp256k1/install_arm64 && \ make -j$(shell nproc 2>/dev/null || echo 4) @mkdir -p secp256k1/.libs @cp secp256k1/build_arm64/.libs/libsecp256k1.a $(SECP256K1_ARM64_LIB) @if [ -f secp256k1/build_arm64/.libs/libsecp256k1_precomputed.a ]; then \ cp secp256k1/build_arm64/.libs/libsecp256k1_precomputed.a $(SECP256K1_ARM64_PRECOMPUTED_LIB); \ fi @echo "ARM64 secp256k1 libraries built successfully" @echo "Restoring x64 secp256k1 build..." @cd secp256k1 && ./configure --enable-module-schnorrsig --enable-module-ecdh --enable-experimental --disable-shared --enable-static --with-pic >/dev/null 2>&1 && make -j$(shell nproc 2>/dev/null || echo 4) >/dev/null 2>&1 || true # Object files (x86_64) %.o: %.c @echo "Compiling: $<" $(CC) $(CFLAGS) $(LOGGING_FLAGS) $(INCLUDES) -c $< -o $@ # ARM64 object files %.arm64.o: %.c @echo "Compiling for ARM64: $<" $(ARM64_CC) $(CFLAGS) $(LOGGING_FLAGS) $(ARM64_INCLUDES) -c $< -o $@ # Examples examples: $(EXAMPLE_TARGETS) examples/%: examples/%.c $(STATIC_LIB) @echo "Building example: $@" $(CC) $(STATIC_CFLAGS) $(LOGGING_FLAGS) $(INCLUDES) $< -o $@ ./libnostr_core.a -lm # Architecture-specific targets x64: $(STATIC_LIB) x64-only: $(STATIC_LIB) # ARM64 targets arm64: $(ARM64_STATIC_LIB) arm64-all: $(ARM64_STATIC_LIB) arm64-only: $(ARM64_STATIC_LIB) # Debug build debug: CFLAGS = $(DEBUG_CFLAGS) debug: clean default # Install library to system (static only) install: $(STATIC_LIB) @echo "Installing static library..." sudo cp $(STATIC_LIB) /usr/local/lib/ sudo cp nostr_core/nostr_core.h /usr/local/include/ sudo cp nostr_core/nostr_crypto.h /usr/local/include/ # Uninstall library uninstall: @echo "Uninstalling library..." sudo rm -f /usr/local/lib/$(STATIC_LIB) sudo rm -f /usr/local/include/nostr_core.h sudo rm -f /usr/local/include/nostr_crypto.h # Test executables CRYPTO_TEST_EXEC = tests/nostr_crypto_test CORE_TEST_EXEC = tests/nostr_core_test RELAY_POOL_TEST_EXEC = tests/relay_pool_test EVENT_GEN_TEST_EXEC = tests/test_event_generation POW_LOOP_TEST_EXEC = tests/test_pow_loop NIP04_TEST_EXEC = tests/nip04_test HTTP_TEST_EXEC = tests/http_test WSS_TEST_EXEC = tests/wss_test STATIC_LINKING_TEST_EXEC = tests/static_linking_only_test MAKEFILE_STATIC_TEST_EXEC = tests/makefile_static_test NIP05_TEST_EXEC = tests/nip05_test NIP11_TEST_EXEC = tests/nip11_test ARM64_CRYPTO_TEST_EXEC = tests/nostr_crypto_test_arm64 ARM64_CORE_TEST_EXEC = tests/nostr_core_test_arm64 ARM64_RELAY_POOL_TEST_EXEC = tests/relay_pool_test_arm64 ARM64_NIP04_TEST_EXEC = tests/nip04_test_arm64 # Test compilation flags TEST_CFLAGS = -Wall -Wextra -std=c99 -g -I. -I./secp256k1/include -I./openssl-install/include -DDISABLE_NIP05 TEST_LDFLAGS = -L. -lnostr_core -lm -static ARM64_TEST_CFLAGS = -Wall -Wextra -std=c99 -g -I. -DDISABLE_NIP05 ARM64_TEST_LDFLAGS = -L. -lnostr_core_arm64 -lssl -lcrypto -lm -static # Build crypto test executable (x86_64) $(CRYPTO_TEST_EXEC): tests/nostr_crypto_test.c $(STATIC_LIB) @echo "Building crypto test suite (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build core test executable (x86_64) $(CORE_TEST_EXEC): tests/nostr_core_test.c $(STATIC_LIB) @echo "Building core test suite (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build relay pool test executable (x86_64) $(RELAY_POOL_TEST_EXEC): tests/relay_pool_test.c $(STATIC_LIB) @echo "Building relay pool test suite (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build event generation test executable (x86_64) $(EVENT_GEN_TEST_EXEC): tests/test_event_generation.c $(STATIC_LIB) @echo "Building event generation test suite (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build PoW loop test executable (x86_64) $(POW_LOOP_TEST_EXEC): tests/test_pow_loop.c $(STATIC_LIB) @echo "Building PoW loop test program (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build NIP-04 test executable (x86_64) $(NIP04_TEST_EXEC): tests/nip04_test.c $(STATIC_LIB) @echo "Building NIP-04 encryption test suite (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build HTTP test executable (x86_64) - Uses static curl for compatibility testing $(HTTP_TEST_EXEC): tests/http_test.c @echo "Building HTTP/curl compatibility test (x86_64)..." $(CC) $(TEST_CFLAGS) -I./curl-install/include $< -o $@ ./curl-install/lib/libcurl.a -lssl -lcrypto -lz -ldl -lpthread -static # Build WebSocket SSL test executable (x86_64) $(WSS_TEST_EXEC): tests/wss_test.c $(STATIC_LIB) @echo "Building WebSocket SSL/OpenSSL compatibility test (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build static linking test executable (x86_64) $(STATIC_LINKING_TEST_EXEC): tests/static_linking_only_test.c $(STATIC_LIB) @echo "Building static linking verification test (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build Makefile-based static test executable (x86_64) - No library dependency, just parses Makefile $(MAKEFILE_STATIC_TEST_EXEC): tests/makefile_static_test.c @echo "Building Makefile-based static configuration test (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ -static # Build NIP-05 test executable (x86_64) - NIP-05 enabled with static curl $(NIP05_TEST_EXEC): tests/nip05_test.c $(STATIC_LIB) @echo "Building NIP-05 identifier verification test (x86_64)..." $(CC) -Wall -Wextra -std=c99 -g -I. -I./secp256k1/include -I./openssl-install/include -I./curl-install/include $< -o $@ -L. -L./openssl-install/lib64 -lnostr_core ./curl-install/lib/libcurl.a ./openssl-install/lib64/libssl.a ./openssl-install/lib64/libcrypto.a -lz -ldl -lpthread -lm -static # Build NIP-11 test executable (x86_64) - NIP-11 enabled with static curl $(NIP11_TEST_EXEC): tests/nip11_test.c $(STATIC_LIB) @echo "Building NIP-11 relay information test (x86_64)..." $(CC) -Wall -Wextra -std=c99 -g -I. -I./secp256k1/include -I./openssl-install/include -I./curl-install/include $< -o $@ -L. -L./openssl-install/lib64 -lnostr_core ./curl-install/lib/libcurl.a ./openssl-install/lib64/libssl.a ./openssl-install/lib64/libcrypto.a -lz -ldl -lpthread -lm -static # Build simple initialization test executable (x86_64) tests/simple_init_test: tests/simple_init_test.c $(STATIC_LIB) @echo "Building simple initialization test program (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build ChaCha20 test executable (x86_64) tests/chacha20_test: tests/chacha20_test.c $(STATIC_LIB) @echo "Building ChaCha20 RFC 8439 test suite (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build sync test executable (x86_64) tests/sync_test: tests/sync_test.c $(STATIC_LIB) @echo "Building synchronous relay query test program (x86_64)..." $(CC) $(TEST_CFLAGS) $< -o $@ $(TEST_LDFLAGS) # Build crypto test ARM64 executable $(ARM64_CRYPTO_TEST_EXEC): tests/nostr_crypto_test.c $(ARM64_STATIC_LIB) @echo "Building crypto test suite (ARM64)..." $(ARM64_CC) $(ARM64_TEST_CFLAGS) $< -o $@ $(ARM64_TEST_LDFLAGS) # Build core test ARM64 executable $(ARM64_CORE_TEST_EXEC): tests/nostr_core_test.c $(ARM64_STATIC_LIB) @echo "Building core test suite (ARM64)..." $(ARM64_CC) $(ARM64_TEST_CFLAGS) $< -o $@ $(ARM64_TEST_LDFLAGS) # Build relay pool test ARM64 executable $(ARM64_RELAY_POOL_TEST_EXEC): tests/relay_pool_test.c $(ARM64_STATIC_LIB) @echo "Building relay pool test suite (ARM64)..." $(ARM64_CC) $(ARM64_TEST_CFLAGS) $< -o $@ $(ARM64_TEST_LDFLAGS) # Build NIP-04 test ARM64 executable $(ARM64_NIP04_TEST_EXEC): tests/nip04_test.c $(ARM64_STATIC_LIB) @echo "Building NIP-04 encryption test suite (ARM64)..." $(ARM64_CC) $(ARM64_TEST_CFLAGS) $< -o $@ $(ARM64_TEST_LDFLAGS) # Run crypto tests (x86_64) test-crypto: $(CRYPTO_TEST_EXEC) @echo "Running crypto tests (x86_64)..." ./$(CRYPTO_TEST_EXEC) # Run core tests (x86_64) test-core: $(CORE_TEST_EXEC) @echo "Running core tests (x86_64)..." ./$(CORE_TEST_EXEC) # Run relay pool tests (x86_64) test-relay-pool: $(RELAY_POOL_TEST_EXEC) @echo "Running relay pool tests (x86_64)..." ./$(RELAY_POOL_TEST_EXEC) # Run NIP-04 tests (x86_64) test-nip04: $(NIP04_TEST_EXEC) @echo "Running NIP-04 encryption tests (x86_64)..." ./$(NIP04_TEST_EXEC) # Run HTTP tests (x86_64) test-http: $(HTTP_TEST_EXEC) @echo "Running HTTP/curl compatibility tests (x86_64)..." ./$(HTTP_TEST_EXEC) # Run WebSocket SSL tests (x86_64) test-wss: $(WSS_TEST_EXEC) @echo "Running WebSocket SSL/OpenSSL compatibility tests (x86_64)..." ./$(WSS_TEST_EXEC) # Run static linking verification test (x86_64) test-static-linking: $(STATIC_LINKING_TEST_EXEC) @echo "Running static linking verification test (x86_64)..." ./$(STATIC_LINKING_TEST_EXEC) # Run Makefile-based static configuration test (x86_64) test-makefile-static: $(MAKEFILE_STATIC_TEST_EXEC) @echo "Running Makefile-based static configuration test (x86_64)..." ./$(MAKEFILE_STATIC_TEST_EXEC) # Run NIP-05 tests (x86_64) test-nip05: $(NIP05_TEST_EXEC) @echo "Running NIP-05 identifier verification tests (x86_64)..." ./$(NIP05_TEST_EXEC) # Run NIP-11 tests (x86_64) test-nip11: $(NIP11_TEST_EXEC) @echo "Running NIP-11 relay information tests (x86_64)..." ./$(NIP11_TEST_EXEC) # Run all test suites (x86_64) test: test-crypto test-core test-relay-pool test-nip04 test-http test-wss test-static-linking test-makefile-static test-nip05 test-nip11 # Run crypto tests ARM64 (requires qemu-user-static or ARM64 system) test-crypto-arm64: $(ARM64_CRYPTO_TEST_EXEC) @echo "Running crypto tests (ARM64)..." @if command -v qemu-aarch64-static >/dev/null 2>&1; then \ echo "Using qemu-aarch64-static to run ARM64 binary..."; \ qemu-aarch64-static ./$(ARM64_CRYPTO_TEST_EXEC); \ else \ echo "qemu-aarch64-static not found. ARM64 binary built but cannot run on x86_64."; \ echo "To run: copy $(ARM64_CRYPTO_TEST_EXEC) to ARM64 system and execute."; \ file ./$(ARM64_CRYPTO_TEST_EXEC); \ fi # Run core tests ARM64 (requires qemu-user-static or ARM64 system) test-core-arm64: $(ARM64_CORE_TEST_EXEC) @echo "Running core tests (ARM64)..." @if command -v qemu-aarch64-static >/dev/null 2>&1; then \ echo "Using qemu-aarch64-static to run ARM64 binary..."; \ qemu-aarch64-static ./$(ARM64_CORE_TEST_EXEC); \ else \ echo "qemu-aarch64-static not found. ARM64 binary built but cannot run on x86_64."; \ echo "To run: copy $(ARM64_CORE_TEST_EXEC) to ARM64 system and execute."; \ file ./$(ARM64_CORE_TEST_EXEC); \ fi # Run relay pool tests ARM64 (requires qemu-user-static or ARM64 system) test-relay-pool-arm64: $(ARM64_RELAY_POOL_TEST_EXEC) @echo "Running relay pool tests (ARM64)..." @if command -v qemu-aarch64-static >/dev/null 2>&1; then \ echo "Using qemu-aarch64-static to run ARM64 binary..."; \ qemu-aarch64-static ./$(ARM64_RELAY_POOL_TEST_EXEC); \ else \ echo "qemu-aarch64-static not found. ARM64 binary built but cannot run on x86_64."; \ echo "To run: copy $(ARM64_RELAY_POOL_TEST_EXEC) to ARM64 system and execute."; \ file ./$(ARM64_RELAY_POOL_TEST_EXEC); \ fi # Run all test suites on ARM64 test-arm64: test-crypto-arm64 test-core-arm64 test-relay-pool-arm64 # Run tests on both architectures test-all: test test-arm64 # Test the library with simple example test-simple: examples/simple_keygen @echo "Running simple key generation test..." ./examples/simple_keygen # Clean build artifacts clean: @echo "Cleaning build artifacts..." rm -f $(LIB_OBJECTS) $(ARM64_LIB_OBJECTS) rm -f $(STATIC_LIB) $(ARM64_STATIC_LIB) rm -f $(SECP256K1_ARM64_LIB) $(SECP256K1_ARM64_PRECOMPUTED_LIB) rm -f $(EXAMPLE_TARGETS) rm -rf .tmp_secp256k1 .tmp_secp256k1_arm64 .tmp_openssl rm -rf secp256k1/build_arm64 secp256k1/install_arm64 # Create distribution package dist: clean @echo "Creating distribution package..." mkdir -p dist/nostr_core cp -r *.h *.c Makefile examples/ tests/ README.md LICENSE dist/nostr_core/ 2>/dev/null || true cd dist && tar -czf nostr_core.tar.gz nostr_core/ @echo "Distribution package created: dist/nostr_core.tar.gz" # Help help: @echo "NOSTR Core Library Build System" @echo "===============================" @echo "" @echo "Available targets:" @echo " default - Build both x64 and ARM64 static libraries (recommended)" @echo " all - Build both architectures and examples" @echo " x64 - Build x64 static library only" @echo " x64-only - Build x64 static library only" @echo " arm64 - Build ARM64 static library only" @echo " arm64-only - Build ARM64 static library only" @echo " arm64-all - Build ARM64 static library only" @echo " debug - Build with debug symbols (both architectures)" @echo " examples - Build example programs" @echo " test - Run simple test" @echo " test-crypto - Run comprehensive crypto test suite" @echo " install - Install static library to system (/usr/local)" @echo " uninstall - Remove library from system" @echo " clean - Remove build artifacts" @echo " dist - Create distribution package" @echo " help - Show this help" @echo "" @echo "Library outputs (static only, self-contained):" @echo " $(STATIC_LIB) - x86_64 static library (includes secp256k1 + OpenSSL)" @echo " $(ARM64_STATIC_LIB) - ARM64 static library (includes secp256k1, needs OpenSSL)" @echo "" @echo "x64 library: Users only need to link with the library + -lm" @echo "ARM64 library: Users need to link with the library + -lssl -lcrypto -lm" .PHONY: default all x64 x64-only arm64 arm64-all arm64-only debug examples test test-crypto install uninstall clean dist help