diff --git a/.github/workflows/busted.yml b/.github/workflows/busted.yml index 3f119cb..00cefeb 100644 --- a/.github/workflows/busted.yml +++ b/.github/workflows/busted.yml @@ -7,11 +7,16 @@ jobs: strategy: fail-fast: false matrix: - lua_version: ["luajit-openresty", "luajit-2.1.0-beta3", "luajit-git"] - os: ["ubuntu-latest"] - include: - - lua_version: "5.4.4" - os: "windows-latest" + lua_version: + [ + "luajit-openresty", + "luajit-2.1.0-beta3", + "luajit-git", + "5.4.6", + "5.1.5", + "5.3.6", + ] + os: ["ubuntu-latest", "windows-latest", "macos-latest"] runs-on: ${{ matrix.os }} @@ -19,6 +24,8 @@ jobs: - name: Checkout uses: actions/checkout@v4 - uses: ilammy/msvc-dev-cmd@v1 + if: ${{ !startsWith(matrix.lua_version, 'luajit-') }} + - name: Setup ‘lua’ uses: jkl1337/gh-actions-lua@master with: @@ -31,11 +38,12 @@ jobs: luarocks install luacov-coveralls - name: Build C library run: | - luarocks make --no-install + ${{ matrix.os == 'ubuntu-latest' && 'FSANITIZE=1' || '' }} luarocks make --no-install - name: Run busted tests - run: busted -c -v + run: | + ${{ matrix.os == 'ubuntu-latest' && 'LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libasan.so.6:/usr/lib/x86_64-linux-gnu/libstdc++.so.6:/usr/lib/x86_64-linux-gnu/libubsan.so.1' || '' }} busted -c -v - name: Report test coverage - if: success() + if: success() && !startsWith(matrix.os, 'windows-') && startsWith(matrix.lua_version, 'luajit-') continue-on-error: true run: luacov-coveralls -e .luarocks -e spec env: diff --git a/Makefile b/Makefile index 8ebec7b..88ffb0d 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,19 @@ LUA_INCDIR := /usr/include SRCDIR := . -IS_CLANG = $(filter %clang++,$(CXX)) -IS_GCC = $(filter %g++,$(CXX)) +ifeq ($(OS),Windows_NT) + is_clang = $(filter %clang++,$(CXX)) + is_gcc = $(filter %g++,$(CXX)) +else + uname_s := $(shell uname -s) + ifeq ($(uname_s),Darwin) + is_clang = 1 + is_gcc = + else + is_clang = $(filter %clang++,$(CXX)) + is_gcc = $(filter %g++,$(CXX)) + endif +endif OPTFLAG := -O2 SANITIZE_FLAGS := -fsanitize=undefined -fsanitize=address -fsanitize=alignment -fsanitize=bounds-strict \ @@ -20,59 +31,59 @@ LTO_FLAGS := -flto=auto -include config.mk ifeq ($(origin LUAROCKS), command line) - CCFLAGS := $(CFLAGS) - override CFLAGS := -std=c99 $(CCFLAGS) + CCFLAGS := $(CFLAGS) + override CFLAGS := -std=c99 $(CCFLAGS) - ifneq ($(filter %gcc,$(CC)),) - CXX := $(patsubst %gcc,%g++,$(CC)) - else - ifneq ($(filter %clang,$(CC)),) - CXX := $(patsubst %clang,%clang++,$(CC)) - endif - endif + ifneq ($(filter %gcc,$(CC)),) + CXX := $(patsubst %gcc,%g++,$(CC)) + else + ifneq ($(filter %clang,$(CC)),) + CXX := $(patsubst %clang,%clang++,$(CC)) + endif + endif -luarocks: mostlyclean ljkiwi.$(LIB_EXT) +luarocks: ljkiwi.$(LIB_EXT) else - CCFLAGS += -fPIC $(OPTFLAG) - override CFLAGS += -std=c99 $(CCFLAGS) + CCFLAGS += -fPIC $(OPTFLAG) + override CFLAGS += -std=c99 $(CCFLAGS) endif CCFLAGS += -Wall -fvisibility=hidden -Wformat=2 -Wconversion -Wimplicit-fallthrough ifdef FSANITIZE - CCFLAGS += $(SANITIZE_FLAGS) + CCFLAGS += $(SANITIZE_FLAGS) endif ifndef FNOLTO - CCFLAGS += $(LTO_FLAGS) + CCFLAGS += $(LTO_FLAGS) endif -ifneq ($(IS_GCC),) - PCH := ljkiwi.hpp.gch +ifneq ($(is_gcc),) + #PCH := ljkiwi.hpp.gch else -ifneq ($(IS_CLANG),) - override CXXFLAGS += -pedantic -Wno-c99-extensions - PCH := ljkiwi.hpp.pch -endif + ifneq ($(is_clang),) + override CXXFLAGS += -pedantic -Wno-c99-extensions + #PCH := ljkiwi.hpp.pch + endif endif override CPPFLAGS += -I$(SRCDIR) -I$(SRCDIR)/kiwi -I"$(LUA_INCDIR)" override CXXFLAGS += -std=c++14 -fno-rtti $(CCFLAGS) ifeq ($(OS),Windows_NT) -override CPPFLAGS += -DLUA_BUILD_AS_DLL -override LIBFLAG += "$(LUA_LIBDIR)/$(LUALIB)" + override CPPFLAGS += -DLUA_BUILD_AS_DLL + override LIBFLAG += "$(LUA_LIBDIR)/$(LUALIB)" endif ifdef LUA -LUA_VERSION ?= $(lastword $(shell "$(LUA)" -e "print(_VERSION)")) + LUA_VERSION ?= $(lastword $(shell "$(LUA)" -e "print(_VERSION)")) endif ifndef LUA_VERSION - LJKIWI_CKIWI := 1 + LJKIWI_CKIWI := 1 else ifeq ($(LUA_VERSION),5.1) - LJKIWI_CKIWI := 1 + LJKIWI_CKIWI := 1 endif endif @@ -82,7 +93,7 @@ KIWI_LIB := AssocVector.h constraint.h debug.h errors.h expression.h kiwi.h mapt OBJS := luakiwi.o ifdef LJKIWI_CKIWI - OBJS += ckiwi.o + OBJS += ckiwi.o endif vpath %.cpp $(SRCDIR)/ckiwi $(SRCDIR)/luakiwi @@ -111,7 +122,7 @@ ljkiwi.$(LIB_EXT): $(OBJS) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -x c++-header -o $@ $< %.hpp.pch: %.hpp - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -x c++-header -o $@ $< + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ -x c++-header $< %.o: %.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< diff --git a/ckiwi/ckiwi.h b/ckiwi/ckiwi.h index 80a61e3..2b5999f 100644 --- a/ckiwi/ckiwi.h +++ b/ckiwi/ckiwi.h @@ -11,7 +11,7 @@ namespace kiwi { class VariableData; -class Constraint; +class ConstraintData; } // namespace kiwi typedef kiwi::VariableData KiwiVar; @@ -25,9 +25,10 @@ typedef struct KiwiConstraint KiwiConstraint; #endif -#if __GNUC__ - #pragma GCC visibility push(default) - #define LJKIWI_DATA_EXPORT __attribute__((visibility("default"))) +#if defined __GNUC__ && (!defined _WIN32 || defined __CYGWIN__) + #define LJKIWI_EXP __attribute__((visibility("default"))) +#elif defined _WIN32 + #define LJKIWI_EXP __declspec(dllexport) #endif // LuaJIT start @@ -75,54 +76,51 @@ typedef struct KiwiErr { struct KiwiSolver; -KiwiVar* kiwi_var_construct(const char* name); -void kiwi_var_release(KiwiVar* var); -void kiwi_var_retain(KiwiVar* var); +LJKIWI_EXP KiwiVar* kiwi_var_construct(const char* name); +LJKIWI_EXP void kiwi_var_release(KiwiVar* var); +LJKIWI_EXP void kiwi_var_retain(KiwiVar* var); -const char* kiwi_var_name(const KiwiVar* var); -void kiwi_var_set_name(KiwiVar* var, const char* name); -double kiwi_var_value(const KiwiVar* var); -void kiwi_var_set_value(KiwiVar* var, double value); +LJKIWI_EXP const char* kiwi_var_name(const KiwiVar* var); +LJKIWI_EXP void kiwi_var_set_name(KiwiVar* var, const char* name); +LJKIWI_EXP double kiwi_var_value(const KiwiVar* var); +LJKIWI_EXP void kiwi_var_set_value(KiwiVar* var, double value); -void kiwi_expression_retain(KiwiExpression* expr); -void kiwi_expression_destroy(KiwiExpression* expr); +LJKIWI_EXP void kiwi_expression_retain(KiwiExpression* expr); +LJKIWI_EXP void kiwi_expression_destroy(KiwiExpression* expr); -KiwiConstraint* kiwi_constraint_construct( +LJKIWI_EXP KiwiConstraint* kiwi_constraint_construct( const KiwiExpression* lhs, const KiwiExpression* rhs, enum KiwiRelOp op, double strength ); -void kiwi_constraint_release(KiwiConstraint* c); -void kiwi_constraint_retain(KiwiConstraint* c); +LJKIWI_EXP void kiwi_constraint_release(KiwiConstraint* c); +LJKIWI_EXP void kiwi_constraint_retain(KiwiConstraint* c); -double kiwi_constraint_strength(const KiwiConstraint* c); -enum KiwiRelOp kiwi_constraint_op(const KiwiConstraint* c); -bool kiwi_constraint_violated(const KiwiConstraint* c); -int kiwi_constraint_expression(KiwiConstraint* c, KiwiExpression* out, int out_size); +LJKIWI_EXP double kiwi_constraint_strength(const KiwiConstraint* c); +LJKIWI_EXP enum KiwiRelOp kiwi_constraint_op(const KiwiConstraint* c); +LJKIWI_EXP bool kiwi_constraint_violated(const KiwiConstraint* c); +LJKIWI_EXP int kiwi_constraint_expression(KiwiConstraint* c, KiwiExpression* out, int out_size); -KiwiSolver* kiwi_solver_construct(unsigned error_mask); -void kiwi_solver_destroy(KiwiSolver* s); -unsigned kiwi_solver_get_error_mask(const KiwiSolver* s); -void kiwi_solver_set_error_mask(KiwiSolver* s, unsigned mask); +LJKIWI_EXP KiwiSolver* kiwi_solver_construct(unsigned error_mask); +LJKIWI_EXP void kiwi_solver_destroy(KiwiSolver* s); +LJKIWI_EXP unsigned kiwi_solver_get_error_mask(const KiwiSolver* s); +LJKIWI_EXP void kiwi_solver_set_error_mask(KiwiSolver* s, unsigned mask); -const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* s, KiwiConstraint* constraint); -const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* s, KiwiConstraint* constraint); -bool kiwi_solver_has_constraint(const KiwiSolver* s, KiwiConstraint* constraint); -const KiwiErr* kiwi_solver_add_edit_var(KiwiSolver* s, KiwiVar* var, double strength); -const KiwiErr* kiwi_solver_remove_edit_var(KiwiSolver* s, KiwiVar* var); -bool kiwi_solver_has_edit_var(const KiwiSolver* s, KiwiVar* var); -const KiwiErr* kiwi_solver_suggest_value(KiwiSolver* s, KiwiVar* var, double value); -void kiwi_solver_update_vars(KiwiSolver* sp); -void kiwi_solver_reset(KiwiSolver* sp); -void kiwi_solver_dump(const KiwiSolver* sp); -char* kiwi_solver_dumps(const KiwiSolver* sp); +LJKIWI_EXP const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* s, KiwiConstraint* constraint); +LJKIWI_EXP const KiwiErr* +kiwi_solver_remove_constraint(KiwiSolver* s, KiwiConstraint* constraint); +LJKIWI_EXP bool kiwi_solver_has_constraint(const KiwiSolver* s, KiwiConstraint* constraint); +LJKIWI_EXP const KiwiErr* kiwi_solver_add_edit_var(KiwiSolver* s, KiwiVar* var, double strength); +LJKIWI_EXP const KiwiErr* kiwi_solver_remove_edit_var(KiwiSolver* s, KiwiVar* var); +LJKIWI_EXP bool kiwi_solver_has_edit_var(const KiwiSolver* s, KiwiVar* var); +LJKIWI_EXP const KiwiErr* kiwi_solver_suggest_value(KiwiSolver* s, KiwiVar* var, double value); +LJKIWI_EXP void kiwi_solver_update_vars(KiwiSolver* sp); +LJKIWI_EXP void kiwi_solver_reset(KiwiSolver* sp); +LJKIWI_EXP void kiwi_solver_dump(const KiwiSolver* sp); +LJKIWI_EXP char* kiwi_solver_dumps(const KiwiSolver* sp); // LuaJIT end -#if __GNUC__ - #pragma GCC visibility pop -#endif - #ifdef __cplusplus } // extern "C" #endif