|
1 | | -# Makefile |
| 1 | +# Makefile for SQLite Sync Extension |
| 2 | +# Supports compilation for Linux, macOS, Windows, Android and iOS |
2 | 3 |
|
3 | | -# Compiler and flags |
4 | | -CC = gcc |
5 | | -NO_COVERAGE_FLAGS = -Wall -Wextra -Wno-unused-parameter -I$(SRC_DIR) -I$(TEST_DIR) -I$(SQLITE_DIR) -I$(CURL_DIR) |
6 | | -CFLAGS = $(NO_COVERAGE_FLAGS) -DCLOUDSYNC_OMIT_NETWORK=1 -DCLOUDSYNC_OMIT_PRINT_RESULT=1 -fprofile-arcs -ftest-coverage |
7 | | -EXTENSION_FLAGS = $(NO_COVERAGE_FLAGS) -O3 -fPIC |
8 | | - |
9 | | -ifeq ($(shell uname -s),Darwin) |
10 | | -CONFIG_DARWIN=y |
11 | | -else ifeq ($(OS),Windows_NT) |
12 | | -CONFIG_WINDOWS=y |
| 4 | +# Set default platform if not specified |
| 5 | +ifeq ($(OS),Windows_NT) |
| 6 | + PLATFORM := windows |
13 | 7 | else |
14 | | -CONFIG_LINUX=y |
15 | | -endif |
16 | | - |
17 | | -ifdef CONFIG_DARWIN |
18 | | -LOADABLE_EXTENSION=dylib |
19 | | -endif |
20 | | - |
21 | | -ifdef CONFIG_LINUX |
22 | | -LOADABLE_EXTENSION=so |
23 | | -CFLAGS += -lm |
24 | | -endif |
25 | | - |
26 | | -ifdef CONFIG_WINDOWS |
27 | | -LOADABLE_EXTENSION=dll |
| 8 | + UNAME_S := $(shell uname -s) |
| 9 | + ifeq ($(UNAME_S),Darwin) |
| 10 | + PLATFORM := macos |
| 11 | + else |
| 12 | + PLATFORM := linux |
| 13 | + endif |
28 | 14 | endif |
29 | 15 |
|
| 16 | +# Compiler and flags |
| 17 | +CC = gcc |
| 18 | +CFLAGS = -Wall -Wextra -Wno-unused-parameter -I$(SRC_DIR) -I$(SQLITE_DIR) -I$(CURL_DIR) |
| 19 | +TEST_FLAGS = $(CFLAGS) -DSQLITE_CORE -DCLOUDSYNC_UNITTEST -DCLOUDSYNC_OMIT_NETWORK -DCLOUDSYNC_OMIT_PRINT_RESULT -fprofile-arcs -ftest-coverage |
| 20 | +EXTENSION_FLAGS = $(CFLAGS) -O3 -fPIC |
30 | 21 | LDFLAGS = -lcurl |
| 22 | +COVERAGE = false |
31 | 23 |
|
32 | | -# setting the -lgcov flag on macOS leads to a linker error |
33 | | -ifeq ($(shell uname), Linux) |
34 | | - LDFLAGS += -lgcov |
35 | | - DYLIB_LDFLAGS = |
36 | | -else |
37 | | - LDFLAGS += |
38 | | - DYLIB_LDFLAGS = -dynamiclib |
39 | | -endif |
40 | | - |
41 | | -# Directories and files |
| 24 | +# Directories |
42 | 25 | SRC_DIR = src |
| 26 | +DIST_DIR = dist |
43 | 27 | TEST_DIR = test |
44 | 28 | SQLITE_DIR = sqlite |
45 | | -OBJ_DIR = obj |
46 | | -CURL_DIR = network/curl/macos |
| 29 | +VPATH = $(SRC_DIR):$(SQLITE_DIR):$(TEST_DIR) |
| 30 | +BUILD_RELEASE = build/release |
| 31 | +BUILD_TEST = build/test |
| 32 | +BUILD_DIRS = $(BUILD_TEST) $(BUILD_RELEASE) |
| 33 | +CURL_DIR = network/curl/$(PLATFORM) |
47 | 34 | COV_DIR = coverage |
48 | | -CUSTOM_CSS = $(TEST_DIR)/sqlitecloud.css |
49 | | -TARGET_PREFIX=dist |
50 | | - |
51 | | -TARGET_NAME=cloudsync |
52 | | -TARGET_LOADABLE=$(TARGET_PREFIX)/$(TARGET_NAME).$(LOADABLE_EXTENSION) |
53 | | -TARGET_STATIC=$(TARGET_PREFIX)/libsqlite_$(TARGET_NAME)0.a |
54 | | -TARGET_STATIC_H=$(TARGET_PREFIX)/sqlite-$(TARGET_NAME).h |
55 | | -TARGET_CLI=$(TARGET_PREFIX)/sqlite3 |
| 35 | +CUSTOM_CSS = $(TEST_DIR)/sqliteai.css |
56 | 36 |
|
57 | 37 | # Files and objects |
58 | | -LIB_HEADERS = $(wildcard $(SRC_DIR)/*.h) $(wildcard $(SQLITE_DIR)/*.h) |
59 | | -SRC_FILES = $(filter-out $(SQLITE_DIR)/sqlite3.c $(TEST_DIR)/unittest.c $(SRC_DIR)/lz4.c, $(wildcard $(SRC_DIR)/*.c) $(wildcard $(TEST_DIR)/*.c) $(wildcard $(SQLITE_DIR)/*.c)) |
60 | | -LIB_OBJ_FILES = $(patsubst %.c, $(TARGET_PREFIX)/$(OBJ_DIR)/%.o, $(notdir $(SRC_FILES))) |
61 | | -LIB_SQLITE_OBJ = $(TARGET_PREFIX)/$(OBJ_DIR)/sqlite3.o |
| 38 | +ifeq ($(PLATFORM),windows) |
| 39 | + TEST_TARGET := $(DIST_DIR)/test.exe |
| 40 | +else |
| 41 | + TEST_TARGET := $(DIST_DIR)/test |
| 42 | +endif |
| 43 | +SRC_FILES = $(wildcard $(SRC_DIR)/*.c) |
| 44 | +TEST_FILES = $(SRC_FILES) $(wildcard $(TEST_DIR)/*.c) $(wildcard $(SQLITE_DIR)/*.c) |
| 45 | +RELEASE_OBJ = $(patsubst %.c, $(BUILD_RELEASE)/%.o, $(notdir $(SRC_FILES))) |
| 46 | +TEST_OBJ = $(patsubst %.c, $(BUILD_TEST)/%.o, $(notdir $(TEST_FILES))) |
| 47 | +COV_FILES = $(filter-out $(SRC_DIR)/lz4.c $(SRC_DIR)/network.c, $(SRC_FILES)) |
| 48 | + |
| 49 | +# Platform-specific settings |
| 50 | +ifeq ($(PLATFORM),windows) |
| 51 | + TARGET := $(DIST_DIR)/cloudsync.dll |
| 52 | + LDFLAGS += -shared |
| 53 | + # Create .def file for Windows |
| 54 | + DEF_FILE := $(BUILD_RELEASE)/cloudsync.def |
| 55 | +else ifeq ($(PLATFORM),macos) |
| 56 | + TARGET := $(DIST_DIR)/cloudsync.dylib |
| 57 | + LDFLAGS += -dynamiclib -undefined dynamic_lookup |
| 58 | + # macOS-specific flags |
| 59 | + CFLAGS += -arch x86_64 -arch arm64 |
| 60 | +else ifeq ($(PLATFORM),android) |
| 61 | + # Use Android NDK's Clang compiler, the user should set the CC |
| 62 | + # example CC=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android26-clang |
| 63 | + ifeq ($(filter %-clang,$(CC)),) |
| 64 | + $(error "CC must be set to the Android NDK's Clang compiler") |
| 65 | + endif |
| 66 | + TARGET := $(DIST_DIR)/cloudsync.so |
| 67 | + LDFLAGS += -shared -lm |
| 68 | + # Android-specific flags |
| 69 | + CFLAGS += -D__ANDROID__ |
| 70 | +else ifeq ($(PLATFORM),ios) |
| 71 | + TARGET := $(DIST_DIR)/cloudsync.dylib |
| 72 | + SDK := -isysroot $(shell xcrun --sdk iphoneos --show-sdk-path) -miphoneos-version-min=11.0 |
| 73 | + LDFLAGS += -dynamiclib $(SDK) |
| 74 | + # iOS-specific flags |
| 75 | + CFLAGS += -arch arm64 $(SDK) |
| 76 | +else ifeq ($(PLATFORM),isim) |
| 77 | + TARGET := $(DIST_DIR)/cloudsync.dylib |
| 78 | + SDK := -isysroot $(shell xcrun --sdk iphonesimulator --show-sdk-path) -miphonesimulator-version-min=11.0 |
| 79 | + LDFLAGS += -dynamiclib $(SDK) |
| 80 | + # iphonesimulator-specific flags |
| 81 | + CFLAGS += -arch x86_64 -arch arm64 $(SDK) |
| 82 | +else # linux |
| 83 | + TARGET := $(DIST_DIR)/cloudsync.so |
| 84 | + LDFLAGS += -shared |
| 85 | + CFLAGS += -lm |
| 86 | + TEST_FLAGS += -lgcov |
| 87 | +endif |
| 88 | + |
| 89 | +# Windows .def file generation |
| 90 | +$(DEF_FILE): |
| 91 | +ifeq ($(PLATFORM),windows) |
| 92 | + @echo "LIBRARY js.dll" > $@ |
| 93 | + @echo "EXPORTS" >> $@ |
| 94 | + @echo " sqlite3_js_init" >> $@ |
| 95 | + @echo " sqlitejs_version" >> $@ |
| 96 | + @echo " quickjs_version" >> $@ |
| 97 | +endif |
62 | 98 |
|
63 | | -SRC_FILES = $(filter-out $(SQLITE_DIR)/sqlite3.c $(TEST_DIR)/unittest.c $(SRC_DIR)/lz4.c, $(wildcard $(SRC_DIR)/*.c) $(wildcard $(TEST_DIR)/*.c) $(wildcard $(SQLITE_DIR)/*.c)) |
64 | | -OBJ_FILES = $(patsubst %.c, $(OBJ_DIR)/%.o, $(notdir $(SRC_FILES))) |
65 | | -LZ4_OBJ = $(OBJ_DIR)/lz4.o |
66 | | -SQLITE_OBJ = $(OBJ_DIR)/sqlite3.o |
67 | | -UNIT_TEST_OBJ = $(OBJ_DIR)/unittest.o |
68 | | -HEADERS = $(wildcard $(SRC_DIR)/*.h) $(wildcard $(TEST_DIR)/*.h) $(wildcard $(SQLITE_DIR)/*.h) |
| 99 | +# Make sure the build and dist directories exist |
| 100 | +$(shell mkdir -p $(BUILD_DIRS) $(DIST_DIR)) |
69 | 101 |
|
70 | 102 | # Default target |
71 | | -extension: $(TARGET_LOADABLE) |
72 | | -all: $(TARGET_LOADABLE) |
| 103 | +extension: $(TARGET) |
| 104 | +all: $(TARGET) |
73 | 105 |
|
74 | 106 | # Loadable library |
75 | | -$(TARGET_LOADABLE): $(LIB_OBJ_FILES) $(LIB_SQLITE_OBJ) $(LZ4_OBJ) $(TARGET_PREFIX) |
76 | | - $(CC) $(LIB_OBJ_FILES) $(LZ4_OBJ) $(LIB_SQLITE_OBJ) -o $@ $(LDFLAGS) $(DYLIB_LDFLAGS) |
77 | | - |
78 | | -# Object files for the lib (with coverage flags) |
79 | | -$(TARGET_PREFIX)/$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(LIB_HEADERS) | $(TARGET_PREFIX)/$(OBJ_DIR) |
80 | | - $(CC) $(EXTENSION_FLAGS) -c $< -o $@ |
81 | | -$(LIB_SQLITE_OBJ): $(SQLITE_DIR)/sqlite3.c $(LIB_HEADERS) | $(TARGET_PREFIX)/$(OBJ_DIR) |
82 | | - $(CC) $(EXTENSION_FLAGS) -c $< -o $@ |
83 | | - |
84 | | -# Object files (with coverage flags) |
85 | | -$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HEADERS) | $(OBJ_DIR) |
86 | | - $(CC) $(CFLAGS) -c $< -o $@ |
87 | | - |
88 | | -$(OBJ_DIR)/%.o: $(TEST_DIR)/%.c $(HEADERS) | $(OBJ_DIR) |
89 | | - $(CC) $(CFLAGS) -c $< -o $@ |
90 | | - |
91 | | -$(OBJ_DIR)/%.o: $(SQLITE_DIR)/%.c $(HEADERS) | $(OBJ_DIR) |
92 | | - $(CC) $(CFLAGS) -c $< -o $@ |
93 | | - |
94 | | -# Compile lz4.c without coverage flags |
95 | | -$(LZ4_OBJ): $(SRC_DIR)/lz4.c $(HEADERS) | $(OBJ_DIR) |
96 | | - $(CC) $(NO_COVERAGE_FLAGS) -c $< -o $@ |
97 | | - |
98 | | -# Compile sqlite3.c without coverage flags |
99 | | -$(SQLITE_OBJ): $(SQLITE_DIR)/sqlite3.c $(HEADERS) | $(OBJ_DIR) |
100 | | - $(CC) $(NO_COVERAGE_FLAGS) -DSQLITE_CORE=1 -c $< -o $@ |
101 | | - |
102 | | -# Compile unittest.c without coverage flags |
103 | | -$(UNIT_TEST_OBJ): $(TEST_DIR)/unittest.c $(HEADERS) | $(OBJ_DIR) |
104 | | - $(CC) $(CFLAGS) -c $< -o $@ |
105 | | - |
106 | | -# Create object directory if not exists |
107 | | -$(OBJ_DIR): |
108 | | - mkdir -p $(OBJ_DIR) |
109 | | -$(TARGET_PREFIX)/$(OBJ_DIR): |
110 | | - mkdir -p $(TARGET_PREFIX)/$(OBJ_DIR) |
| 107 | +$(TARGET): $(RELEASE_OBJ) $(DEF_FILE) |
| 108 | + $(CC) $(LDFLAGS) $? -o $@ |
| 109 | +ifeq ($(PLATFORM),windows) |
| 110 | + # Generate import library for Windows |
| 111 | + dlltool -D $@ -d $(DEF_FILE) -l $(DIST_DIR)/js.lib |
| 112 | +endif |
111 | 113 |
|
112 | | -$(TARGET_PREFIX): |
113 | | - mkdir -p $(TARGET_PREFIX) |
| 114 | +# Test executable |
| 115 | +$(TEST_TARGET): $(TEST_OBJ) |
| 116 | + $(CC) $(TEST_FLAGS) $? -o $@ |
114 | 117 |
|
115 | | -# Build unit test executable |
116 | | -UNIT_TEST = unittest |
117 | | -$(UNIT_TEST): CFLAGS += -DSQLITE_CORE=1 -DCLOUDSYNC_UNITTEST=1 |
118 | | -$(UNIT_TEST): $(OBJ_FILES) $(SQLITE_OBJ) $(LZ4_OBJ) $(UNIT_TEST_OBJ) |
119 | | - $(CC) $(CFLAGS) $(OBJ_FILES) $(LZ4_OBJ) $(SQLITE_OBJ) $(UNIT_TEST_OBJ) -o $@ $(LDFLAGS) |
| 118 | +# Object files |
| 119 | +$(BUILD_RELEASE)/%.o: %.c |
| 120 | + $(CC) $(EXTENSION_FLAGS) -c $< -o $@ |
| 121 | +$(BUILD_TEST)/sqlite3.o: $(SQLITE_DIR)/sqlite3.c |
| 122 | + $(CC) $(CFLAGS) -DSQLITE_CORE=1 -c $< -o $@ |
| 123 | +$(BUILD_TEST)/%.o: %.c |
| 124 | + $(CC) $(TEST_FLAGS) -c $< -o $@ |
120 | 125 |
|
121 | 126 | # Run code coverage (--css-file $(CUSTOM_CSS)) |
122 | | -coverage: $(UNIT_TEST) |
123 | | - ./$(UNIT_TEST) |
| 127 | +test: $(TARGET) $(TEST_TARGET) |
| 128 | + sqlite3 ":memory:" -cmd ".bail on" ".load ./$<" "SELECT cloudsync_version();" |
| 129 | + ./$(TEST_TARGET) |
| 130 | +ifneq ($(COVERAGE),false) |
124 | 131 | mkdir -p $(COV_DIR) |
125 | | - lcov --capture --directory . --output-file $(COV_DIR)/coverage.info |
| 132 | + lcov --capture --directory . --output-file $(COV_DIR)/coverage.info $(subst src, --include src,${COV_FILES}) |
126 | 133 | genhtml $(COV_DIR)/coverage.info --output-directory $(COV_DIR) |
| 134 | +endif |
127 | 135 |
|
128 | 136 | # Clean up generated files |
129 | 137 | clean: |
130 | | - rm -rf $(OBJ_DIR) $(UNIT_TEST) $(COV_DIR) *.gcda *.gcno *.gcov dist/* |
131 | | - |
132 | | -.PHONY: all clean coverage extension $(DEPS) |
| 138 | + rm -rf $(BUILD_DIRS) $(DIST_DIR)/* $(COV_DIR) *.gcda *.gcno *.gcov |
| 139 | + |
| 140 | +# Help message |
| 141 | +help: |
| 142 | + @echo "SQLite Sync Extension Makefile" |
| 143 | + @echo "Usage:" |
| 144 | + @echo " make [PLATFORM=platform] [target]" |
| 145 | + @echo "" |
| 146 | + @echo "Platforms:" |
| 147 | + @echo " linux (default on Linux)" |
| 148 | + @echo " macos (default on macOS)" |
| 149 | + @echo " windows (default on Windows)" |
| 150 | + @echo " android (needs CC to be set to Android NDK's Clang compiler)" |
| 151 | + @echo " ios (only on macOS)" |
| 152 | + @echo " isim (only on macOS)" |
| 153 | + @echo "" |
| 154 | + @echo "Targets:" |
| 155 | + @echo " all - Build the extension (default)" |
| 156 | + @echo " clean - Remove built files" |
| 157 | + @echo " test [COVERAGE=true] - Test the extension with optional coverage output" |
| 158 | + @echo " help - Display this help message" |
| 159 | + |
| 160 | +.PHONY: all clean test extension help |
0 commit comments