diff --git a/.circleci/config.yml b/.circleci/config.yml index babdb9fc..982ceb42 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,6 +47,18 @@ commands: command: | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh dep ensure --vendor-only + llvm-source-linux: + steps: + - restore_cache: + keys: + - llvm-source-8-v2 + - run: + name: "Fetch LLVM source" + command: make llvm-source + - save_cache: + key: llvm-source-8-v2 + paths: + - llvm smoketest: steps: - smoketest-no-avr @@ -86,6 +98,7 @@ commands: keys: - go-cache-{{ checksum "Gopkg.lock" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }} - go-cache-{{ checksum "Gopkg.lock" }} + - llvm-source-linux - dep - run: go install . - run: go test -v @@ -121,16 +134,7 @@ commands: keys: - go-cache-{{ checksum "Gopkg.lock" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }} - go-cache-{{ checksum "Gopkg.lock" }} - - restore_cache: - keys: - - llvm-source-8-v2 - - run: - name: "Fetch LLVM source" - command: make llvm-source - - save_cache: - key: llvm-source-8-v2 - paths: - - llvm + - llvm-source-linux - restore_cache: keys: - llvm-build-8-v2 diff --git a/Makefile b/Makefile index e5145b8a..ea96730a 100644 --- a/Makefile +++ b/Makefile @@ -86,13 +86,16 @@ test: release: build/tinygo gen-device @mkdir -p build/release/tinygo/bin + @mkdir -p build/release/tinygo/lib/clang/include @mkdir -p build/release/tinygo/lib/CMSIS/CMSIS @mkdir -p build/release/tinygo/lib/compiler-rt/lib @mkdir -p build/release/tinygo/lib/nrfx @mkdir -p build/release/tinygo/pkg/armv6m-none-eabi @mkdir -p build/release/tinygo/pkg/armv7m-none-eabi @mkdir -p build/release/tinygo/pkg/armv7em-none-eabi + @echo copying source files @cp -p build/tinygo build/release/tinygo/bin + @cp -p $(abspath $(CLANG_SRC))/lib/Headers/*.h build/release/tinygo/lib/clang/include @cp -rp lib/CMSIS/CMSIS/Include build/release/tinygo/lib/CMSIS/CMSIS @cp -rp lib/CMSIS/README.md build/release/tinygo/lib/CMSIS @cp -rp lib/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt/lib diff --git a/compiler/compiler.go b/compiler/compiler.go index 4c686556..0a61d9b1 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -217,8 +217,9 @@ func (c *Compiler) Compile(mainPath string) error { MaxAlign: int64(c.targetData.PrefTypeAlignment(c.i8ptrType)), }, }, - Dir: wd, - CFlags: c.CFlags, + Dir: wd, + TinyGoRoot: c.RootDir, + CFlags: c.CFlags, } if strings.HasSuffix(mainPath, ".go") { _, err = lprogram.ImportFile(mainPath) diff --git a/loader/loader.go b/loader/loader.go index 2d15a060..4e57b39b 100644 --- a/loader/loader.go +++ b/loader/loader.go @@ -22,6 +22,7 @@ type Program struct { fset *token.FileSet TypeChecker types.Config Dir string // current working directory (for error reporting) + TinyGoRoot string // root of the TinyGo installation or root of the source code CFlags []string } @@ -292,6 +293,16 @@ func (p *Package) parseFiles() ([]*ast.File, error) { } files = append(files, f) } + clangIncludes := "" + if len(p.CgoFiles) != 0 { + if _, err := os.Stat(filepath.Join(p.TinyGoRoot, "llvm", "tools", "clang", "lib", "Headers")); !os.IsNotExist(err) { + // Running from the source directory. + clangIncludes = filepath.Join(p.TinyGoRoot, "llvm", "tools", "clang", "lib", "Headers") + } else { + // Running from the installation directory. + clangIncludes = filepath.Join(p.TinyGoRoot, "lib", "clang", "include") + } + } for _, file := range p.CgoFiles { path := filepath.Join(p.Package.Dir, file) f, err := p.parseFile(path, parser.ParseComments) @@ -299,7 +310,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) { fileErrs = append(fileErrs, err) continue } - errs := p.processCgo(path, f, append(p.CFlags, "-I"+p.Package.Dir)) + errs := p.processCgo(path, f, append(p.CFlags, "-I"+p.Package.Dir, "-I"+clangIncludes)) if errs != nil { fileErrs = append(fileErrs, errs...) continue diff --git a/targets/cortex-m.json b/targets/cortex-m.json index 0e11034a..eaba1595 100644 --- a/targets/cortex-m.json +++ b/targets/cortex-m.json @@ -9,7 +9,10 @@ "cflags": [ "-Oz", "-mthumb", + "-Werror", "-fshort-enums", + "-nostdlibinc", + "-Wno-macro-redefined", "-fno-exceptions", "-fno-unwind-tables", "-ffunction-sections", "-fdata-sections" ], diff --git a/targets/wasm.json b/targets/wasm.json index 06988a53..8b5ed855 100644 --- a/targets/wasm.json +++ b/targets/wasm.json @@ -7,6 +7,8 @@ "linker": "wasm-ld", "cflags": [ "--target=wasm32", + "-nostdlibinc", + "-Wno-macro-redefined", "-Oz" ], "ldflags": [ diff --git a/testdata/cgo/main.c b/testdata/cgo/main.c index 6f52749f..d62c1dea 100644 --- a/testdata/cgo/main.c +++ b/testdata/cgo/main.c @@ -1,8 +1,8 @@ #include "main.h" int global = 3; -_Bool globalBool = 1; -_Bool globalBool2 = 10; // test narrowing +bool globalBool = 1; +bool globalBool2 = 10; // test narrowing float globalFloat = 3.1; double globalDouble = 3.2; _Complex float globalComplexFloat = 4.1+3.3i; @@ -11,6 +11,7 @@ _Complex double globalComplexLongDouble = 4.3+3.5i; char globalChar = 100; void *globalVoidPtrSet = &global; void *globalVoidPtrNull; +int64_t globalInt64 = -(2LL << 40); collection_t globalStruct = {256, -123456, 3.14, 88}; int globalStructSize = sizeof(globalStruct); short globalArray[3] = {5, 6, 7}; diff --git a/testdata/cgo/main.go b/testdata/cgo/main.go index 0e85fc09..07eb76e3 100644 --- a/testdata/cgo/main.go +++ b/testdata/cgo/main.go @@ -43,6 +43,7 @@ func main() { println("char match:", C.globalChar == 100) var voidPtr unsafe.Pointer = C.globalVoidPtrNull println("void* match:", voidPtr == nil, C.globalVoidPtrNull == nil, (*C.int)(C.globalVoidPtrSet) == &C.global) + println("int64_t match:", C.globalInt64 == C.int64_t(-(2<<40))) // complex types println("struct:", C.int(unsafe.Sizeof(C.globalStruct)) == C.globalStructSize, C.globalStruct.s, C.globalStruct.l, C.globalStruct.f) diff --git a/testdata/cgo/main.h b/testdata/cgo/main.h index a7b3b75a..7eeb2c33 100644 --- a/testdata/cgo/main.h +++ b/testdata/cgo/main.h @@ -1,3 +1,6 @@ +#include +#include + typedef short myint; int add(int a, int b); typedef int (*binop_t) (int, int); @@ -27,10 +30,10 @@ void unionSetShort(short s); void unionSetFloat(float f); void unionSetData(short f0, short f1, short f2); -// test globals +// test globals and datatypes extern int global; -extern _Bool globalBool; -extern _Bool globalBool2; +extern bool globalBool; +extern bool globalBool2; extern float globalFloat; extern double globalDouble; extern _Complex float globalComplexFloat; @@ -39,6 +42,7 @@ extern _Complex double globalComplexLongDouble; extern char globalChar; extern void *globalVoidPtrSet; extern void *globalVoidPtrNull; +extern int64_t globalInt64; extern collection_t globalStruct; extern int globalStructSize; extern short globalArray[3]; diff --git a/testdata/cgo/out.txt b/testdata/cgo/out.txt index 2e799e60..9b193c5d 100644 --- a/testdata/cgo/out.txt +++ b/testdata/cgo/out.txt @@ -16,6 +16,7 @@ complex double: (+4.200000e+000+3.400000e+000i) complex long double: (+4.300000e+000+3.500000e+000i) char match: true void* match: true true true +int64_t match: true struct: true 256 -123456 +3.140000e+000 array: 5 6 7 union: true