From 15679891428d23a73d26a42164fbaeab942d4849 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Wed, 24 Apr 2024 11:49:43 +0800 Subject: [PATCH] llgo install: use clang to link --- internal/build/build_install.go | 22 +++++++++++----- x/clang/clang.go | 46 +++++++++++++++++++++++++++++++++ x/llexportdata/llexportdata.go | 40 ---------------------------- 3 files changed, 62 insertions(+), 46 deletions(-) create mode 100644 x/clang/clang.go delete mode 100644 x/llexportdata/llexportdata.go diff --git a/internal/build/build_install.go b/internal/build/build_install.go index 9c968d67..166fcaf8 100644 --- a/internal/build/build_install.go +++ b/internal/build/build_install.go @@ -28,6 +28,7 @@ import ( "github.com/goplus/llgo/cl" llssa "github.com/goplus/llgo/ssa" + "github.com/goplus/llgo/x/clang" ) type Mode int @@ -60,8 +61,7 @@ func Do(args []string, mode Mode) { check(err) // Create SSA-form program representation. - ssaProg, pkgs, errPkgs := allPkgs(initial, ssa.SanityCheckFunctions) - ssaProg.Build() + _, pkgs, errPkgs := allPkgs(initial, ssa.SanityCheckFunctions) for _, errPkg := range errPkgs { log.Println("cannot build SSA for package", errPkg) } @@ -71,22 +71,32 @@ func Do(args []string, mode Mode) { // cl.SetDebug(cl.DbgFlagAll) prog := llssa.NewProgram(nil) + llFiles := make([]string, 0, len(pkgs)) for _, pkg := range pkgs { - buildPkg(prog, pkg, mode) + pkg.SSA.Build() + llFiles = buildPkg(llFiles, prog, pkg, mode) + } + if mode == ModeInstall { + fmt.Fprintln(os.Stderr, "clang", llFiles) + err = clang.New("").Exec(llFiles...) + check(err) } } -func buildPkg(prog llssa.Program, pkg aPackage, mode Mode) { +func buildPkg(llFiles []string, prog llssa.Program, pkg aPackage, mode Mode) []string { pkgPath := pkg.PkgPath fmt.Fprintln(os.Stderr, pkgPath) if pkgPath == "unsafe" { // TODO(xsw): remove this special case - return + return llFiles } ret, err := cl.NewPackage(prog, pkg.SSA, pkg.Syntax) check(err) if mode == ModeInstall { - os.WriteFile(pkg.ExportFile+".ll", []byte(ret.String()), 0644) + file := pkg.ExportFile + ".ll" + os.WriteFile(file, []byte(ret.String()), 0644) + llFiles = append(llFiles, file) } + return llFiles } type aPackage struct { diff --git a/x/clang/clang.go b/x/clang/clang.go new file mode 100644 index 00000000..eeda4758 --- /dev/null +++ b/x/clang/clang.go @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package clang + +import ( + "os" + "os/exec" +) + +// ----------------------------------------------------------------------------- + +// Cmd represents a nm command. +type Cmd struct { + app string +} + +// New creates a new nm command. +func New(app string) *Cmd { + if app == "" { + app = "clang" + } + return &Cmd{app} +} + +func (p *Cmd) Exec(args ...string) error { + cmd := exec.Command(p.app, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +// ----------------------------------------------------------------------------- diff --git a/x/llexportdata/llexportdata.go b/x/llexportdata/llexportdata.go deleted file mode 100644 index 59bc05bf..00000000 --- a/x/llexportdata/llexportdata.go +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package llexportdata - -import ( - "go/token" - "go/types" - "io" -) - -// Read reads export data from in, decodes it, and returns type information for the package. -// -// The package path (effectively its linker symbol prefix) is specified by path, since unlike -// the package name, this information may not be recorded in the export data. -// -// File position information is added to fset. -// -// Read may inspect and add to the imports map to ensure that references within the export data -// to other packages are consistent. The caller must ensure that imports[path] does not exist, -// or exists but is incomplete (see types.Package.Complete), and Read inserts the resulting package -// into this map entry. -// -// On return, the state of the reader is undefined. -func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { - panic("todo") -}