From 0504fee0a3cea5bc005ae6407d3e385cfebf0035 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Thu, 18 Jun 2020 17:54:49 +0200 Subject: [PATCH 01/21] extract cmake configuration & build to a separate package --- test/cmake/cmake.go | 140 ++++++++++++++++++++++++++++++++++++ test/comparison/c-helper.go | 84 ++++++---------------- 2 files changed, 161 insertions(+), 63 deletions(-) create mode 100644 test/cmake/cmake.go diff --git a/test/cmake/cmake.go b/test/cmake/cmake.go new file mode 100644 index 00000000..3326d2d4 --- /dev/null +++ b/test/cmake/cmake.go @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2020 ObjectBox Ltd. All rights reserved. + * https://objectbox.io + * + * This file is part of ObjectBox Generator. + * + * ObjectBox Generator 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 3 of the License, or + * (at your option) any later version. + * ObjectBox Generator 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 ObjectBox Generator. If not, see . + */ + +// package cmake provides tools to create, configure and build C & C++ projects using CMake +package cmake + +import ( + "bufio" + "errors" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "text/template" +) + +type Cmake struct { + // Configs required for CMakeLists.txt + Name string // Executable name + IsCpp bool + Standard int // CMAKE_C/CXX_STANDARD + Files []string + IncludeDirs []string + LinkLibs []string // Library names or full paths + LinkDirs []string // Where should the linker look for libraries + + // Build configuration + SourceDir string + ConfDir string + BuildDir string + + tempRoot string +} + +// CreateCmake creates new cmake configuration. +// If useTempDirs is true, ConfDir and BuildDir are created as temporary directory +func CreateCmake(name, sourceDir string, useTempDirs bool) (Cmake, error) { + var cmake = Cmake{ + Name: name, + SourceDir: sourceDir, + } + + if useTempDirs { + var err error + if cmake.tempRoot, err = ioutil.TempDir("", name+"cmake"); err != nil { + return cmake, err + } + + cmake.BuildDir = filepath.Join(cmake.tempRoot, "build") + cmake.ConfDir = filepath.Join(cmake.tempRoot, "conf") + if err = os.Mkdir(cmake.BuildDir, 0700); err != nil { + os.RemoveAll(cmake.tempRoot) + return cmake, err + } + if err = os.Mkdir(cmake.ConfDir, 0700); err != nil { + os.RemoveAll(cmake.tempRoot) + return cmake, err + } + } + + return cmake, nil +} + +func (cmake *Cmake) RemoveTempDirs() error { + if len(cmake.tempRoot) == 0 { + return errors.New("temp dirs were not used") + } + return os.RemoveAll(cmake.tempRoot) +} + +// WriteCMakeListsTxt writes cmake specification to file and returns the file name. +func (cmake *Cmake) WriteCMakeListsTxt() error { + // open the file, overwrite if it exists + file, err := os.OpenFile(filepath.Join(cmake.ConfDir, "CMakeLists.txt"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + defer file.Close() + + writer := bufio.NewWriter(file) + if err := cmakeListsTpl.Execute(writer, cmake); err != nil { + return err + } + + return writer.Flush() +} + +var cmakeListsTpl = template.Must(template.New("CMakeLists.txt"). + Funcs(template.FuncMap{ + "Join": func(ss []string) string { + return strings.Join(ss, " ") + }, + }). + Parse(` +cmake_minimum_required(VERSION 3.0) +set(CMAKE_C{{if .IsCpp}}XX{{end}}_STANDARD {{.Standard}}) +project({{.Name}} C{{if .IsCpp}}XX{{end}}) + +add_executable(${PROJECT_NAME} {{Join .Files}}) +{{if .IncludeDirs}}target_include_directories(${PROJECT_NAME} PRIVATE {{Join .IncludeDirs}}){{end}} +{{if .LinkLibs}}target_link_libraries(${PROJECT_NAME} {{Join .LinkLibs}}){{end}} +{{if .LinkDirs}}target_link_directories(${PROJECT_NAME} {{Join .LinkDirs}}){{end}} +`)) + +// Configure runs cmake configuration step. +func (cmake *Cmake) Configure() ([]byte, []byte, error) { + return cmakeExec(cmake.BuildDir, cmake.ConfDir) +} + +// Configure runs cmake build step. +func (cmake *Cmake) Build() ([]byte, []byte, error) { + return cmakeExec(cmake.SourceDir, "--build", cmake.BuildDir) +} + +func cmakeExec(cwd string, args ...string) (stdOut []byte, stdErr []byte, err error) { + var cmd = exec.Command("cmake", args...) + cmd.Dir = cwd + stdOut, err = cmd.Output() + if ee, ok := err.(*exec.ExitError); ok { + stdErr = ee.Stderr + } + return +} diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index efeb87d7..c22c1303 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -20,35 +20,17 @@ package comparison import ( - "bufio" - "bytes" "io/ioutil" - "os" - "os/exec" "path" "path/filepath" "testing" - "text/template" "github.com/objectbox/objectbox-generator/internal/generator" cgenerator "github.com/objectbox/objectbox-generator/internal/generator/c" "github.com/objectbox/objectbox-generator/test/assert" + "github.com/objectbox/objectbox-generator/test/cmake" ) -var cmakeListsTpl = template.Must(template.New("cmake").Parse(` -cmake_minimum_required(VERSION 3.0) -{{if .Cpp}} -set(CMAKE_CXX_STANDARD 11) -{{else}} -set(CMAKE_C_STANDARD 99) -{{end}} -project(compilation-test {{if not .Cpp}}C{{end}}) - -add_executable(${PROJECT_NAME} {{.Main}}) -target_include_directories(${PROJECT_NAME} PRIVATE {{.Include}}) -target_link_libraries(${PROJECT_NAME} objectbox) -`)) - type cTestHelper struct { cpp bool } @@ -68,34 +50,25 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro includeDir, err := filepath.Abs(dir) // main.c/cpp will include generated headers from here assert.NoErr(t, err) - tempRoot, err := ioutil.TempDir("", "objectbox-generator-test-build") + build, err := cmake.CreateCmake("compilation-test", includeDir, true) assert.NoErr(t, err) - defer os.RemoveAll(tempRoot) - - buildDir := path.Join(tempRoot, "build") - cmakeConfDir := path.Join(tempRoot, "conf") // using "conf" dir to write CMakeLists.txt and main.c/cpp - assert.NoErr(t, os.Mkdir(buildDir, 0700)) - assert.NoErr(t, os.Mkdir(cmakeConfDir, 0700)) + defer build.RemoveTempDirs() - mainFile := path.Join(cmakeConfDir, "main.c") + var mainFile string if h.cpp { - mainFile = path.Join(cmakeConfDir, "main.cpp") + build.IsCpp = true + build.Standard = 11 + mainFile = path.Join(build.ConfDir, "main.cpp") + } else { + build.Standard = 99 + mainFile = path.Join(build.ConfDir, "main.c") } - { // write CMakeLists.txt to the conf dir - var tplArguments = struct { - Cpp bool - Ext string - Include string - Main string - }{h.cpp, conf.generatedExt, includeDir, mainFile} + build.Files = append(build.Files, mainFile) + build.LinkLibs = append(build.LinkLibs, "objectbox") + build.IncludeDirs = append(build.IncludeDirs, includeDir) - var b bytes.Buffer - writer := bufio.NewWriter(&b) - assert.NoErr(t, cmakeListsTpl.Execute(writer, tplArguments)) - assert.NoErr(t, writer.Flush()) - assert.NoErr(t, ioutil.WriteFile(path.Join(cmakeConfDir, "CMakeLists.txt"), b.Bytes(), 0600)) - } + assert.NoErr(t, build.WriteCMakeListsTxt()) { // write main.c/cpp to the conf dir - a simple one, just include all sources var mainSrc = "" @@ -111,31 +84,16 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro assert.NoErr(t, ioutil.WriteFile(mainFile, []byte(mainSrc), 0600)) } - // configure the cmake project - stdOut, stdErr, err := cmake(buildDir, cmakeConfDir) - if err != nil { - assert.Failf(t, "cmake build configuration failed: \n%s\n%s\n%s", stdOut, stdErr, err) - } - if testing.Verbose() { + if stdOut, stdErr, err := build.Configure(); err != nil { + assert.Failf(t, "cmake configuration failed: \n%s\n%s\n%s", stdOut, stdErr, err) + } else if testing.Verbose() { t.Logf("configuration output:\n%s", string(stdOut)) } - // build the code - stdOut, stdErr, err = cmake(includeDir, "--build", buildDir) - - checkBuildError(t, errorTransformer, stdOut, stdErr, err, expectedError) - - if testing.Verbose() { + if stdOut, stdErr, err := build.Build(); err != nil { + checkBuildError(t, errorTransformer, stdOut, stdErr, err, expectedError) + assert.Failf(t, "cmake build failed: \n%s\n%s\n%s", stdOut, stdErr, err) + } else if testing.Verbose() { t.Logf("build output:\n%s", string(stdOut)) } } - -func cmake(cwd string, args ...string) (stdOut []byte, stdErr []byte, err error) { - var cmd = exec.Command("cmake", args...) - cmd.Dir = cwd - stdOut, err = cmd.Output() - if ee, ok := err.(*exec.ExitError); ok { - stdErr = ee.Stderr - } - return -} From 2e44d201bdab92ce2b693acdcdde356811cf6ecb Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Fri, 19 Jun 2020 08:49:03 +0200 Subject: [PATCH 02/21] add libcheck utility --- test/cmake/cmake.go | 60 +++++++++++++++++++------------- test/cmake/libcheck.go | 68 +++++++++++++++++++++++++++++++++++++ test/cmake/libcheck_test.go | 41 ++++++++++++++++++++++ test/comparison/c-helper.go | 18 +++++----- 4 files changed, 155 insertions(+), 32 deletions(-) create mode 100644 test/cmake/libcheck.go create mode 100644 test/cmake/libcheck_test.go diff --git a/test/cmake/cmake.go b/test/cmake/cmake.go index 3326d2d4..dff50d66 100644 --- a/test/cmake/cmake.go +++ b/test/cmake/cmake.go @@ -31,6 +31,7 @@ import ( "text/template" ) +// Cmake contains all configuration necessary to configure and build a CMake project type Cmake struct { // Configs required for CMakeLists.txt Name string // Executable name @@ -49,38 +50,49 @@ type Cmake struct { tempRoot string } -// CreateCmake creates new cmake configuration. -// If useTempDirs is true, ConfDir and BuildDir are created as temporary directory -func CreateCmake(name, sourceDir string, useTempDirs bool) (Cmake, error) { - var cmake = Cmake{ - Name: name, - SourceDir: sourceDir, +// CreateTempDirs creates temporary directories for conf and build dir +func (cmake *Cmake) CreateTempDirs() error { + if len(cmake.tempRoot) != 0 { + return errors.New("temp root is already set") } - if useTempDirs { - var err error - if cmake.tempRoot, err = ioutil.TempDir("", name+"cmake"); err != nil { - return cmake, err - } + tempRoot, err := ioutil.TempDir("", cmake.Name+"cmake") + if err != nil { + return err + } - cmake.BuildDir = filepath.Join(cmake.tempRoot, "build") - cmake.ConfDir = filepath.Join(cmake.tempRoot, "conf") - if err = os.Mkdir(cmake.BuildDir, 0700); err != nil { - os.RemoveAll(cmake.tempRoot) - return cmake, err - } - if err = os.Mkdir(cmake.ConfDir, 0700); err != nil { - os.RemoveAll(cmake.tempRoot) - return cmake, err + buildDir, err := createTempDir(tempRoot, "build") + confDir, err2 := createTempDir(tempRoot, "conf") + + if err != nil || err2 != nil { + os.RemoveAll(cmake.tempRoot) + if err != nil { + return err } + return err2 } - return cmake, nil + cmake.tempRoot = tempRoot + cmake.BuildDir = buildDir + cmake.ConfDir = confDir + + if len(cmake.SourceDir) == 0 { + cmake.SourceDir = cmake.ConfDir + } + return nil +} + +func createTempDir(parent, name string) (string, error) { + var path = filepath.Join(parent, name) + if err := os.Mkdir(path, 0700); err != nil { + return "", err + } + return path, nil } func (cmake *Cmake) RemoveTempDirs() error { - if len(cmake.tempRoot) == 0 { - return errors.New("temp dirs were not used") + if len(cmake.SourceDir) == 0 { + cmake.SourceDir = cmake.ConfDir } return os.RemoveAll(cmake.tempRoot) } @@ -110,7 +122,7 @@ var cmakeListsTpl = template.Must(template.New("CMakeLists.txt"). }). Parse(` cmake_minimum_required(VERSION 3.0) -set(CMAKE_C{{if .IsCpp}}XX{{end}}_STANDARD {{.Standard}}) +{{if .Standard}}set(CMAKE_C{{if .IsCpp}}XX{{end}}_STANDARD {{.Standard}}){{end}} project({{.Name}} C{{if .IsCpp}}XX{{end}}) add_executable(${PROJECT_NAME} {{Join .Files}}) diff --git a/test/cmake/libcheck.go b/test/cmake/libcheck.go new file mode 100644 index 00000000..269d2976 --- /dev/null +++ b/test/cmake/libcheck.go @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2020 ObjectBox Ltd. All rights reserved. + * https://objectbox.io + * + * This file is part of ObjectBox Generator. + * + * ObjectBox Generator 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 3 of the License, or + * (at your option) any later version. + * ObjectBox Generator 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 ObjectBox Generator. If not, see . + */ + +package cmake + +import ( + "fmt" + "io/ioutil" + "path/filepath" +) + +// LibraryExists tries to compile a simple program linking to the given library +func LibraryExists(name, includeFile string) (bool, error) { + build := Cmake{ + Name: "check-" + name, + IsCpp: true, + Files: []string{"main.cpp"}, + } + if err := build.CreateTempDirs(); err != nil { + return false, err + } + defer build.RemoveTempDirs() + + if len(name) > 0 { + build.LinkLibs = []string{name} + } + + if err := build.WriteCMakeListsTxt(); err != nil { + return false, err + } + + { // write main.cpp + mainPath := filepath.Join(build.SourceDir, build.Files[0]) + mainSrc := "int main(){ return 0; }\n\n" + if len(includeFile) > 0 { + mainSrc = "#include <" + includeFile + ">\n" + mainSrc + } + if err := ioutil.WriteFile(mainPath, []byte(mainSrc), 0600); err != nil { + return false, err + } + } + + if stdOut, stdErr, err := build.Configure(); err != nil { + return false, fmt.Errorf("cmake configuration failed: \n%s\n%s\n%s", stdOut, stdErr, err) + } + + if stdOut, stdErr, err := build.Build(); err != nil { + return false, fmt.Errorf("cmake build failed: \n%s\n%s\n%s", stdOut, stdErr, err) + } + + return true, nil +} diff --git a/test/cmake/libcheck_test.go b/test/cmake/libcheck_test.go new file mode 100644 index 00000000..eaaff6ff --- /dev/null +++ b/test/cmake/libcheck_test.go @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 ObjectBox Ltd. All rights reserved. + * https://objectbox.io + * + * This file is part of ObjectBox Generator. + * + * ObjectBox Generator 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 3 of the License, or + * (at your option) any later version. + * ObjectBox Generator 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 ObjectBox Generator. If not, see . + */ + +package cmake_test + +import ( + "testing" + + "github.com/objectbox/objectbox-generator/test/assert" + "github.com/objectbox/objectbox-generator/test/cmake" +) + +func TestLibExists(t *testing.T) { + exists, err := cmake.LibraryExists("nonsense", "") + t.Log(err) + assert.True(t, !exists) + + exists, err = cmake.LibraryExists("", "non-existent-lib/include.h") + t.Log(err) + assert.True(t, !exists) + + exists, err = cmake.LibraryExists("stdc++", "bits/stdc++.h") + assert.NoErr(t, err) + assert.True(t, exists) +} diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index c22c1303..a28793f1 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -50,13 +50,17 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro includeDir, err := filepath.Abs(dir) // main.c/cpp will include generated headers from here assert.NoErr(t, err) - build, err := cmake.CreateCmake("compilation-test", includeDir, true) - assert.NoErr(t, err) + build := cmake.Cmake{ + Name: "compilation-test", + IsCpp: h.cpp, + IncludeDirs: []string{includeDir}, + LinkLibs: []string{"objectbox"}, + } + assert.NoErr(t, build.CreateTempDirs()) defer build.RemoveTempDirs() var mainFile string - if h.cpp { - build.IsCpp = true + if build.IsCpp { build.Standard = 11 mainFile = path.Join(build.ConfDir, "main.cpp") } else { @@ -65,8 +69,6 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro } build.Files = append(build.Files, mainFile) - build.LinkLibs = append(build.LinkLibs, "objectbox") - build.IncludeDirs = append(build.IncludeDirs, includeDir) assert.NoErr(t, build.WriteCMakeListsTxt()) @@ -86,14 +88,14 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro if stdOut, stdErr, err := build.Configure(); err != nil { assert.Failf(t, "cmake configuration failed: \n%s\n%s\n%s", stdOut, stdErr, err) - } else if testing.Verbose() { + } else { t.Logf("configuration output:\n%s", string(stdOut)) } if stdOut, stdErr, err := build.Build(); err != nil { checkBuildError(t, errorTransformer, stdOut, stdErr, err, expectedError) assert.Failf(t, "cmake build failed: \n%s\n%s\n%s", stdOut, stdErr, err) - } else if testing.Verbose() { + } else { t.Logf("build output:\n%s", string(stdOut)) } } From 058330b1a3ea92876982bce990d26d224be6d06c Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Fri, 19 Jun 2020 10:31:09 +0200 Subject: [PATCH 03/21] conditional compilation in comparison tests --- test/cmake/libcheck.go | 23 +++++++++-------- test/cmake/libcheck_test.go | 13 ++++------ test/comparison/c-helper.go | 42 ++++++++++++++++++++++++++++++- test/comparison/conf.go | 7 ++++-- test/comparison/generator_test.go | 1 + test/comparison/go-helper.go | 2 ++ test/comparison/test-all.go | 1 + 7 files changed, 68 insertions(+), 21 deletions(-) diff --git a/test/cmake/libcheck.go b/test/cmake/libcheck.go index 269d2976..294ae1c9 100644 --- a/test/cmake/libcheck.go +++ b/test/cmake/libcheck.go @@ -26,14 +26,14 @@ import ( ) // LibraryExists tries to compile a simple program linking to the given library -func LibraryExists(name, includeFile string) (bool, error) { +func LibraryExists(name string, includeFiles []string) error { build := Cmake{ Name: "check-" + name, IsCpp: true, Files: []string{"main.cpp"}, } if err := build.CreateTempDirs(); err != nil { - return false, err + return err } defer build.RemoveTempDirs() @@ -42,27 +42,30 @@ func LibraryExists(name, includeFile string) (bool, error) { } if err := build.WriteCMakeListsTxt(); err != nil { - return false, err + return err } { // write main.cpp mainPath := filepath.Join(build.SourceDir, build.Files[0]) - mainSrc := "int main(){ return 0; }\n\n" - if len(includeFile) > 0 { - mainSrc = "#include <" + includeFile + ">\n" + mainSrc + var mainSrc string + if len(includeFiles) > 0 { + for _, inc := range includeFiles { + mainSrc = mainSrc + "#include <" + inc + ">\n" + } } + mainSrc = mainSrc + "\nint main(){ return 0; }\n\n" if err := ioutil.WriteFile(mainPath, []byte(mainSrc), 0600); err != nil { - return false, err + return err } } if stdOut, stdErr, err := build.Configure(); err != nil { - return false, fmt.Errorf("cmake configuration failed: \n%s\n%s\n%s", stdOut, stdErr, err) + return fmt.Errorf("cmake configuration failed: \n%s\n%s\n%s", stdOut, stdErr, err) } if stdOut, stdErr, err := build.Build(); err != nil { - return false, fmt.Errorf("cmake build failed: \n%s\n%s\n%s", stdOut, stdErr, err) + return fmt.Errorf("cmake build failed: \n%s\n%s\n%s", stdOut, stdErr, err) } - return true, nil + return nil } diff --git a/test/cmake/libcheck_test.go b/test/cmake/libcheck_test.go index eaaff6ff..6effa744 100644 --- a/test/cmake/libcheck_test.go +++ b/test/cmake/libcheck_test.go @@ -27,15 +27,12 @@ import ( ) func TestLibExists(t *testing.T) { - exists, err := cmake.LibraryExists("nonsense", "") - t.Log(err) - assert.True(t, !exists) + err := cmake.LibraryExists("nonsense", nil) + assert.Err(t, err) - exists, err = cmake.LibraryExists("", "non-existent-lib/include.h") - t.Log(err) - assert.True(t, !exists) + err = cmake.LibraryExists("", []string{"non-existent-lib/include.h"}) + assert.Err(t, err) - exists, err = cmake.LibraryExists("stdc++", "bits/stdc++.h") + err = cmake.LibraryExists("stdc++", []string{"bits/stdc++.h"}) assert.NoErr(t, err) - assert.True(t, exists) } diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index a28793f1..e3d6532e 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -32,7 +32,36 @@ import ( ) type cTestHelper struct { - cpp bool + cpp bool + canCompile bool +} + +func (h *cTestHelper) init(t *testing.T, conf testSpec) { + if !testing.Short() { + h.canCompile = true + + { // check objectbox lib + var includeFiles = []string{"objectbox.h"} + if h.cpp { + includeFiles = append(includeFiles, "objectbox-cpp.h") + } + assert.NoErr(t, cmake.LibraryExists("objectbox", includeFiles)) + } + + // check flatbuffers library availability + if h.cpp { + // Cpp compilation is mandatory. + // Note: we don't need flatbuffers library explicitly, it's part of objectbox at the moment. + assert.NoErr(t, cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"})) + } else { + + err := cmake.LibraryExists("flatccrt", []string{"flatcc/flatcc.h", "flatcc/flatcc_builder.h"}) + if err != nil { + t.Logf("C compilation not available, it will be skipped during tests, because %s", err) + h.canCompile = false + } + } + } } func (h cTestHelper) generatorFor(t *testing.T, conf testSpec, sourceFile string, genDir string) generator.CodeGenerator { @@ -47,6 +76,10 @@ func (cTestHelper) prepareTempDir(t *testing.T, conf testSpec, srcDir, tempDir, } func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedError error, errorTransformer func(err error) error) { + if !h.canCompile { + t.Skip("Compilation not available") + } + includeDir, err := filepath.Abs(dir) // main.c/cpp will include generated headers from here assert.NoErr(t, err) @@ -74,6 +107,11 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro { // write main.c/cpp to the conf dir - a simple one, just include all sources var mainSrc = "" + if build.IsCpp { + mainSrc = mainSrc + "#include \"objectbox-cpp.h\"\n" + } else { + mainSrc = mainSrc + "#include \"objectbox.h\"\n" + } files, err := ioutil.ReadDir(includeDir) assert.NoErr(t, err) @@ -82,7 +120,9 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro mainSrc = mainSrc + "#include \"" + file.Name() + "\"\n" } } + mainSrc = mainSrc + "int main(){ return 0; }\n\n" + t.Logf("main.c/cpp file contents \n%s", mainSrc) assert.NoErr(t, ioutil.WriteFile(mainFile, []byte(mainSrc), 0600)) } diff --git a/test/comparison/conf.go b/test/comparison/conf.go index b0e73612..7ac142da 100644 --- a/test/comparison/conf.go +++ b/test/comparison/conf.go @@ -27,6 +27,9 @@ import ( ) type testHelper interface { + // init sets up the helper before the very first execution + init(t *testing.T, conf testSpec) + // generatorFor constructs and configures a code generator for the given source file generatorFor(t *testing.T, conf testSpec, sourceFile string, genDir string) generator.CodeGenerator @@ -48,7 +51,7 @@ type testSpec struct { } var confs = map[string]testSpec{ - "fbs-c": {"c", ".fbs", ".obx.h", &cgenerator.CGenerator{PlainC: true}, cTestHelper{cpp: false}}, - "fbs-cpp": {"cpp", ".fbs", "-cpp.obx.h", &cgenerator.CGenerator{PlainC: false}, cTestHelper{cpp: true}}, + "fbs-c": {"c", ".fbs", ".obx.h", &cgenerator.CGenerator{PlainC: true}, &cTestHelper{cpp: false}}, + "fbs-cpp": {"cpp", ".fbs", "-cpp.obx.h", &cgenerator.CGenerator{PlainC: false}, &cTestHelper{cpp: true}}, // TODO "go": {"go", ".go", ".obx.go", &gogenerator.GoGenerator{}, goTestHelper{}}, } diff --git a/test/comparison/generator_test.go b/test/comparison/generator_test.go index db5742e8..3cb3c9b5 100644 --- a/test/comparison/generator_test.go +++ b/test/comparison/generator_test.go @@ -46,6 +46,7 @@ func TestCompare(t *testing.T) { srcType, genType := typesFromConfKey(parts[0]) conf, ok := confs[parts[0]] assert.True(t, ok) + conf.helper.init(t, conf) generateOneDir(t, *overwriteExpected, conf, srcType, genType, parts[1]) } else { t.Fatal("invalid target specification, expected 1 or two parts separated by '/'") diff --git a/test/comparison/go-helper.go b/test/comparison/go-helper.go index 56c8c44c..7e97d7ce 100644 --- a/test/comparison/go-helper.go +++ b/test/comparison/go-helper.go @@ -42,6 +42,8 @@ var goGeneratorArgsRegexp = regexp.MustCompile("//go:generate go run github.com/ type goTestHelper struct{} +func (h *goTestHelper) init(t *testing.T, conf testSpec) {} + func (h goTestHelper) generatorFor(t *testing.T, conf testSpec, sourceFile string, genDir string) generator.CodeGenerator { source, err := ioutil.ReadFile(sourceFile) assert.NoErr(t, err) diff --git a/test/comparison/test-all.go b/test/comparison/test-all.go index 238d60d2..562e6c44 100644 --- a/test/comparison/test-all.go +++ b/test/comparison/test-all.go @@ -53,6 +53,7 @@ func generateAllDirs(t *testing.T, overwriteExpected bool, confKey string) { conf, ok := confs[confKey] assert.True(t, ok) + conf.helper.init(t, conf) for _, testCase := range testCases { if !testCase.IsDir() { From 24d4dcd472d97ba7ea5cc1c9c3d9be1ae0deefc8 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Fri, 19 Jun 2020 10:42:16 +0200 Subject: [PATCH 04/21] extract CanCompileC to a separate package --- test/comparison/c-helper.go | 26 ++--------------- test/compilers/c-compiler.go | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 test/compilers/c-compiler.go diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index e3d6532e..caf3fec4 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -29,6 +29,7 @@ import ( cgenerator "github.com/objectbox/objectbox-generator/internal/generator/c" "github.com/objectbox/objectbox-generator/test/assert" "github.com/objectbox/objectbox-generator/test/cmake" + "github.com/objectbox/objectbox-generator/test/compilers" ) type cTestHelper struct { @@ -38,29 +39,8 @@ type cTestHelper struct { func (h *cTestHelper) init(t *testing.T, conf testSpec) { if !testing.Short() { - h.canCompile = true - - { // check objectbox lib - var includeFiles = []string{"objectbox.h"} - if h.cpp { - includeFiles = append(includeFiles, "objectbox-cpp.h") - } - assert.NoErr(t, cmake.LibraryExists("objectbox", includeFiles)) - } - - // check flatbuffers library availability - if h.cpp { - // Cpp compilation is mandatory. - // Note: we don't need flatbuffers library explicitly, it's part of objectbox at the moment. - assert.NoErr(t, cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"})) - } else { - - err := cmake.LibraryExists("flatccrt", []string{"flatcc/flatcc.h", "flatcc/flatcc_builder.h"}) - if err != nil { - t.Logf("C compilation not available, it will be skipped during tests, because %s", err) - h.canCompile = false - } - } + var mandatory = h.cpp // we require cpp compilation to be available at the moment + h.canCompile = compilers.CanCompileC(t, h.cpp, mandatory) } } diff --git a/test/compilers/c-compiler.go b/test/compilers/c-compiler.go new file mode 100644 index 00000000..ee7f5e60 --- /dev/null +++ b/test/compilers/c-compiler.go @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 ObjectBox Ltd. All rights reserved. + * https://objectbox.io + * + * This file is part of ObjectBox Generator. + * + * ObjectBox Generator 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 3 of the License, or + * (at your option) any later version. + * ObjectBox Generator 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 ObjectBox Generator. If not, see . + */ + +package compilers + +import ( + "testing" + + "github.com/objectbox/objectbox-generator/test/assert" + "github.com/objectbox/objectbox-generator/test/cmake" +) + +// Check verifies the C/C++ objectbox test code can be compiled - whether the required libraries are available. +func CanCompileC(t *testing.T, cpp, required bool) bool { + { // check objectbox lib + var includeFiles = []string{"objectbox.h"} + if cpp { + includeFiles = append(includeFiles, "objectbox-cpp.h") + } + assert.NoErr(t, cmake.LibraryExists("objectbox", includeFiles)) + } + + // check flatbuffers library availability + var err error + if cpp { + // Note: we don't need flatbuffers library explicitly, it's part of objectbox at the moment. + err = cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"}) + } else { + err = cmake.LibraryExists("flatccrt", []string{"flatcc/flatcc.h", "flatcc/flatcc_builder.h"}) + } + + if required { + assert.NoErr(t, err) + } else if err != nil { + t.Logf("C/C++ compilation not available because %s", err) + return false + } + return true +} From 9bec8acedc4728c4b576af38f0fb104c93b39c8c Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Fri, 19 Jun 2020 11:10:38 +0200 Subject: [PATCH 05/21] use local flatbuffers includes in tests --- test/{compilers => build}/c-compiler.go | 26 ++++++++++-------- test/build/conf.go | 22 ++++++++++++++++ test/cmake/libcheck.go | 9 ++++--- test/cmake/libcheck_test.go | 6 ++--- test/comparison/c-helper.go | 35 +++++++++++++------------ test/comparison/util.go | 7 +++++ 6 files changed, 70 insertions(+), 35 deletions(-) rename test/{compilers => build}/c-compiler.go (76%) create mode 100644 test/build/conf.go diff --git a/test/compilers/c-compiler.go b/test/build/c-compiler.go similarity index 76% rename from test/compilers/c-compiler.go rename to test/build/c-compiler.go index ee7f5e60..dcac3880 100644 --- a/test/compilers/c-compiler.go +++ b/test/build/c-compiler.go @@ -17,9 +17,10 @@ * along with ObjectBox Generator. If not, see . */ -package compilers +package build import ( + "path" "testing" "github.com/objectbox/objectbox-generator/test/assert" @@ -27,22 +28,25 @@ import ( ) // Check verifies the C/C++ objectbox test code can be compiled - whether the required libraries are available. -func CanCompileC(t *testing.T, cpp, required bool) bool { - { // check objectbox lib - var includeFiles = []string{"objectbox.h"} - if cpp { - includeFiles = append(includeFiles, "objectbox-cpp.h") - } - assert.NoErr(t, cmake.LibraryExists("objectbox", includeFiles)) +func CanCompileObjectBoxCCpp(t *testing.T, repoRoot string, cpp, required bool) bool { + var fbsIncludeDirs = []string{path.Join(repoRoot, FlatbuffersIncludeDir)} + + var err error + + // check objectbox lib + if cpp { + err = cmake.LibraryExists("objectbox", []string{"objectbox-cpp.h"}, fbsIncludeDirs) + } else { + err = cmake.LibraryExists("objectbox", []string{"objectbox.h"}, nil) } + assert.NoErr(t, err) // check flatbuffers library availability - var err error if cpp { // Note: we don't need flatbuffers library explicitly, it's part of objectbox at the moment. - err = cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"}) + err = cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"}, fbsIncludeDirs) } else { - err = cmake.LibraryExists("flatccrt", []string{"flatcc/flatcc.h", "flatcc/flatcc_builder.h"}) + err = cmake.LibraryExists("flatccrt", []string{"flatcc/flatcc.h", "flatcc/flatcc_builder.h"}, nil) } if required { diff --git a/test/build/conf.go b/test/build/conf.go new file mode 100644 index 00000000..f89af15d --- /dev/null +++ b/test/build/conf.go @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2020 ObjectBox Ltd. All rights reserved. + * https://objectbox.io + * + * This file is part of ObjectBox Generator. + * + * ObjectBox Generator 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 3 of the License, or + * (at your option) any later version. + * ObjectBox Generator 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 ObjectBox Generator. If not, see . + */ + +package build + +const FlatbuffersIncludeDir = "third_party/flatbuffers-c-bridge/third_party/flatbuffers/include" diff --git a/test/cmake/libcheck.go b/test/cmake/libcheck.go index 294ae1c9..326ac148 100644 --- a/test/cmake/libcheck.go +++ b/test/cmake/libcheck.go @@ -26,11 +26,12 @@ import ( ) // LibraryExists tries to compile a simple program linking to the given library -func LibraryExists(name string, includeFiles []string) error { +func LibraryExists(name string, includeFiles []string, includeDirs []string) error { build := Cmake{ - Name: "check-" + name, - IsCpp: true, - Files: []string{"main.cpp"}, + Name: "check-" + name, + IsCpp: true, + Files: []string{"main.cpp"}, + IncludeDirs: includeDirs, } if err := build.CreateTempDirs(); err != nil { return err diff --git a/test/cmake/libcheck_test.go b/test/cmake/libcheck_test.go index 6effa744..60f95116 100644 --- a/test/cmake/libcheck_test.go +++ b/test/cmake/libcheck_test.go @@ -27,12 +27,12 @@ import ( ) func TestLibExists(t *testing.T) { - err := cmake.LibraryExists("nonsense", nil) + err := cmake.LibraryExists("nonsense", nil, nil) assert.Err(t, err) - err = cmake.LibraryExists("", []string{"non-existent-lib/include.h"}) + err = cmake.LibraryExists("", []string{"non-existent-lib/include.h"}, nil) assert.Err(t, err) - err = cmake.LibraryExists("stdc++", []string{"bits/stdc++.h"}) + err = cmake.LibraryExists("stdc++", []string{"bits/stdc++.h"}, nil) assert.NoErr(t, err) } diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index caf3fec4..c24c4b5a 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -26,10 +26,10 @@ import ( "testing" "github.com/objectbox/objectbox-generator/internal/generator" - cgenerator "github.com/objectbox/objectbox-generator/internal/generator/c" + "github.com/objectbox/objectbox-generator/internal/generator/c" "github.com/objectbox/objectbox-generator/test/assert" + "github.com/objectbox/objectbox-generator/test/build" "github.com/objectbox/objectbox-generator/test/cmake" - "github.com/objectbox/objectbox-generator/test/compilers" ) type cTestHelper struct { @@ -39,8 +39,9 @@ type cTestHelper struct { func (h *cTestHelper) init(t *testing.T, conf testSpec) { if !testing.Short() { + var mandatory = h.cpp // we require cpp compilation to be available at the moment - h.canCompile = compilers.CanCompileC(t, h.cpp, mandatory) + h.canCompile = build.CanCompileObjectBoxCCpp(t, repoRoot(t), h.cpp, mandatory) } } @@ -63,31 +64,31 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro includeDir, err := filepath.Abs(dir) // main.c/cpp will include generated headers from here assert.NoErr(t, err) - build := cmake.Cmake{ + cmak := cmake.Cmake{ Name: "compilation-test", IsCpp: h.cpp, - IncludeDirs: []string{includeDir}, + IncludeDirs: []string{includeDir, path.Join(repoRoot(t), build.FlatbuffersIncludeDir)}, LinkLibs: []string{"objectbox"}, } - assert.NoErr(t, build.CreateTempDirs()) - defer build.RemoveTempDirs() + assert.NoErr(t, cmak.CreateTempDirs()) + defer cmak.RemoveTempDirs() var mainFile string - if build.IsCpp { - build.Standard = 11 - mainFile = path.Join(build.ConfDir, "main.cpp") + if cmak.IsCpp { + cmak.Standard = 11 + mainFile = path.Join(cmak.ConfDir, "main.cpp") } else { - build.Standard = 99 - mainFile = path.Join(build.ConfDir, "main.c") + cmak.Standard = 99 + mainFile = path.Join(cmak.ConfDir, "main.c") } - build.Files = append(build.Files, mainFile) + cmak.Files = append(cmak.Files, mainFile) - assert.NoErr(t, build.WriteCMakeListsTxt()) + assert.NoErr(t, cmak.WriteCMakeListsTxt()) { // write main.c/cpp to the conf dir - a simple one, just include all sources var mainSrc = "" - if build.IsCpp { + if cmak.IsCpp { mainSrc = mainSrc + "#include \"objectbox-cpp.h\"\n" } else { mainSrc = mainSrc + "#include \"objectbox.h\"\n" @@ -106,13 +107,13 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro assert.NoErr(t, ioutil.WriteFile(mainFile, []byte(mainSrc), 0600)) } - if stdOut, stdErr, err := build.Configure(); err != nil { + if stdOut, stdErr, err := cmak.Configure(); err != nil { assert.Failf(t, "cmake configuration failed: \n%s\n%s\n%s", stdOut, stdErr, err) } else { t.Logf("configuration output:\n%s", string(stdOut)) } - if stdOut, stdErr, err := build.Build(); err != nil { + if stdOut, stdErr, err := cmak.Build(); err != nil { checkBuildError(t, errorTransformer, stdOut, stdErr, err, expectedError) assert.Failf(t, "cmake build failed: \n%s\n%s\n%s", stdOut, stdErr, err) } else { diff --git a/test/comparison/util.go b/test/comparison/util.go index 613910f4..d36846b0 100644 --- a/test/comparison/util.go +++ b/test/comparison/util.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "os" + "path/filepath" "strings" "testing" @@ -50,3 +51,9 @@ func checkBuildError(t *testing.T, errorTransformer func(err error) error, stdOu assert.Eq(t, expectedError, receivedError) } + +func repoRoot(t *testing.T) string { + cwd, err := os.Getwd() + assert.NoErr(t, err) + return filepath.Join(cwd, "..", "..") +} From aaa204575a7f562cd8541ab7f61fac33c169b4c0 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 09:13:42 +0200 Subject: [PATCH 06/21] fix flatcc lib check - currently requires explicit include of stddef.h --- test/build/c-compiler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/build/c-compiler.go b/test/build/c-compiler.go index dcac3880..99e6b09b 100644 --- a/test/build/c-compiler.go +++ b/test/build/c-compiler.go @@ -46,7 +46,7 @@ func CanCompileObjectBoxCCpp(t *testing.T, repoRoot string, cpp, required bool) // Note: we don't need flatbuffers library explicitly, it's part of objectbox at the moment. err = cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"}, fbsIncludeDirs) } else { - err = cmake.LibraryExists("flatccrt", []string{"flatcc/flatcc.h", "flatcc/flatcc_builder.h"}, nil) + err = cmake.LibraryExists("flatccrt", []string{"stddef.h", "flatcc/flatcc.h", "flatcc/flatcc_builder.h"}, nil) } if required { From c9e98318aa6fbf303d0254781fc244dae7875254 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 11:00:39 +0200 Subject: [PATCH 07/21] add objectbox-c download script --- Makefile | 4 ++-- third_party/objectbox-c/.gitignore | 3 +++ third_party/objectbox-c/get-objectbox-c.sh | 24 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 third_party/objectbox-c/.gitignore create mode 100755 third_party/objectbox-c/get-objectbox-c.sh diff --git a/Makefile b/Makefile index 154164a4..723f9b82 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,6 @@ default_target: all help: ## Show this help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - - #============================================================================== all: depend build @@ -26,3 +24,5 @@ clean: ## Clean previous builds depend: ## Build dependencies ./third_party/flatbuffers-c-bridge/build.sh + ./third_party/objectbox-c/get-objectbox-c.sh + diff --git a/third_party/objectbox-c/.gitignore b/third_party/objectbox-c/.gitignore new file mode 100644 index 00000000..5c15c317 --- /dev/null +++ b/third_party/objectbox-c/.gitignore @@ -0,0 +1,3 @@ +download +include +lib \ No newline at end of file diff --git a/third_party/objectbox-c/get-objectbox-c.sh b/third_party/objectbox-c/get-objectbox-c.sh new file mode 100755 index 00000000..b11922c4 --- /dev/null +++ b/third_party/objectbox-c/get-objectbox-c.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +cVersion=0.9.0 + +scriptDir=$(dirname "${BASH_SOURCE[0]}") + + +echo "******** Downloading ObjectBox-C library ********" +echo "Into: ${scriptDir}" +cd "${scriptDir}" + +# don't install the library system-wide, just download it +export installLibrary=false +bash <(curl -s https://raw.githubusercontent.com/objectbox/objectbox-c/master/download.sh) --quiet ${cVersion} + +echo "******** Collecting artifacts ********" +cp -rfv download/testing/*objectbox*/include ./ +cp -rfv download/testing/*objectbox*/lib ./ +rm -rfv download + +echo "Downloaded ObjectBox-C headers and library:" +echo "Current directory: ${scriptDir}" +ls -lh include lib \ No newline at end of file From 2ee34e7623cdbd3ec9416d64efb9604103974f7b Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 11:11:18 +0200 Subject: [PATCH 08/21] tests - use locally downloaded objectbox-c during compilation --- test/build/c-compiler.go | 14 +++++++------- test/build/conf.go | 18 +++++++++++++++++- test/cmake/cmake.go | 4 ++-- test/cmake/libcheck.go | 3 ++- test/cmake/libcheck_test.go | 6 +++--- test/comparison/c-helper.go | 3 ++- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/test/build/c-compiler.go b/test/build/c-compiler.go index 99e6b09b..89706c90 100644 --- a/test/build/c-compiler.go +++ b/test/build/c-compiler.go @@ -20,7 +20,6 @@ package build import ( - "path" "testing" "github.com/objectbox/objectbox-generator/test/assert" @@ -29,24 +28,25 @@ import ( // Check verifies the C/C++ objectbox test code can be compiled - whether the required libraries are available. func CanCompileObjectBoxCCpp(t *testing.T, repoRoot string, cpp, required bool) bool { - var fbsIncludeDirs = []string{path.Join(repoRoot, FlatbuffersIncludeDir)} - var err error + var includeDirs = IncludeDirs(repoRoot) + var libDirs = LibDirs(repoRoot) + // check objectbox lib if cpp { - err = cmake.LibraryExists("objectbox", []string{"objectbox-cpp.h"}, fbsIncludeDirs) + err = cmake.LibraryExists("objectbox", []string{"objectbox-cpp.h"}, includeDirs, libDirs) } else { - err = cmake.LibraryExists("objectbox", []string{"objectbox.h"}, nil) + err = cmake.LibraryExists("objectbox", []string{"objectbox.h"}, includeDirs, libDirs) } assert.NoErr(t, err) // check flatbuffers library availability if cpp { // Note: we don't need flatbuffers library explicitly, it's part of objectbox at the moment. - err = cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"}, fbsIncludeDirs) + err = cmake.LibraryExists("", []string{"flatbuffers/flatbuffers.h"}, includeDirs, libDirs) } else { - err = cmake.LibraryExists("flatccrt", []string{"stddef.h", "flatcc/flatcc.h", "flatcc/flatcc_builder.h"}, nil) + err = cmake.LibraryExists("flatccrt", []string{"stddef.h", "flatcc/flatcc.h", "flatcc/flatcc_builder.h"}, includeDirs, libDirs) } if required { diff --git a/test/build/conf.go b/test/build/conf.go index f89af15d..987ccd9d 100644 --- a/test/build/conf.go +++ b/test/build/conf.go @@ -19,4 +19,20 @@ package build -const FlatbuffersIncludeDir = "third_party/flatbuffers-c-bridge/third_party/flatbuffers/include" +import "path" + +const flatbuffersDir = "third_party/flatbuffers-c-bridge/third_party/flatbuffers" +const ObjectBoxCDir = "third_party/objectbox-c" + +func IncludeDirs(repoRoot string) []string { + var result []string + result = append(result, path.Join(repoRoot, flatbuffersDir, "include")) + result = append(result, path.Join(repoRoot, ObjectBoxCDir, "include")) + return result +} + +func LibDirs(repoRoot string) []string { + var result []string + result = append(result, path.Join(repoRoot, ObjectBoxCDir, "lib")) + return result +} diff --git a/test/cmake/cmake.go b/test/cmake/cmake.go index dff50d66..9854704f 100644 --- a/test/cmake/cmake.go +++ b/test/cmake/cmake.go @@ -127,8 +127,8 @@ project({{.Name}} C{{if .IsCpp}}XX{{end}}) add_executable(${PROJECT_NAME} {{Join .Files}}) {{if .IncludeDirs}}target_include_directories(${PROJECT_NAME} PRIVATE {{Join .IncludeDirs}}){{end}} -{{if .LinkLibs}}target_link_libraries(${PROJECT_NAME} {{Join .LinkLibs}}){{end}} -{{if .LinkDirs}}target_link_directories(${PROJECT_NAME} {{Join .LinkDirs}}){{end}} +{{if .LinkLibs}}target_link_libraries(${PROJECT_NAME} PRIVATE {{Join .LinkLibs}}){{end}} +{{if .LinkDirs}}target_link_directories(${PROJECT_NAME} PRIVATE {{Join .LinkDirs}}){{end}} `)) // Configure runs cmake configuration step. diff --git a/test/cmake/libcheck.go b/test/cmake/libcheck.go index 326ac148..f0a9ea79 100644 --- a/test/cmake/libcheck.go +++ b/test/cmake/libcheck.go @@ -26,12 +26,13 @@ import ( ) // LibraryExists tries to compile a simple program linking to the given library -func LibraryExists(name string, includeFiles []string, includeDirs []string) error { +func LibraryExists(name string, includeFiles, includeDirs, linkDirs []string) error { build := Cmake{ Name: "check-" + name, IsCpp: true, Files: []string{"main.cpp"}, IncludeDirs: includeDirs, + LinkDirs: linkDirs, } if err := build.CreateTempDirs(); err != nil { return err diff --git a/test/cmake/libcheck_test.go b/test/cmake/libcheck_test.go index 60f95116..7ac48b36 100644 --- a/test/cmake/libcheck_test.go +++ b/test/cmake/libcheck_test.go @@ -27,12 +27,12 @@ import ( ) func TestLibExists(t *testing.T) { - err := cmake.LibraryExists("nonsense", nil, nil) + err := cmake.LibraryExists("nonsense", nil, nil, nil) assert.Err(t, err) - err = cmake.LibraryExists("", []string{"non-existent-lib/include.h"}, nil) + err = cmake.LibraryExists("", []string{"non-existent-lib/include.h"}, nil, nil) assert.Err(t, err) - err = cmake.LibraryExists("stdc++", []string{"bits/stdc++.h"}, nil) + err = cmake.LibraryExists("stdc++", []string{"bits/stdc++.h"}, nil, nil) assert.NoErr(t, err) } diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index c24c4b5a..f349d497 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -67,7 +67,8 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro cmak := cmake.Cmake{ Name: "compilation-test", IsCpp: h.cpp, - IncludeDirs: []string{includeDir, path.Join(repoRoot(t), build.FlatbuffersIncludeDir)}, + IncludeDirs: append(build.IncludeDirs(repoRoot(t)), includeDir), + LinkDirs: build.LibDirs(repoRoot(t)), LinkLibs: []string{"objectbox"}, } assert.NoErr(t, cmak.CreateTempDirs()) From b87c620b1b2785c7cf63c85abace1af37b387bdb Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 13:37:20 +0200 Subject: [PATCH 09/21] tests - use locally downloaded flatcc during compilation --- Makefile | 5 ++- test/build/conf.go | 9 ++++-- third_party/flatcc/.gitignore | 4 +++ third_party/flatcc/build.sh | 59 +++++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 third_party/flatcc/.gitignore create mode 100755 third_party/flatcc/build.sh diff --git a/Makefile b/Makefile index 723f9b82..bbff7175 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Default target executed when no arguments are given to make. default_target: all -.PHONY: default_target help clean depend build test +.PHONY: default_target help clean depend build test test-depend help: ## Show this help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' @@ -24,5 +24,8 @@ clean: ## Clean previous builds depend: ## Build dependencies ./third_party/flatbuffers-c-bridge/build.sh + +test-depend: ## Build test dependencies + ./third_party/flatcc/build.sh ./third_party/objectbox-c/get-objectbox-c.sh diff --git a/test/build/conf.go b/test/build/conf.go index 987ccd9d..8b627126 100644 --- a/test/build/conf.go +++ b/test/build/conf.go @@ -22,17 +22,20 @@ package build import "path" const flatbuffersDir = "third_party/flatbuffers-c-bridge/third_party/flatbuffers" -const ObjectBoxCDir = "third_party/objectbox-c" +const flatccDir = "third_party/flatcc" +const objectBoxCDir = "third_party/objectbox-c" func IncludeDirs(repoRoot string) []string { var result []string result = append(result, path.Join(repoRoot, flatbuffersDir, "include")) - result = append(result, path.Join(repoRoot, ObjectBoxCDir, "include")) + result = append(result, path.Join(repoRoot, flatccDir, "include")) + result = append(result, path.Join(repoRoot, objectBoxCDir, "include")) return result } func LibDirs(repoRoot string) []string { var result []string - result = append(result, path.Join(repoRoot, ObjectBoxCDir, "lib")) + result = append(result, path.Join(repoRoot, objectBoxCDir, "lib")) + result = append(result, path.Join(repoRoot, flatccDir, "lib")) return result } diff --git a/third_party/flatcc/.gitignore b/third_party/flatcc/.gitignore new file mode 100644 index 00000000..0e1dfdcc --- /dev/null +++ b/third_party/flatcc/.gitignore @@ -0,0 +1,4 @@ +build +src +lib +include \ No newline at end of file diff --git a/third_party/flatcc/build.sh b/third_party/flatcc/build.sh new file mode 100755 index 00000000..40bc91e2 --- /dev/null +++ b/third_party/flatcc/build.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +set -euo pipefail + +fccVersion=v0.6.0 +fccRepo=github.com/dvidelabs/flatcc + +scriptDir=$(dirname "${BASH_SOURCE[0]}") +srcDir=${scriptDir}/src +buildDir=${scriptDir}/build +installDir=${scriptDir} + +buildType=Release + +configArgs="-DCMAKE_BUILD_TYPE=${buildType}" +buildArgs="-- -j" +if [[ "$(uname)" == MINGW* ]] || [[ "$(uname)" == CYGWIN* ]]; then + configArgs+=' -G "MinGW Makefiles"' +fi + +function prepare() { + echo "******** Getting Flatcc sources ********" + if [[ ! -d ${srcDir} ]]; then + echo "Cloning ${fccRepo} into Into: ${srcDir}" + git clone https://${fccRepo}.git "${srcDir}" + fi + + echo "Checking out ${fccVersion}" + (cd "${srcDir}"; git fetch) + (cd "${srcDir}"; git checkout ${fccVersion}) +} + +function build() { + echo "******** Configuring & building ********" + + srcDirAbsolute="$(pwd)/$srcDir" + pwd=$(pwd) + mkdir -p "$buildDir" + + set -x + + # need to use eval because of quotes in configArgs... bash is just wonderful... + cd "$buildDir" + eval "cmake \"$srcDirAbsolute\" $configArgs" + cd "$pwd" + + cmake --build "$buildDir" --config ${buildType} --target flatccrt ${buildArgs} + set +x +} + +function install() { + echo "******** Collecting artifacts ********" + echo "Copying from ${srcDir} to ${installDir}:" + cp -rv "${srcDir}/include" "${installDir}" + cp -rv "${srcDir}/lib" "${installDir}" +} + +prepare +build +install From ed28ee2cc97c549047862df29156961668eb4140 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 13:45:54 +0200 Subject: [PATCH 10/21] CI - use makefile and run tests --- .github/workflows/ci.yml | 48 ++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab4fe860..8347ecca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,9 @@ jobs: image: centos/devtoolset-7-toolchain-centos7 options: --user 0 steps: + - name: Install Git + run: yum install -y git + - name: Install CMake env: version: 3.17.3 @@ -25,29 +28,23 @@ jobs: - name: Get sources uses: actions/checkout@v2 - - name: Cache FBS-C-Bridge build dir - id: fbs-bridge-cache + - name: Cache Deps uses: actions/cache@v2 - env: - cache-name: cache-fbs-c-bridge-build with: - path: ./third_party/flatbuffers-c-bridge/cmake-build/*.a - key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('./third_party/flatbuffers-c-bridge/*') }} - - - name: Build FBS-C-Bridge - if: steps.fbs-bridge-cache.outputs.cache-hit != 'true' - run: ./third_party/flatbuffers-c-bridge/build.sh + path: ./third_party/* + key: ${{ runner.os }}-deps-${{ hashFiles('./third_party/*') }} - - name: Build + - name: Build & Test run: | - cd cmd/objectbox-generator - go build + make + make test-depend + make test - name: Upload artifact uses: actions/upload-artifact@v2 with: name: objectbox-generator-${{ runner.os }} - path: cmd/objectbox-generator/objectbox-generator + path: objectbox-generator build: strategy: @@ -60,27 +57,20 @@ jobs: - name: Get sources uses: actions/checkout@v2 - - name: Cache FBS-C-Bridge build dir - id: fbs-bridge-cache + - name: Cache Deps uses: actions/cache@v2 - env: - cache-name: cache-fbs-c-bridge-build with: - path: ./third_party/flatbuffers-c-bridge/cmake-build/*.a - key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('./third_party/flatbuffers-c-bridge/*') }} - - - name: Build FBS-C-Bridge - if: steps.fbs-bridge-cache.outputs.cache-hit != 'true' - shell: bash - run: ./third_party/flatbuffers-c-bridge/build.sh + path: ./third_party/* + key: ${{ runner.os }}-deps-${{ hashFiles('./third_party/*') }} - - name: Build + - name: Build & Test run: | - cd cmd/objectbox-generator - go build + make + make test-depend + make test - name: Upload artifact uses: actions/upload-artifact@v2 with: name: objectbox-generator-${{ runner.os }} - path: cmd/objectbox-generator/objectbox-generator* + path: objectbox-generator* From 3e608c79717e2cb23e9513ad4809676847cfa678 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 14:00:54 +0200 Subject: [PATCH 11/21] tests - change gcc-specific include test from bits/stdc++.h to --- test/cmake/libcheck_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cmake/libcheck_test.go b/test/cmake/libcheck_test.go index 7ac48b36..7ff62367 100644 --- a/test/cmake/libcheck_test.go +++ b/test/cmake/libcheck_test.go @@ -33,6 +33,6 @@ func TestLibExists(t *testing.T) { err = cmake.LibraryExists("", []string{"non-existent-lib/include.h"}, nil, nil) assert.Err(t, err) - err = cmake.LibraryExists("stdc++", []string{"bits/stdc++.h"}, nil, nil) + err = cmake.LibraryExists("stdc++", []string{"array"}, nil, nil) assert.NoErr(t, err) } From 28b1cae11c53604b70411303361a11134f87f737 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 14:23:48 +0200 Subject: [PATCH 12/21] update make clean to include new with dependency cleanup --- Makefile | 2 ++ third_party/flatcc/clean.sh | 9 +++++++++ third_party/objectbox-c/clean.sh | 8 ++++++++ 3 files changed, 19 insertions(+) create mode 100755 third_party/flatcc/clean.sh create mode 100755 third_party/objectbox-c/clean.sh diff --git a/Makefile b/Makefile index bbff7175..1dc4a701 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,8 @@ clean: ## Clean previous builds rm -f objectbox-generator rm -f objectbox-generator.exe rm -rf third_party/flatbuffers-c-bridge/cmake-build + ./third_party/flatcc/clean.sh + ./third_party/objectbox-c/clean.sh depend: ## Build dependencies ./third_party/flatbuffers-c-bridge/build.sh diff --git a/third_party/flatcc/clean.sh b/third_party/flatcc/clean.sh new file mode 100755 index 00000000..e97f6047 --- /dev/null +++ b/third_party/flatcc/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +scriptDir=$(dirname "${BASH_SOURCE[0]}") +set +x +rm -rf "${scriptDir}/build" +rm -rf "${scriptDir}/include" +rm -rf "${scriptDir}/lib" +rm -rf "${scriptDir}/src" \ No newline at end of file diff --git a/third_party/objectbox-c/clean.sh b/third_party/objectbox-c/clean.sh new file mode 100755 index 00000000..66aa5de5 --- /dev/null +++ b/third_party/objectbox-c/clean.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +scriptDir=$(dirname "${BASH_SOURCE[0]}") +set +x +rm -rf "${scriptDir}/download" +rm -rf "${scriptDir}/include" +rm -rf "${scriptDir}/lib" \ No newline at end of file From 10d419bcf0271161b8ac6bd21e5cb26f3c581b7e Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 15:26:16 +0200 Subject: [PATCH 13/21] ci cross-platform fixes --- .github/workflows/ci.yml | 1 + Makefile | 2 +- test/cmake/libcheck_test.go | 11 ++++++++++- test/comparison/c-helper.go | 2 +- test/comparison/util.go | 2 +- third_party/flatbuffers-c-bridge/build.sh | 10 +++++++++- third_party/flatcc/build.sh | 13 ++++++------- 7 files changed, 29 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8347ecca..0d3f35a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,6 +64,7 @@ jobs: key: ${{ runner.os }}-deps-${{ hashFiles('./third_party/*') }} - name: Build & Test + shell: bash run: | make make test-depend diff --git a/Makefile b/Makefile index 1dc4a701..4ee3d369 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ clean: ## Clean previous builds depend: ## Build dependencies ./third_party/flatbuffers-c-bridge/build.sh -test-depend: ## Build test dependencies +test-depend: depend ## Build test dependencies ./third_party/flatcc/build.sh ./third_party/objectbox-c/get-objectbox-c.sh diff --git a/test/cmake/libcheck_test.go b/test/cmake/libcheck_test.go index 7ff62367..f9402609 100644 --- a/test/cmake/libcheck_test.go +++ b/test/cmake/libcheck_test.go @@ -20,6 +20,7 @@ package cmake_test import ( + "runtime" "testing" "github.com/objectbox/objectbox-generator/test/assert" @@ -27,12 +28,20 @@ import ( ) func TestLibExists(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + err := cmake.LibraryExists("nonsense", nil, nil, nil) assert.Err(t, err) err = cmake.LibraryExists("", []string{"non-existent-lib/include.h"}, nil, nil) assert.Err(t, err) - err = cmake.LibraryExists("stdc++", []string{"array"}, nil, nil) + if runtime.GOOS == "windows" { + err = cmake.LibraryExists("", []string{"array"}, nil, nil) + } else { + err = cmake.LibraryExists("stdc++", []string{"array"}, nil, nil) + } assert.NoErr(t, err) } diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index f349d497..1539f5dc 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -39,7 +39,6 @@ type cTestHelper struct { func (h *cTestHelper) init(t *testing.T, conf testSpec) { if !testing.Short() { - var mandatory = h.cpp // we require cpp compilation to be available at the moment h.canCompile = build.CanCompileObjectBoxCCpp(t, repoRoot(t), h.cpp, mandatory) } @@ -81,6 +80,7 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro } else { cmak.Standard = 99 mainFile = path.Join(cmak.ConfDir, "main.c") + cmak.LinkLibs = append(cmak.LinkLibs, "flatccrt") } cmak.Files = append(cmak.Files, mainFile) diff --git a/test/comparison/util.go b/test/comparison/util.go index d36846b0..e3404455 100644 --- a/test/comparison/util.go +++ b/test/comparison/util.go @@ -55,5 +55,5 @@ func checkBuildError(t *testing.T, errorTransformer func(err error) error, stdOu func repoRoot(t *testing.T) string { cwd, err := os.Getwd() assert.NoErr(t, err) - return filepath.Join(cwd, "..", "..") + return filepath.ToSlash(filepath.Join(cwd, "..", "..")) } diff --git a/third_party/flatbuffers-c-bridge/build.sh b/third_party/flatbuffers-c-bridge/build.sh index 5c3196e3..3cc5843b 100755 --- a/third_party/flatbuffers-c-bridge/build.sh +++ b/third_party/flatbuffers-c-bridge/build.sh @@ -31,7 +31,15 @@ fi function build() { echo "******** Configuring & building ********" - srcDirAbsolute="$(pwd)/$srcDir" + # Note: we need an absolute path... + # realpath isn't available on macOS and the "else" variant didn't work well on windows because the path was already absolute... + srcDirAbsolute= + if [[ -x $(command -v realpath) ]]; then + srcDirAbsolute=$(realpath "$srcDir") + else + srcDirAbsolute="$(pwd)/$srcDir" + fi + pwd=$(pwd) mkdir -p "$buildDir" diff --git a/third_party/flatcc/build.sh b/third_party/flatcc/build.sh index 40bc91e2..3f59fb05 100755 --- a/third_party/flatcc/build.sh +++ b/third_party/flatcc/build.sh @@ -10,12 +10,7 @@ buildDir=${scriptDir}/build installDir=${scriptDir} buildType=Release - configArgs="-DCMAKE_BUILD_TYPE=${buildType}" -buildArgs="-- -j" -if [[ "$(uname)" == MINGW* ]] || [[ "$(uname)" == CYGWIN* ]]; then - configArgs+=' -G "MinGW Makefiles"' -fi function prepare() { echo "******** Getting Flatcc sources ********" @@ -43,7 +38,7 @@ function build() { eval "cmake \"$srcDirAbsolute\" $configArgs" cd "$pwd" - cmake --build "$buildDir" --config ${buildType} --target flatccrt ${buildArgs} + cmake --build "$buildDir" --config ${buildType} --target flatccrt set +x } @@ -51,7 +46,11 @@ function install() { echo "******** Collecting artifacts ********" echo "Copying from ${srcDir} to ${installDir}:" cp -rv "${srcDir}/include" "${installDir}" - cp -rv "${srcDir}/lib" "${installDir}" + if [[ -d "${srcDir}/lib/${buildType}" ]]; then + cp -rv "${srcDir}/lib/${buildType}" "${installDir}/lib" + else + cp -rv "${srcDir}/lib" "${installDir}" + fi } prepare From 085b772b0ef45eb4eb96e54d6350393164bbb1e7 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 16:57:51 +0200 Subject: [PATCH 14/21] flatcc & test build windows fixes --- test/cmake/cmake.go | 39 ++++++++++++++++++++++++++++++++++--- test/comparison/c-helper.go | 5 +++++ test/comparison/util.go | 2 +- third_party/flatcc/build.sh | 6 ++++++ 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/test/cmake/cmake.go b/test/cmake/cmake.go index 9854704f..1770b244 100644 --- a/test/cmake/cmake.go +++ b/test/cmake/cmake.go @@ -22,12 +22,13 @@ package cmake import ( "bufio" + "bytes" "errors" "io/ioutil" "os" "os/exec" "path/filepath" - "strings" + "runtime" "text/template" ) @@ -41,6 +42,7 @@ type Cmake struct { IncludeDirs []string LinkLibs []string // Library names or full paths LinkDirs []string // Where should the linker look for libraries + Generator string // Build configuration SourceDir string @@ -114,10 +116,32 @@ func (cmake *Cmake) WriteCMakeListsTxt() error { return writer.Flush() } +func (cmake *Cmake) GetCMakeListsTxt() (string, error) { + var b bytes.Buffer + writer := bufio.NewWriter(&b) + if err := cmakeListsTpl.Execute(writer, cmake); err != nil { + return "", err + } else if err = writer.Flush(); err != nil { + return "", err + } + return string(b.Bytes()), nil +} + var cmakeListsTpl = template.Must(template.New("CMakeLists.txt"). Funcs(template.FuncMap{ "Join": func(ss []string) string { - return strings.Join(ss, " ") + switch len(ss) { + case 0: + return "" + case 1: + return filepath.ToSlash(ss[0]) + default: + var result string + for _, s := range ss { + result = result + "\n\t" + filepath.ToSlash(s) + } + return result + } }, }). Parse(` @@ -133,7 +157,16 @@ add_executable(${PROJECT_NAME} {{Join .Files}}) // Configure runs cmake configuration step. func (cmake *Cmake) Configure() ([]byte, []byte, error) { - return cmakeExec(cmake.BuildDir, cmake.ConfDir) + if len(cmake.Generator) == 0 && runtime.GOOS == "windows" { + // Using MinGW because MSVC doesn't support linking to .dll - app is supposed to load them on runtime + cmake.Generator = "MinGW Makefiles" + } + + if len(cmake.Generator) > 0 { + return cmakeExec(cmake.BuildDir, cmake.ConfDir, "-G", cmake.Generator) + } else { + return cmakeExec(cmake.BuildDir, cmake.ConfDir) + } } // Configure runs cmake build step. diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index 1539f5dc..104584c9 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -86,6 +86,11 @@ func (h cTestHelper) build(t *testing.T, conf testSpec, dir string, expectedErro cmak.Files = append(cmak.Files, mainFile) assert.NoErr(t, cmak.WriteCMakeListsTxt()) + if testing.Verbose() { + cml, err := cmak.GetCMakeListsTxt() + assert.NoErr(t, err) + t.Logf("Using CMakeLists.txt: %s", cml) + } { // write main.c/cpp to the conf dir - a simple one, just include all sources var mainSrc = "" diff --git a/test/comparison/util.go b/test/comparison/util.go index e3404455..eedda5f7 100644 --- a/test/comparison/util.go +++ b/test/comparison/util.go @@ -41,7 +41,7 @@ func checkBuildError(t *testing.T, errorTransformer func(err error) error, stdOu var receivedError = errorTransformer(fmt.Errorf("%s\n%s\n%s", stdOut, stdErr, err)) // Fix paths in the error output on Windows so that it matches the expected error (which always uses '/'). - if os.PathSeparator != '/' { + if os.PathSeparator != '/' && expectedError != nil { // Make sure the expected error doesn't contain the path separator already - to make it easier to debug. if strings.Contains(expectedError.Error(), string(os.PathSeparator)) { assert.Failf(t, "compile-error.expected contains this OS path separator '%v' so paths can't be normalized to '/'", string(os.PathSeparator)) diff --git a/third_party/flatcc/build.sh b/third_party/flatcc/build.sh index 3f59fb05..3edc0208 100755 --- a/third_party/flatcc/build.sh +++ b/third_party/flatcc/build.sh @@ -12,6 +12,12 @@ installDir=${scriptDir} buildType=Release configArgs="-DCMAKE_BUILD_TYPE=${buildType}" +if [[ "$(uname)" == MINGW* ]] || [[ "$(uname)" == CYGWIN* ]]; then + echo "TODO flatcc temporarily disabled on Windows, see https://github.com/dvidelabs/flatcc/issues/155" + exit 0 + configArgs+=' -G "MinGW Makefiles"' +fi + function prepare() { echo "******** Getting Flatcc sources ********" if [[ ! -d ${srcDir} ]]; then From d723900ce79859ab697b2476c1a1cac6abe3fc98 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 17:01:11 +0200 Subject: [PATCH 15/21] fbsC test - close written file before reading --- internal/generator/flatbuffersc/fbsc_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/generator/flatbuffersc/fbsc_test.go b/internal/generator/flatbuffersc/fbsc_test.go index 31f10a65..1d3b724d 100644 --- a/internal/generator/flatbuffersc/fbsc_test.go +++ b/internal/generator/flatbuffersc/fbsc_test.go @@ -65,6 +65,7 @@ func TestFbsSchemaParser(t *testing.T) { _, err = file.WriteString(testSchema) assert.NoErr(t, err) + assert.NoErr(t, file.Close()) schema, err = ParseSchemaFile(file.Name()) assert.NoErr(t, err) @@ -123,6 +124,7 @@ func TestFbsFlatc(t *testing.T) { _, err = file.WriteString(testSchema) assert.NoErr(t, err) + assert.NoErr(t, file.Close()) code, err = ExecuteFlatc([]string{"--go", "-o", outDir, file.Name()}) assert.NoErr(t, err) From 15c3f86872ae608aae2ebf83fa38230803c8d40f Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 17:03:09 +0200 Subject: [PATCH 16/21] CI - split up make calls to separate steps --- .github/workflows/ci.yml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d3f35a9..f49c6282 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,10 @@ name: CI on: [push, pull_request] +defaults: + run: + shell: bash + jobs: build-linux: runs-on: ubuntu-latest @@ -34,11 +38,9 @@ jobs: path: ./third_party/* key: ${{ runner.os }}-deps-${{ hashFiles('./third_party/*') }} - - name: Build & Test - run: | - make - make test-depend - make test + - run: make + - run: make test-depend + - run: make test - name: Upload artifact uses: actions/upload-artifact@v2 @@ -63,12 +65,9 @@ jobs: path: ./third_party/* key: ${{ runner.os }}-deps-${{ hashFiles('./third_party/*') }} - - name: Build & Test - shell: bash - run: | - make - make test-depend - make test + - run: make + - run: make test-depend + - run: make test - name: Upload artifact uses: actions/upload-artifact@v2 From d3983afc18e7476751b3375f37733f80e1c897af Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 17:08:44 +0200 Subject: [PATCH 17/21] change LibraryExists to use cpp11 explicitly to fix macOS compilation --- test/cmake/libcheck.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cmake/libcheck.go b/test/cmake/libcheck.go index f0a9ea79..1c3b6231 100644 --- a/test/cmake/libcheck.go +++ b/test/cmake/libcheck.go @@ -30,6 +30,7 @@ func LibraryExists(name string, includeFiles, includeDirs, linkDirs []string) er build := Cmake{ Name: "check-" + name, IsCpp: true, + Standard: 11, Files: []string{"main.cpp"}, IncludeDirs: includeDirs, LinkDirs: linkDirs, From 2db05656e7764ebd57b6ca25d05de6f6880d7b7d Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 17:28:36 +0200 Subject: [PATCH 18/21] disable autocrlf in windows CI --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f49c6282..0b3fa91f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,8 @@ jobs: - macos-10.15 runs-on: ${{ matrix.os }} steps: + - run: git config --global core.autocrlf false + - name: Get sources uses: actions/checkout@v2 From 7a7239261c4916ffcbc3f6ae6177760979eedd19 Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 17:42:04 +0200 Subject: [PATCH 19/21] CI - launch verbose test and make compilation mandatory --- test/comparison/c-helper.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index 104584c9..bcd57c68 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -21,8 +21,10 @@ package comparison import ( "io/ioutil" + "os" "path" "path/filepath" + "runtime" "testing" "github.com/objectbox/objectbox-generator/internal/generator" @@ -40,6 +42,16 @@ type cTestHelper struct { func (h *cTestHelper) init(t *testing.T, conf testSpec) { if !testing.Short() { var mandatory = h.cpp // we require cpp compilation to be available at the moment + if _, isCI := os.LookupEnv("CI"); isCI { + t.Log("CI environment variable defined. Compilation support is mandatory.") + + // TODO remove the exception + // C build is temporarily not mandatory on Windows due to https://github.com/dvidelabs/flatcc/issues/155 + if runtime.GOOS != "windows" { + mandatory = true + } + } + h.canCompile = build.CanCompileObjectBoxCCpp(t, repoRoot(t), h.cpp, mandatory) } } From da24fc16fb75253a0ac7247a09954c8a1e28e04b Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 18:41:58 +0200 Subject: [PATCH 20/21] flatcc - use generic aligned alloc, mingw doesn't have one --- test/comparison/c-helper.go | 8 +------- third_party/flatcc/build.sh | 14 +++++++++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/test/comparison/c-helper.go b/test/comparison/c-helper.go index bcd57c68..6404ea11 100644 --- a/test/comparison/c-helper.go +++ b/test/comparison/c-helper.go @@ -24,7 +24,6 @@ import ( "os" "path" "path/filepath" - "runtime" "testing" "github.com/objectbox/objectbox-generator/internal/generator" @@ -44,12 +43,7 @@ func (h *cTestHelper) init(t *testing.T, conf testSpec) { var mandatory = h.cpp // we require cpp compilation to be available at the moment if _, isCI := os.LookupEnv("CI"); isCI { t.Log("CI environment variable defined. Compilation support is mandatory.") - - // TODO remove the exception - // C build is temporarily not mandatory on Windows due to https://github.com/dvidelabs/flatcc/issues/155 - if runtime.GOOS != "windows" { - mandatory = true - } + mandatory = true } h.canCompile = build.CanCompileObjectBoxCCpp(t, repoRoot(t), h.cpp, mandatory) diff --git a/third_party/flatcc/build.sh b/third_party/flatcc/build.sh index 3edc0208..939adb46 100755 --- a/third_party/flatcc/build.sh +++ b/third_party/flatcc/build.sh @@ -13,9 +13,9 @@ buildType=Release configArgs="-DCMAKE_BUILD_TYPE=${buildType}" if [[ "$(uname)" == MINGW* ]] || [[ "$(uname)" == CYGWIN* ]]; then - echo "TODO flatcc temporarily disabled on Windows, see https://github.com/dvidelabs/flatcc/issues/155" - exit 0 configArgs+=' -G "MinGW Makefiles"' + echo "aligned_alloc() would be missing on MinGW, see https://github.com/dvidelabs/flatcc/issues/155" + export CFLAGS="-DFLATCC_USE_GENERIC_ALIGNED_ALLOC=1" fi function prepare() { @@ -33,7 +33,15 @@ function prepare() { function build() { echo "******** Configuring & building ********" - srcDirAbsolute="$(pwd)/$srcDir" + # Note: we need an absolute path... + # realpath isn't available on macOS and the "else" variant didn't work well on windows because the path was already absolute... + srcDirAbsolute= + if [[ -x $(command -v realpath) ]]; then + srcDirAbsolute=$(realpath "$srcDir") + else + srcDirAbsolute="$(pwd)/$srcDir" + fi + pwd=$(pwd) mkdir -p "$buildDir" From ea45674a174064dafcbae2c35352ca4baa900acb Mon Sep 17 00:00:00 2001 From: Ivan Dlugos Date: Mon, 22 Jun 2020 19:05:46 +0200 Subject: [PATCH 21/21] flatcc build.sh comment instead of echo --- third_party/flatcc/build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/third_party/flatcc/build.sh b/third_party/flatcc/build.sh index 939adb46..fe96056a 100755 --- a/third_party/flatcc/build.sh +++ b/third_party/flatcc/build.sh @@ -14,7 +14,8 @@ configArgs="-DCMAKE_BUILD_TYPE=${buildType}" if [[ "$(uname)" == MINGW* ]] || [[ "$(uname)" == CYGWIN* ]]; then configArgs+=' -G "MinGW Makefiles"' - echo "aligned_alloc() would be missing on MinGW, see https://github.com/dvidelabs/flatcc/issues/155" + # aligned_alloc() would be missing on MinGW, see https://github.com/dvidelabs/flatcc/issues/155 + # It's fixed now on master, the following line can be removed after upgrading to a new release export CFLAGS="-DFLATCC_USE_GENERIC_ALIGNED_ALLOC=1" fi