aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2019-04-07 15:40:03 +0200
committerRon Evans <[email protected]>2019-04-11 11:53:58 +0200
commit315cd4059fd38be4c078a5974556e5d120d1662a (patch)
tree934a64bc4834ca751a7c66d2c5caa1fd83f94674
parent078dd9ff5236e40bfd530f8418d72916ce111e33 (diff)
downloadtinygo-315cd4059fd38be4c078a5974556e5d120d1662a.tar.gz
tinygo-315cd4059fd38be4c078a5974556e5d120d1662a.zip
main: drop the dependency on llvm-ar
The ar file format is pretty simple and can be implemented by using a Go library. Use that instead of calling out to llvm-ar. There are a few limitations to the used package, but that doesn't seem to matter for our use case (linking compiler-rt for use with ld.lld): * no index is created * long filenames are truncated * no support for archives bigger than 4GB
-rw-r--r--.circleci/config.yml2
-rw-r--r--Gopkg.lock9
-rw-r--r--builtins.go48
-rw-r--r--commands.go1
-rw-r--r--commands_macos.go1
5 files changed, 51 insertions, 10 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index bc71b59d1..adb28790b 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -154,7 +154,6 @@ commands:
name: "Create LLVM symlinks"
command: |
ln -s $PWD/llvm-build/bin/clang-8 /go/bin/clang-8
- ln -s $PWD/llvm-build/bin/llvm-ar /go/bin/llvm-ar-8
ln -s $PWD/llvm-build/bin/ld.lld /go/bin/ld.lld-8
ln -s $PWD/llvm-build/bin/wasm-ld /go/bin/wasm-ld-8
- dep
@@ -220,7 +219,6 @@ commands:
name: "Create LLVM symlinks"
command: |
ln -s $PWD/llvm-build/bin/clang-8 /usr/local/bin/clang-8
- ln -s $PWD/llvm-build/bin/llvm-ar /usr/local/bin/llvm-ar
- run:
name: "Install Go dependencies"
command: dep ensure --vendor-only
diff --git a/Gopkg.lock b/Gopkg.lock
index 4cf9b0f8e..e6e7dba1e 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -3,6 +3,14 @@
[[projects]]
branch = "master"
+ digest = "1:06519a2ec1d59040eaccec40206f9d0b59dc662db2a032f974d6d6b9a2bcb839"
+ name = "github.com/blakesmith/ar"
+ packages = ["."]
+ pruneopts = "UT"
+ revision = "8bd4349a67f2533b078dbc524689d15dba0f4659"
+
+[[projects]]
+ branch = "master"
digest = "1:00b45e06c7843541372fc17d982242bd6adfc2fc382b6f2e9ef9ce53d87a50b9"
name = "github.com/marcinbor85/gohex"
packages = ["."]
@@ -33,6 +41,7 @@
analyzer-name = "dep"
analyzer-version = 1
input-imports = [
+ "github.com/blakesmith/ar",
"github.com/marcinbor85/gohex",
"golang.org/x/tools/go/ast/astutil",
"golang.org/x/tools/go/ssa",
diff --git a/builtins.go b/builtins.go
index 2ec155884..a34001a77 100644
--- a/builtins.go
+++ b/builtins.go
@@ -1,11 +1,16 @@
package main
import (
+ "errors"
+ "io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
+ "time"
+
+ "github.com/blakesmith/ar"
)
// These are the GENERIC_SOURCES according to CMakeList.txt.
@@ -246,14 +251,45 @@ func compileBuiltins(target string, callback func(path string) error) error {
}
// Put all builtins in an archive to link as a static library.
+ // Note: this does not create a symbol index, but ld.lld doesn't seem to
+ // care.
arpath := filepath.Join(dir, "librt.a")
- cmd := exec.Command(commands["ar"], append([]string{"cr", arpath}, objs...)...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- cmd.Dir = dir
- err = cmd.Run()
+ arfile, err := os.Create(arpath)
+ if err != nil {
+ return err
+ }
+ defer arfile.Close()
+ arwriter := ar.NewWriter(arfile)
+ err = arwriter.WriteGlobalHeader()
if err != nil {
- return &commandError{"failed to make static library", arpath, err}
+ return &os.PathError{"write ar header", arpath, err}
+ }
+ for _, objpath := range objs {
+ name := filepath.Base(objpath)
+ objfile, err := os.Open(objpath)
+ if err != nil {
+ return err
+ }
+ defer objfile.Close()
+ st, err := objfile.Stat()
+ if err != nil {
+ return err
+ }
+ arwriter.WriteHeader(&ar.Header{
+ Name: name,
+ ModTime: time.Unix(0, 0),
+ Uid: 0,
+ Gid: 0,
+ Mode: 0644,
+ Size: st.Size(),
+ })
+ n, err := io.Copy(arwriter, objfile)
+ if err != nil {
+ return err
+ }
+ if n != st.Size() {
+ return errors.New("file modified during ar creation: " + arpath)
+ }
}
// Give the caller the resulting file. The callback must copy the file,
diff --git a/commands.go b/commands.go
index 8fb9d13da..a975b5b2c 100644
--- a/commands.go
+++ b/commands.go
@@ -4,7 +4,6 @@ package main
// commands used by the compilation process might have different file names on Linux than those used on macOS.
var commands = map[string]string{
- "ar": "llvm-ar-8",
"clang": "clang-8",
"ld.lld": "ld.lld-8",
"wasm-ld": "wasm-ld-8",
diff --git a/commands_macos.go b/commands_macos.go
index e457ba886..9ec428ec6 100644
--- a/commands_macos.go
+++ b/commands_macos.go
@@ -4,7 +4,6 @@ package main
// commands used by the compilation process might have different file names on macOS than those used on Linux.
var commands = map[string]string{
- "ar": "llvm-ar",
"clang": "clang-8",
"ld.lld": "ld.lld",
"wasm-ld": "wasm-ld",