diff --git a/Makefile b/Makefile deleted file mode 100644 index 2bb3fba..0000000 --- a/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# set the binaries that have to be built - -#SRCS := $(wildcard apps/mnist/*.cpp) -SRCS := ${SRCS} $(wildcard tests/*.cpp) - -TARGETS := $(TARGETS) $(SRCS:.cpp=) - -# set the build configuration set -BUILD := release -#BUILD := debug -BIT := 64 -#BIT := 32 - -# set bin and build dirs -BUILDDIR := .build_$(BUILD)$(BIT) -BINDIR := $(BUILD)$(BIT) - -# include directories -INCLUDEDIRS := \ - src -# library directories -LIBDIRS := - -# set which libraries are used by which executable -LDLIBS = $(addprefix -l, $(LIBS) $(LIBS_$(notdir $*))) -LIBS = -#LIBS = pthread - -# set some flags and compiler/linker specific commands -CXXFLAGS = -m$(BIT) -pipe -D STD=std -Wall $(CXXFLAGS_$(BUILD)) $(addprefix -I, $(INCLUDEDIRS)) -CXXFLAGS_debug := -ggdb -std=c++1z -CXXFLAGS_release := -std=c++1z -O3 -DNDEBUG -LDFLAGS = -m$(BIT) -pipe -Wall $(LDFLAGS_$(BUILD)) $(addprefix -L, $(LIBDIRS)) -LDFLAGS_debug := -ggdb -LDFLAGS_release := -O3 - -# we set specific compilers for specific tools -CXX = $(if $(CXX_$(notdir $*)), $(CXX_$(notdir $*)), g++) - -include ./make/generic.mk diff --git a/docs/build.md b/docs/build.md new file mode 100644 index 0000000..53cd5c9 --- /dev/null +++ b/docs/build.md @@ -0,0 +1,20 @@ +# Overview of the build system +`datalog-cpp` uses the [CMake](www.cmake.org) build tool to generate build files for other build systems. Currently, building using clang and gcc with Makefiles are supported. + +# Building with Makefiles +From the command line inside a git clone, run the following: +``` +mkdir build +cd build +cmake ../src +make +``` +# Building directly with CMake in Visual Studio 2019 +Visual Studio 2019 supports using CMake to manage the build directly by selecting File -> Open -> Cmake... and opening `src/CMakeLists.txt`. Then Visual Studio's normal build shortcuts will update the CMake configuration as well as building the project. + +CMake options are configured using the `CMakeSettings.json` file, which Visual Studio will generate when `CMakeLists.txt` is opened. + +# Build options +Additional configuration variables can be provided in the `cmake` invocation. + +For Makefile builds, a build type can be specified by passing `-DCMAKE_BUILD_TYPE=Debug`, `-DCMAKE_BUILD_TYPE=MinSizeRel`, `-DCMAKE_BUILD_TYPE=Release`, or `-DCMAKE_BUILD_TYPE=RelWithDebInfo`. By default, Makefile builds will use `RelWithDebInfo`. diff --git a/make/dep.py b/make/dep.py deleted file mode 100755 index 4ac7090..0000000 --- a/make/dep.py +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2009 Alexander Kl"aser -# -# This piece is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# This software has been downloaded from: -# http://lear.inrialpes.fr/people/klaeser/software -# - -import sys -import os -import string -import os.path -import re - -HELP_USAGE = """ -Usage: dep.py ... -""" - -regSuffix = re.compile(r"\.[^.]*$") -regSrc = re.compile(r"^.*\.(c|cc|cpp)$") -regDep = re.compile(r"^.*\.d$") -regDepSplit = re.compile(r"\s*\\*\s*") - -suffixes = ['.cpp', '.c', '.cc'] -includeDirs = [] - - -def parseDepFile(fileName): - # read in the dependency file - depFile = open(fileName, 'r') - depStr = depFile.read() - - # discard everything up to the colon - colonPos = depStr.find(":") - assert colonPos > 0, "the dependency file '" + fileName + "' does not have the correct format" - depStr = depStr[colonPos + 1:] - - # collect all included files - return regDepSplit.split(depStr) - - -def findSourceFile(headerFile): - # get the basename without extension - headerFile = regSuffix.sub('', headerFile) - if not headerFile: - return None - - # iterate over known suffixes - for suffix in suffixes: - srcFile = headerFile + suffix - - # check whether a source file corresponding to the header exists - if os.path.exists(srcFile): - return srcFile - - # we add to the file path directory by directory and check whether it - # exists in one of the include directories - i = headerFile.find('/') + 1 - if i != 1: - i = 0 - while True: - # check whether a source file exists in one of the given include dirs - for dir in includeDirs: - # check all suffixes for source files - for suffix in suffixes: - srcFile = os.path.join(dir, headerFile[i:] + suffix) - if os.path.exists(srcFile): - return srcFile - - # find next position of '/' - i = headerFile.find('/', i) + 1 - if i <= 0: - break - - return None - - -def main(argv): - global includeDirs - - # check command line parameters - if len(sys.argv) < 5: - print HELP_USAGE - return - - args = sys.argv - args.pop(0) - ruleTarget = args.pop(0) - linkFile = args.pop(0) - buildDir = args.pop(0) - rootDepFile = args.pop(0) - includeDirs = args - - - # scan all dependency files for files we need to link to - # do this recursively starting at the root dependency file - linkFiles = set() - incFiles = set() - depFileStack = set([rootDepFile]) - depFilesDone = set() - while depFileStack: - # get the next dependency file to process from the stack - depFile = depFileStack.pop() - if depFile in depFilesDone: - continue - depFilesDone.add(depFile) - - # iterate over all source files in the dependency file - for nextFile in parseDepFile(depFile): - newDepFile = "" - - # if we have a source file, we need to link against it - if regSrc.match(nextFile): - linkFiles.add(nextFile) - newDepFile = buildDir + "/" + regSuffix.sub(".d", nextFile) - - # check whether a .cpp/.c/.cc file exist - srcFile = findSourceFile(nextFile) - if srcFile != None: - linkFiles.add(srcFile) - newDepFile = buildDir + "/" + regSuffix.sub(".d", srcFile) - - # if the corresponding .d file exists as parameter, add it to the stack - if newDepFile and os.path.exists(newDepFile): - depFileStack.add(newDepFile) - - # - # generate all necessary rules - # - - # all includes of dependency files - for i in linkFiles: - i = regSuffix.sub(".d", i) - print "-include " + buildDir + "/" + i - print - - # dependencies for link file - print linkFile + ": \\" - for i in linkFiles: - i = regSuffix.sub(".d", i) - print "\t" + buildDir + "/" + i + " \\" - print - - # print out all files we need to link against - print ruleTarget + ": " + linkFile + " \\" - for i in linkFiles: - i = regSuffix.sub(".o", i) - print "\t" + buildDir + "/" + i + " \\" - print - - -if __name__ == "__main__": - main( sys.argv ) - - diff --git a/make/generic.mk b/make/generic.mk deleted file mode 100644 index 8273893..0000000 --- a/make/generic.mk +++ /dev/null @@ -1,115 +0,0 @@ -# -# Copyright (C) 2009 Alexander Kl"aser -# -# This piece is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# This software has been downloaded from: -# http://lear.inrialpes.fr/people/klaeser/software -# -# -# Variables that need to be set in the Makefile that includes this file: -# TARGETS all files that are exectuables without there .cpp extension -# BUILDDIR temporary dir where things are compiled to (optional, by default ".build") -# BINDIR dir where executables are linked to (optional, by default "bin") -# SRCDIRS list of directories in which source files are located -# this variable needs to be set if you do not have your source and -# include files located in the same directory! -# -# Variables used for compiling/linking: -# CXXFLAGS flags for compiling -# LDFLAGS flags used for linking -# LDLIBS list of libraries to be linked -# CXX compiler linker (should be g++ by default) -# - -# set paths for the dependency tool and gcc -DEP = ./make/dep.py - -# set some standard directories in case they have not been set -BUILDDIR ?= .build -BINDIR ?= bin - -# all include files -INCLUDES := $(addprefix $(BUILDDIR)/,$(TARGETS:=.l)) - - -# -# some general rules -# - -.PHONY: all clean -.PRECIOUS: $(BUILDDIR)/%.d - -all: $(BINDIR) $(addprefix $(BINDIR)/,$(notdir $(TARGETS))) - @echo "=== done ===" - -$(INCLUDES): $(BUILDDIR) - -clean: - @echo "=== cleaning up ===" - @rm -rf $(BUILDDIR) - -$(BUILDDIR) $(BINDIR): - @echo "=== creating directory: $@ ===" - @mkdir -p $@ - - -# -# rules for creating dependency files -# - -# dependencies of .cpp files on other files -$(BUILDDIR)/%.d: %.cpp - @echo "=== creating dependency file: $@ ===" - @test -e $(dir $@) || mkdir -p $(dir $@) - g++ $(CXXFLAGS) -MM -MT $(BUILDDIR)/$*.o -MT $(BUILDDIR)/$*.d -MF $@ $< - -# dependencies for the linking -%.l: %.d - @echo "=== creating dependency file: $@ ===" - @test -e $(dir $@) || mkdir -p $(dir $@) - $(DEP) "$(BINDIR)/$(*F)" $@ $(BUILDDIR) $< $(SRCDIRS) > $@ - - -# -# rules for compiling and linking -# - -# compiling -$(BUILDDIR)/%.o: %.cpp - @echo "=== compiling: $@ ===" - @test -e $(dir $@) || mkdir -p $(dir $@) - $(CXX) $(CXXFLAGS) -c -o $@ $< - -# linking .. link dependencies are defined in the .l files -$(BINDIR)/%: - @echo "=== linking: $@ ===" - @rm -f $@ - $(CXX) $(LDFLAGS) -o $@ $(filter %.o, $^) $(LDLIBS) - -%: %.o -%.h: ; -%.hpp: ; -%.c: ; -%.cpp: ; - - -# -# include dependency files -# - -ifneq ($(MAKECMDGOALS),clean) --include $(INCLUDES) -endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..9644bfe --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,27 @@ +# CMakeLists.txt + +# CMake setup +cmake_minimum_required (VERSION 3.8) + +# Set a default build type if none was specified +set(default_build_type "RelWithDebInfo") + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE + STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +# Project initialisation +project("datalog-cpp") + +# specify the C++ standard +set(CMAKE_CXX_STANDARD 17) + +# types_test target +add_executable(types_test ../tests/types_test.cpp) +target_include_directories(types_test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_compile_definitions(types_test PUBLIC UNIX) diff --git a/src/Datalog.h b/src/Datalog.h index 8490104..c537100 100644 --- a/src/Datalog.h +++ b/src/Datalog.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "tuple_hash.h" #include "Variable.h" @@ -18,6 +19,56 @@ namespace datalog using namespace std; +template +Variable *var() +{ + return new Variable(); +} + +template +T val(Variable *t) +{ + return t->value(); +} + +template +void deleteVar(Variable *v) +{ + delete v; +} + +template +void unbind(Variable *t) +{ + t->unbind(); +} + +template +void unbind(const T &t) {} + +template +void unbind(const tuple &tuple) +{ + apply([](auto &&... args) { ((unbind(args), ...)); }, tuple); +} + +template +bool bind(const T &a, const T &b) +{ + return a == b; +} + +template +bool bind(const T &a, Variable *const b) +{ + if (b->isBound()) + { + return b->value() == a; + } + b->bind(a); + return true; +} + template bool bind(const GROUND_TYPE &fact, const tuple &atom, index_sequence) { diff --git a/src/Variable.h b/src/Variable.h index fa781bd..1dabf54 100644 --- a/src/Variable.h +++ b/src/Variable.h @@ -1,7 +1,7 @@ #ifndef VARIABLE_H #define VARIABLE_H -#include +#include namespace datalog { @@ -56,56 +56,6 @@ struct Variable : optional } }; -template -Variable *var() -{ - return new Variable(); -} - -template -T val(Variable *t) -{ - return t->value(); -} - -template -void deleteVar(Variable *v) -{ - delete v; -} - -template -void unbind(Variable *t) -{ - t->unbind(); -} - -template -void unbind(const T &t) {} - -template -void unbind(const tuple &tuple) -{ - apply([](auto &&... args) { ((unbind(args), ...)); }, tuple); -} - -template -bool bind(const T &a, const T &b) -{ - return a == b; -} - -template -bool bind(const T &a, Variable *const b) -{ - if (b->isBound()) - { - return b->value() == a; - } - b->bind(a); - return true; -} - } // namespace datalog #endif \ No newline at end of file