From 313110607b6f54d8b9b9d2363d63107b1a07b5e3 Mon Sep 17 00:00:00 2001 From: Philippe Boyd Date: Tue, 28 Jan 2025 17:54:22 -0500 Subject: [PATCH] feat: add osx support --- .github/workflows/ci.yml | 148 +++++++++++++++++++---------------- deps/redis/listpack_malloc.h | 16 +++- src/cli/Makefile | 21 +++-- src/ext/Makefile | 18 ++++- src/lib/Makefile | 19 ++++- test/Makefile | 25 ++++-- test/test_common.c | 2 +- test/test_common.h | 2 +- 8 files changed, 152 insertions(+), 99 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d927559..d833690 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,97 +7,111 @@ on: - cron: '0 0 * * 0' # Run every Sunday at midnight UTC jobs: - build: - runs-on: ubuntu-latest + build-linux: + strategy: + matrix: + version: + - "5.0" + - "6.0" + - "6.2" + - "7.2" + - "7.4" + - "unstable" + compiler: + - "gcc" + - "clang" + + runs-on: "ubuntu-latest" + + env: + DEBIAN_FRONTEND: noninteractive + CC: ${{ matrix.compiler }} + + # TODO: would be nice to connect to a redis server instead of building from source + # services: + # redis: + # image: redis:${{ matrix.version }} + # options: >- + # --health-cmd "redis-cli ping" + # --health-interval 10s + # --health-timeout 5s + # --health-retries 5 + steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout librdb + uses: actions/checkout@v4 with: - submodules: 'recursive' + submodules: "recursive" + + - name: Clone Redis (${{ matrix.version }}) + uses: actions/checkout@v4 + with: + repository: redis/redis + ref: ${{ matrix.version }} + path: redis - - name: Install Prerequisites and clone Redis + - name: Install prerequisites run: | sudo apt-get update - sudo apt-get install -y cmake libssl-dev valgrind git + sudo apt-get install -y cmake clang libssl-dev git bc + git clone https://git.cryptomilk.org/projects/cmocka.git cd cmocka mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local make - ctest sudo make install - git clone https://github.com/redis/redis.git ~/redis + - name: Test on redis-${{ matrix.version }} shell: bash - - - name: Test librdb vs. redis-5.0 run: | - pushd ~/redis - git checkout 5.0 - make distclean - make -j 4 -C ~/redis - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make test - working-directory: ${{github.workspace}} + make -j -C ${{ github.workspace }}/redis - - name: Test librdb vs. redis-unstable - run: | - pushd ~/redis - git checkout unstable - make -j 4 -C ~/redis - make -C ~/redis/tests/modules - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make all example valgrind + if [ $(bc -l <<< "${{ matrix.version }} >= 6.2") -eq 1 ] || [ "${{ matrix.version }}" = "unstable" ]; then + make -j -C ${{ github.workspace }}/redis/tests/modules + fi + + LIBRDB_REDIS_FOLDER="${{ github.workspace }}/redis/src" make clean debug test example working-directory: ${{github.workspace}} - build-clang: - runs-on: ubuntu-latest - env: - CC: clang + build-osx: + strategy: + matrix: + version: + - "6.2" + - "7.2" + - "7.4" + - "unstable" + + runs-on: "macos-latest" + steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout librdb + uses: actions/checkout@v4 with: submodules: 'recursive' - - name: Install Prerequisites and clone Redis - run: | - sudo apt-get update - sudo apt-get install -y cmake libssl-dev git clang - git clone https://git.cryptomilk.org/projects/cmocka.git - cd cmocka - mkdir build - cd build - cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local - make - sudo make install - - git clone https://github.com/redis/redis.git ~/redis - shell: bash + - name: Clone Redis (${{ matrix.version }}) + uses: actions/checkout@v4 + with: + repository: redis/redis + ref: ${{ matrix.version }} + path: redis - - name: Test librdb vs. redis-6.0 + - name: Install prerequisites run: | - pushd ~/redis - git checkout 6.0 - make distclean - make -j 4 -C ~/redis - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make test - working-directory: ${{github.workspace}} + brew install cmocka bc llvm grep - - name: Test librdb vs. redis-6.2 + - name: Test on redis-${{ matrix.version }} + shell: bash run: | - # clang is more strict to shared-obj versioning. Satisfy its needs. - pushd ~/redis - git checkout 6.2 - make -j 4 -C ~/redis - make -C ~/redis/tests/modules - popd - export LIBRDB_REDIS_FOLDER=~/redis/src - make clean debug test - working-directory: ${{github.workspace}} + export PATH="$(brew --prefix)/opt/grep/libexec/gnubin:${PATH}" + make -j -C ${{ github.workspace }}/redis + make -j -C ${{ github.workspace }}/redis/tests/modules + + # FIXME NOT WORKING + # LIBRDB_REDIS_FOLDER="${{ github.workspace }}/redis/src" + make clean debug test example + working-directory: ${{github.workspace}} diff --git a/deps/redis/listpack_malloc.h b/deps/redis/listpack_malloc.h index c8f96e2..4a76ccd 100644 --- a/deps/redis/listpack_malloc.h +++ b/deps/redis/listpack_malloc.h @@ -38,13 +38,21 @@ #ifndef LISTPACK_ALLOC_H #define LISTPACK_ALLOC_H -//#include "zmalloc.h" + +#ifdef __APPLE__ +#include +#else #include "malloc.h" -/* We use zmalloc_usable/zrealloc_usable instead of zmalloc/zrealloc - * to ensure the safe invocation of 'zmalloc_usable_size(). - * See comment in zmalloc_usable_size(). */ +#endif + #define lp_malloc(sz) malloc(sz) #define lp_realloc(ptr,sz) realloc(ptr,sz) #define lp_free free + +#ifdef __APPLE__ +#define lp_malloc_size malloc_size +#else #define lp_malloc_size malloc_usable_size #endif + +#endif diff --git a/src/cli/Makefile b/src/cli/Makefile index 72add76..391374b 100644 --- a/src/cli/Makefile +++ b/src/cli/Makefile @@ -1,29 +1,30 @@ default: all LIB_DIR = ../../lib -LIB_NAME = librdb.a -LIB_NAME_EXT = librdb-ext.a +LIB_NAME = rdb +LIB_NAME_EXT = $(LIB_NAME)-ext # Artifacts: -TARGET_APP = rdb-cli +TARGET_APP = rdb-cli +TARGET_LIB_STATIC_EXT = $(LIB_DIR)/lib$(LIB_NAME_EXT).a ######################################################################################### SOURCES = $(notdir $(basename $(wildcard *.c))) OBJECTS = $(patsubst %,%.o,$(SOURCES)) TARGETS = $(basename $(SOURCES)) -OPTIMIZATION?=-O3 +OPTIMIZATION ?= -O3 STD = -std=c99 STACK = -fstack-protector-all -Wstack-protector WARNS = -Wall -Wextra -pedantic -Werror CFLAGS = -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) DEBUG = -g3 -DDEBUG=1 -LIBS = -L /usr/lib -L $(LIB_DIR) -l:$(LIB_NAME_EXT) -l:$(LIB_NAME) +LIBS = -L /usr/lib -L $(LIB_DIR) -l $(LIB_NAME) -l $(LIB_NAME_EXT) ifeq ($(BUILD_TLS),yes) -CFLAGS+=-DUSE_OPENSSL=1 -LIBS+=-lssl -lcrypto + CFLAGS += -DUSE_OPENSSL=1 + LIBS += -lssl -lcrypto endif ######################################### RULES ####################################### @@ -32,12 +33,10 @@ all: $(TARGET_APP) cp $(TARGET_APP) ../../bin/ @echo "Done."; -$(TARGET_APP): %: %.c lib_dependency +$(TARGET_APP): %: %.c $(TARGET_LIB_STATIC_EXT) $(CC) $(CFLAGS) -o $@ $< $(DEBUG) $(LIBS) -lib_dependency: $(LIB_DIR)/$(LIB_NAME_EXT) - clean: @rm -rvf $(TARGETS) ./*.o ../../bin/$(TARGET_APP) -.PHONY: all clean lib_dependency \ No newline at end of file +.PHONY: all clean \ No newline at end of file diff --git a/src/ext/Makefile b/src/ext/Makefile index fc88679..b4c0eac 100644 --- a/src/ext/Makefile +++ b/src/ext/Makefile @@ -5,9 +5,9 @@ LIB_NAME_EXT = $(LIB_NAME)-ext LIB_DIR = ../../lib LIBRDB_SONAME_EXT = lib$(LIB_NAME_EXT).so.${LIBRDB_VERSION} -TARGET_LIB_STATIC = $(LIB_DIR)/lib$(LIB_NAME).a # Artifacts: TARGET_LIB_EXT = $(LIB_DIR)/$(LIBRDB_SONAME_EXT) +TARGET_LIB_STATIC = $(LIB_DIR)/lib$(LIB_NAME).a TARGET_LIB_STATIC_EXT = $(LIB_DIR)/lib$(LIB_NAME_EXT).a ######################################################################################### @@ -32,14 +32,26 @@ LDFLAGS = LIBS = -L $(LIB_DIR) -l $(LIB_NAME) ifeq ($(BUILD_TLS),yes) -CFLAGS+=-DUSE_OPENSSL=1 + CFLAGS += -DUSE_OPENSSL=1 +endif + +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +ifeq ($(uname_S),Darwin) + SONAME_FLAG = -install_name + SHARED_FLAG = -dynamiclib +else + SONAME_FLAG = -soname + SHARED_FLAG = -shared endif + ######################################### RULES ####################################### all: $(TARGET_LIB_EXT) $(TARGET_LIB_STATIC_EXT) @echo "Done."; $(TARGET_LIB_EXT): $(OBJECTS) $(REDIS_OBJECTS) - $(CC) -o $@ -shared -Wl,-soname,${LIBRDB_SONAME_EXT} ${LDFLAGS} $^ $(LIBS) + $(CC) -o $@ $(SHARED_FLAG) -Wl,$(SONAME_FLAG),${LIBRDB_SONAME_EXT} ${LDFLAGS} $^ $(LIBS) $(TARGET_LIB_STATIC_EXT): $(OBJECTS) $(REDIS_OBJECTS) ar rcs $@ $^ diff --git a/src/lib/Makefile b/src/lib/Makefile index 25e8e9f..9d7dbbe 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -1,7 +1,7 @@ default: all -LIB_NAME = rdb LIB_DIR = ../../lib +LIB_NAME = rdb LIBRDB_SONAME = lib$(LIB_NAME).so.${LIBRDB_VERSION} # Artifacts: @@ -18,8 +18,8 @@ OBJECTS = $(patsubst %,%.o,$(SOURCES)) REDIS_SOURCES = $(notdir $(basename $(wildcard ../../deps/redis/*.c))) REDIS_OBJECTS = $(patsubst %,../../deps/redis/%.o,$(REDIS_SOURCES)) -OPTIMIZATION?=-O3 -LIBRDB_DEBUG?=0 +OPTIMIZATION ?= -O3 +LIBRDB_DEBUG ?= 0 STD = -std=c99 STACK = -fstack-protector-all -Wstack-protector @@ -34,12 +34,23 @@ else CFLAGS += -DNDEBUG=1 endif +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +ifeq ($(uname_S),Darwin) + SONAME_FLAG = -install_name + SHARED_FLAG = -dynamiclib +else + SONAME_FLAG = -soname + SHARED_FLAG = -shared +endif + ######################################### RULES ####################################### all: $(TARGET_LIB) $(TARGET_LIB_STATIC) @echo "Done."; $(TARGET_LIB): $(OBJECTS) $(REDIS_OBJECTS) - $(CC) -o $@ -shared -Wl,-soname,${LIBRDB_SONAME} ${LDFLAGS} $^ + $(CC) -o $@ $(SHARED_FLAG) -Wl,$(SONAME_FLAG),${LIBRDB_SONAME} ${LDFLAGS} $^ $(TARGET_LIB_STATIC): $(OBJECTS) $(REDIS_OBJECTS) ar rcs $@ $^ diff --git a/test/Makefile b/test/Makefile index 693d9f8..8062703 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,9 +1,9 @@ default: all -LIB_NAME = rdb LIB_DIR = ../lib +LIB_NAME = rdb LIB_NAME_EXT = $(LIB_NAME)-ext -LIBHIREDIS=../deps/hiredis/libhiredis.a +LIBHIREDIS = ../deps/hiredis/libhiredis.a # Artifacts: TARGET_TEST = test_lib @@ -17,16 +17,25 @@ STD = -std=c99 STACK = -fstack-protector-all -Wstack-protector WARNS = -Wall -Wextra -pedantic -Werror -Wno-unused-function -OPTIMIZATION?=-O0 +OPTIMIZATION ?= -O0 CFLAGS = -D_DEFAULT_SOURCE -fPIC $(OPTIMIZATION) $(STD) $(STACK) $(WARNS) DEBUG = -g3 -DDEBUG=1 -LIBS = -l cmocka -L /usr/lib -L $(LIB_DIR) -l $(LIB_NAME) -l $(LIB_NAME_EXT) -l:$(LIBHIREDIS) -LIBS_STATIC = -l cmocka -L /usr/lib -L $(LIB_DIR) -l:lib$(LIB_NAME_EXT).a -l:$(LIBHIREDIS) +LIBS = -l cmocka -L /usr/lib -L $(LIB_DIR) -l $(LIB_NAME) -l $(LIB_NAME_EXT) $(LIBHIREDIS) +LIBS_STATIC = -l cmocka -L /usr/lib -L $(LIB_DIR) $(LIB_DIR)/lib$(LIB_NAME).a $(LIB_DIR)/lib$(LIB_NAME_EXT).a $(LIBHIREDIS) ifeq ($(BUILD_TLS),yes) -CFLAGS+=-DUSE_OPENSSL=1 -LIBS+=-lssl -lcrypto + CFLAGS += -DUSE_OPENSSL=1 + LIBS += -lssl -lcrypto +endif + +# Platform-specific overrides +uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') + +ifeq ($(uname_S),Darwin) + CFLAGS += -I$(shell brew --prefix)/include + LIBS += -L$(shell brew --prefix)/lib + LIBS_STATIC += -L$(shell brew --prefix)/lib endif ######################################### RULES ####################################### @@ -37,7 +46,7 @@ $(TARGET_TEST): $(OBJECTS) $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS) $(TARGET_TEST_STATIC): $(OBJECTS) - $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS) $(LIBS_STATIC) + $(CC) $(OBJECTS) -o $@ $(DEBUG) $(CFLAGS) $(LIBS_STATIC) -include $(OBJECTS:.o=.d) diff --git a/test/test_common.c b/test/test_common.c index 21443f5..1ca43b2 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -138,7 +138,7 @@ void cleanTmpFolder(void) { closedir(dir); } -void setEnvVar (const char *name, const char *val) { +void setEnvVar(const char *name, const char *val) { setenv(name, val, 1); } diff --git a/test/test_common.h b/test/test_common.h index 289a0a5..f34aa0f 100644 --- a/test/test_common.h +++ b/test/test_common.h @@ -73,7 +73,7 @@ void *xrealloc(void *ptr, size_t size); char *readFile(const char *filename, size_t *len, char *ignoredCh); void cleanTmpFolder(void); -void setEnvVar (const char *name, const char *val); +void setEnvVar(const char *name, const char *val); char *substring(char *str, size_t len, char *substr); void assert_file_payload(const char *filename, char *expData, int expLen, MatchType matchType, int expMatch);