github.com/goplus/igop@v0.17.0/pkg/gen.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  /*
     5   * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved.
     6   *
     7   * Licensed under the Apache License, Version 2.0 (the "License");
     8   * you may not use this file except in compliance with the License.
     9   * You may obtain a copy of the License at
    10   *
    11   *     http://www.apache.org/licenses/LICENSE-2.0
    12   *
    13   * Unless required by applicable law or agreed to in writing, software
    14   * distributed under the License is distributed on an "AS IS" BASIS,
    15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16   * See the License for the specific language governing permissions and
    17   * limitations under the License.
    18   */
    19  
    20  package main
    21  
    22  import (
    23  	"fmt"
    24  	"go/format"
    25  	"io/ioutil"
    26  	"log"
    27  	"os"
    28  	"os/exec"
    29  	"runtime"
    30  	"strings"
    31  )
    32  
    33  func main() {
    34  	ver := runtime.Version()[:6]
    35  	var tags string
    36  	var name string
    37  	var fname string
    38  	switch ver {
    39  	case "go1.20":
    40  		tags = "//+build go1.20"
    41  		name = "go120_export"
    42  		fname = "go120_pkgs.go"
    43  	case "go1.19":
    44  		tags = "//+build go1.19,!go1.20"
    45  		name = "go119_export"
    46  		fname = "go119_pkgs.go"
    47  	case "go1.18":
    48  		tags = "//+build go1.18,!go1.19"
    49  		name = "go118_export"
    50  		fname = "go118_pkgs.go"
    51  	case "go1.17":
    52  		tags = "//+build go1.17,!go1.18"
    53  		name = "go117_export"
    54  		fname = "go117_pkgs.go"
    55  	case "go1.16":
    56  		tags = "//+build go1.16,!go1.17"
    57  		name = "go116_export"
    58  		fname = "go116_pkgs.go"
    59  	case "go1.15":
    60  		tags = "//+build go1.15,!go1.16"
    61  		name = "go115_export"
    62  		fname = "go115_pkgs.go"
    63  	case "go1.14":
    64  		tags = "//+build go1.14,!go1.15"
    65  		name = "go114_export"
    66  		fname = "go114_pkgs.go"
    67  	}
    68  
    69  	pkgs := stdList()
    70  
    71  	log.Println(ver, name, tags)
    72  	log.Println(pkgs)
    73  
    74  	cmd := exec.Command("qexp", "-outdir", ".", "-addtags", tags, "-filename", name)
    75  	cmd.Args = append(cmd.Args, pkgs...)
    76  	cmd.Stderr = os.Stderr
    77  	cmd.Stdout = os.Stdout
    78  	err := cmd.Run()
    79  	if err != nil {
    80  		panic(err)
    81  	}
    82  	// sync/atomic
    83  	cmd = exec.Command("qexp", "-outdir", ".", "-addtags", tags, "-filename", name, "-src", "sync/atomic")
    84  	cmd.Stderr = os.Stderr
    85  	cmd.Stdout = os.Stdout
    86  	err = cmd.Run()
    87  	if err != nil {
    88  		panic(err)
    89  	}
    90  
    91  	list := osarchList()
    92  	log.Println(list)
    93  	for _, osarch := range list {
    94  		ar := strings.Split(osarch, "_")
    95  		if len(ar) != 2 {
    96  			continue
    97  		}
    98  		cmd := exec.Command("qexp", "-outdir", ".", "-addtags", tags, "-filename", name, "-contexts", osarch, "syscall")
    99  		cmd.Stderr = os.Stderr
   100  		cmd.Stdout = os.Stdout
   101  		cmd.Env = os.Environ()
   102  		cmd.Env = append(cmd.Env, "GOOS="+ar[0])
   103  		cmd.Env = append(cmd.Env, "GOARCH="+ar[1])
   104  		cmd.Env = append(cmd.Env, "GOEXPERIMENT=noregabi")
   105  		err := cmd.Run()
   106  		if err != nil {
   107  			panic(err)
   108  		}
   109  		err = makepkg("./"+fname, []string{tags}, pkgs)
   110  		if err != nil {
   111  			panic(err)
   112  		}
   113  	}
   114  }
   115  
   116  func makepkg(fname string, tags []string, std []string) error {
   117  	//_ github.com/goplus/igop/pkg
   118  	var pkgs []string
   119  	for _, v := range std {
   120  		if strings.HasPrefix(v, "testing/") {
   121  			continue
   122  		}
   123  		if v == "log/syslog" || v == "net/rpc" || v == "net/rpc/jsonrpc" {
   124  			continue
   125  		}
   126  		pkgs = append(pkgs, fmt.Sprintf(`_ "github.com/goplus/igop/pkg/%v"`, v))
   127  	}
   128  	pkgs = append(pkgs, fmt.Sprintf(`_ "github.com/goplus/igop/pkg/syscall"`))
   129  	r := strings.NewReplacer("$TAGS", strings.Join(tags, "\n"), "$PKGS", strings.Join(pkgs, "\t\n"))
   130  	src := r.Replace(tmpl)
   131  	data, err := format.Source([]byte(src))
   132  	if err != nil {
   133  		return err
   134  	}
   135  	return ioutil.WriteFile(fname, []byte(data), 0644)
   136  }
   137  
   138  var tmpl = `$TAGS
   139  
   140  package pkg
   141  
   142  import (
   143  	$PKGS
   144  )
   145  `
   146  
   147  // skip syscall
   148  func stdList() []string {
   149  	cmd := exec.Command("go", "list", "std")
   150  	data, err := cmd.Output()
   151  	if err != nil {
   152  		panic(err)
   153  	}
   154  	var ar []string
   155  	for _, v := range strings.Split(string(data), "\n") {
   156  		if v == "" {
   157  			continue
   158  		}
   159  		if isSkipPkg(v) {
   160  			continue
   161  		}
   162  		ar = append(ar, v)
   163  	}
   164  	return ar
   165  }
   166  
   167  func isSkipPkg(pkg string) bool {
   168  	switch pkg {
   169  	case "syscall", "unsafe":
   170  		return true
   171  	case "sync/atomc":
   172  		return true
   173  	case "runtime/cgo", "runtime/race":
   174  		return true
   175  	default:
   176  		if strings.HasPrefix(pkg, "vendor/") {
   177  			return true
   178  		}
   179  		for _, v := range strings.Split(pkg, "/") {
   180  			if v == "internal" {
   181  				return true
   182  			}
   183  		}
   184  	}
   185  	return false
   186  }
   187  
   188  // aix_ppc64 android_386 android_amd64
   189  func checkRegAbi(list []string, ver string) (regabi []string, noregabi []string) {
   190  	for _, v := range list {
   191  		ar := strings.Split(v, "_")
   192  		if len(ar) != 2 {
   193  			continue
   194  		}
   195  		switch ver {
   196  		case "go1.17":
   197  			if ar[1] == "amd64" {
   198  				regabi = append(regabi, v)
   199  				continue
   200  			}
   201  		case "go1.18":
   202  			switch ar[1] {
   203  			case "amd64", "arm64", "ppc64", "ppc64le":
   204  				regabi = append(regabi, v)
   205  				continue
   206  			}
   207  		case "go1.19":
   208  			switch ar[1] {
   209  			case "amd64", "arm64", "ppc64", "ppc64le", "riscv64":
   210  				regabi = append(regabi, v)
   211  				continue
   212  			}
   213  		}
   214  		noregabi = append(noregabi, v)
   215  	}
   216  	return
   217  }
   218  
   219  func osarchList() []string {
   220  	//go tool dist list
   221  	cmd := exec.Command("go", "tool", "dist", "list")
   222  	data, err := cmd.Output()
   223  	if err != nil {
   224  		panic(err)
   225  	}
   226  	var ar []string
   227  	for _, v := range strings.Split(string(data), "\n") {
   228  		if v == "" {
   229  			continue
   230  		}
   231  		ar = append(ar, strings.Replace(v, "/", "_", 1))
   232  	}
   233  	return ar
   234  }