diff --git a/.github/workflows/busted.yml b/.github/workflows/busted.yml index ae8e397..3f119cb 100644 --- a/.github/workflows/busted.yml +++ b/.github/workflows/busted.yml @@ -8,12 +8,17 @@ jobs: 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" - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v4 + - uses: ilammy/msvc-dev-cmd@v1 - name: Setup ‘lua’ uses: jkl1337/gh-actions-lua@master with: diff --git a/.gitignore b/.gitignore index 98b74ee..0aecd58 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,14 @@ /lua /lua_modules /.luarocks +/config.mk *.pch *.gch +*.lib *.so *.o +*.obj +*.exp +*.dll .cache/ compile_commands.json diff --git a/Makefile b/Makefile index b1a3035..8ebec7b 100644 --- a/Makefile +++ b/Makefile @@ -1,61 +1,88 @@ --include config.mk - -CC := $(CROSS)gcc +CXX := $(CROSS)g++ CP := cp RM := rm LIBFLAG := -shared -LIB_EXT := so +LIB_EXT := $(if $(filter Windows_NT,$(OS)),dll,so) LUA_INCDIR := /usr/include SRCDIR := . -OPTFLAG := -O2 -CCFLAGS += $(OPTFLAG) -fPIC -Wall -fvisibility=hidden -Wformat=2 -Wconversion -Wimplicit-fallthrough +IS_CLANG = $(filter %clang++,$(CXX)) +IS_GCC = $(filter %g++,$(CXX)) + +OPTFLAG := -O2 +SANITIZE_FLAGS := -fsanitize=undefined -fsanitize=address -fsanitize=alignment -fsanitize=bounds-strict \ + -fsanitize=shift -fsanitize=unreachable -fsanitize=bool \ + -fsanitize=enum -SANITIZE_FLAGS := -fstrict-flex-arrays -fsanitize=undefined -fsanitize=address LTO_FLAGS := -flto=auto -ifdef SANITIZE +-include config.mk + +ifeq ($(origin LUAROCKS), command line) + 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 + +luarocks: mostlyclean ljkiwi.$(LIB_EXT) + +else + CCFLAGS += -fPIC $(OPTFLAG) + override CFLAGS += -std=c99 $(CCFLAGS) +endif + +CCFLAGS += -Wall -fvisibility=hidden -Wformat=2 -Wconversion -Wimplicit-fallthrough + +ifdef FSANITIZE CCFLAGS += $(SANITIZE_FLAGS) endif -ifdef LTO +ifndef FNOLTO CCFLAGS += $(LTO_FLAGS) endif -override CPPFLAGS += -I$(SRCDIR) -I$(SRCDIR)/kiwi -I$(LUA_INCDIR) -override CXXFLAGS += -std=c++14 -fno-rtti $(CCFLAGS) -override CFLAGS += -std=c99 $(CCFLAGS) - -ifneq ($(filter %gcc,$(CC)),) - CXX := $(patsubst %gcc,%g++,$(CC)) - PCH := ljkiwi.hpp.gch +ifneq ($(IS_GCC),) + PCH := ljkiwi.hpp.gch else - ifneq ($(filter %clang,$(CC)),) - CXX := $(patsubst %clang,%clang++,$(CC)) - override CXXFLAGS += -pedantic -Wno-c99-extensions - PCH := ljkiwi.hpp.pch +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)" +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 - endif +ifeq ($(LUA_VERSION),5.1) + LJKIWI_CKIWI := 1 +endif endif KIWI_LIB := AssocVector.h constraint.h debug.h errors.h expression.h kiwi.h maptype.h \ - row.h shareddata.h solver.h solverimpl.h strength.h symbol.h symbolics.h term.h \ - util.h variable.h version.h + row.h shareddata.h solver.h solverimpl.h strength.h symbol.h symbolics.h term.h \ + util.h variable.h version.h OBJS := luakiwi.o ifdef LJKIWI_CKIWI - OBJS += ckiwi.o + OBJS += ckiwi.o endif vpath %.cpp $(SRCDIR)/ckiwi $(SRCDIR)/luakiwi @@ -67,13 +94,15 @@ install: $(CP) -f ljkiwi.$(LIB_EXT) $(INST_LIBDIR)/ljkiwi.$(LIB_EXT) $(CP) -f kiwi.lua $(INST_LUADIR)/kiwi.lua -clean: - $(RM) -f ljkiwi.$(LIB_EXT) $(OBJS) $(PCH) +mostlyclean: + $(RM) -f ljkiwi.$(LIB_EXT) $(OBJS) +clean: mostlyclean + $(RM) -f $(PCH) -ljkiwi.hpp.gch: $(KIWI_LIB) ckiwi.o: $(PCH) ckiwi.cpp ckiwi.h $(KIWI_LIB) luakiwi.o: $(PCH) luakiwi-int.h luacompat.h $(KIWI_LIB) +$(PCH): $(KIWI_LIB) ljkiwi.$(LIB_EXT): $(OBJS) $(CXX) $(CCFLAGS) $(LIBFLAG) -o $@ $(OBJS) @@ -84,10 +113,7 @@ ljkiwi.$(LIB_EXT): $(OBJS) %.hpp.pch: %.hpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -x c++-header -o $@ $< -%.o: %.c - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< - %.o: %.cpp $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $< -.PHONY: all install clean +.PHONY: all install clean mostlyclean diff --git a/Makefile.win b/Makefile.win new file mode 100644 index 0000000..1f19116 --- /dev/null +++ b/Makefile.win @@ -0,0 +1,21 @@ +T= ljkiwi + +OBJS= luakiwi.obj + +lib: $T.dll + +{luakiwi\}.cpp.obj: + $(CC) $(CFLAGS) /W4 /wd4200 /c /D_CRT_SECURE_NO_DEPRECATE /I. /I kiwi /I"$(LUA_INCDIR)" /EHs /Fo$@ $(CFLAGS) $< + +$T.dll: $(OBJS) + link $(LIBFLAG) /out:$T.dll "$(LUA_LIBDIR)\$(LUALIB)" $(OBJS) + IF EXIST $T.dll.manifest mt -manifest $T.dll.manifest -outputresource:$T.dll;2 + +install: $T.dll + IF NOT EXIST "$(INST_LIBDIR)" mkdir "$(INST_LIBDIR)" + copy $T.dll "$(INST_LIBDIR)" + copy kiwi.lua "$(INST_LUADIR)" + +clean: + del $T.dll $(OBJS) $T.lib $T.exp + IF EXIST $T.dll.manifest del $T.dll.manifest diff --git a/kiwi-scm-1.rockspec b/kiwi-scm-1.rockspec index 749b688..d23a409 100644 --- a/kiwi-scm-1.rockspec +++ b/kiwi-scm-1.rockspec @@ -21,9 +21,12 @@ dependencies = { build = { type = "make", build_variables = { + LUAROCKS = "1", LUA = "$(LUA)", CFLAGS = "$(CFLAGS)", LUA_INCDIR = "$(LUA_INCDIR)", + LUA_LIBDIR = "$(LUA_LIBDIR)", + LUALIB = "$(LUALIB)", LIBFLAG = "$(LIBFLAG)", LIB_EXT = "$(LIB_EXTENSION)", OBJ_EXT = "$(OBJ_EXTENSION)", diff --git a/luakiwi/luakiwi-int.h b/luakiwi/luakiwi-int.h index 09adfcd..e477b5a 100644 --- a/luakiwi/luakiwi-int.h +++ b/luakiwi/luakiwi-int.h @@ -92,13 +92,15 @@ struct KiwiExpression { KiwiTerm terms[]; static constexpr std::size_t sz(int count) { - return sizeof(KiwiExpression) + sizeof(KiwiTerm) * (count > 0 ? count : 0); + return sizeof(KiwiExpression) + + sizeof(KiwiTerm) * static_cast(count > 0 ? count : 0); } #else KiwiTerm terms[1]; static constexpr std::size_t sz(int count) { - return sizeof(KiwiExpression) + sizeof(KiwiTerm) * (count > 1 ? count - 1 : 0); + return sizeof(KiwiExpression) + + sizeof(KiwiTerm) * static_cast(count > 0 ? count : 0); } #endif diff --git a/luakiwi/luakiwi.cpp b/luakiwi/luakiwi.cpp index 198b966..b84c02b 100644 --- a/luakiwi/luakiwi.cpp +++ b/luakiwi/luakiwi.cpp @@ -1607,6 +1607,8 @@ void compat_init(lua_State*, int) {} #if defined __GNUC__ && (!defined _WIN32 || defined __CYGWIN__) #define LJKIWI_EXPORT __attribute__((__visibility__("default"))) +#elif defined _WIN32 + #define LJKIWI_EXPORT __declspec(dllexport) #endif extern "C" LJKIWI_EXPORT int luaopen_ljkiwi(lua_State* L) {