github.com/goplus/igop@v0.25.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.21": 40 tags = "//+build go1.21" 41 name = "go121_export" 42 fname = "go121_pkgs.go" 43 case "go1.20": 44 tags = "//+build go1.20,!go1.21" 45 name = "go120_export" 46 fname = "go120_pkgs.go" 47 case "go1.19": 48 tags = "//+build go1.19,!go1.20" 49 name = "go119_export" 50 fname = "go119_pkgs.go" 51 case "go1.18": 52 tags = "//+build go1.18,!go1.19" 53 name = "go118_export" 54 fname = "go118_pkgs.go" 55 case "go1.17": 56 tags = "//+build go1.17,!go1.18" 57 name = "go117_export" 58 fname = "go117_pkgs.go" 59 case "go1.16": 60 tags = "//+build go1.16,!go1.17" 61 name = "go116_export" 62 fname = "go116_pkgs.go" 63 case "go1.15": 64 tags = "//+build go1.15,!go1.16" 65 name = "go115_export" 66 fname = "go115_pkgs.go" 67 case "go1.14": 68 tags = "//+build go1.14,!go1.15" 69 name = "go114_export" 70 fname = "go114_pkgs.go" 71 } 72 73 pkgs := stdList() 74 75 log.Println(ver, name, tags) 76 log.Println(pkgs) 77 78 cmd := exec.Command("qexp", "-outdir", ".", "-addtags", tags, "-filename", name) 79 cmd.Args = append(cmd.Args, pkgs...) 80 cmd.Stderr = os.Stderr 81 cmd.Stdout = os.Stdout 82 err := cmd.Run() 83 if err != nil { 84 panic(err) 85 } 86 87 gpkgs := genericPkgs(pkgs) 88 // sync/atomic 89 cmd = exec.Command("qexp", "-outdir", ".", "-addtags", tags, "-filename", name, "-src") 90 cmd.Args = append(cmd.Args, gpkgs...) 91 cmd.Stderr = os.Stderr 92 cmd.Stdout = os.Stdout 93 err = cmd.Run() 94 if err != nil { 95 panic(err) 96 } 97 98 list := osarchList() 99 log.Println(list) 100 for _, osarch := range list { 101 ar := strings.Split(osarch, "_") 102 if len(ar) != 2 { 103 continue 104 } 105 cmd := exec.Command("qexp", "-outdir", ".", "-addtags", tags, "-filename", name, "-contexts", osarch, "syscall") 106 cmd.Stderr = os.Stderr 107 cmd.Stdout = os.Stdout 108 cmd.Env = os.Environ() 109 cmd.Env = append(cmd.Env, "GOOS="+ar[0]) 110 cmd.Env = append(cmd.Env, "GOARCH="+ar[1]) 111 cmd.Env = append(cmd.Env, "GOEXPERIMENT=noregabi") 112 err := cmd.Run() 113 if err != nil { 114 panic(err) 115 } 116 err = makepkg("./"+fname, []string{tags}, pkgs) 117 if err != nil { 118 panic(err) 119 } 120 } 121 } 122 123 var genericList = []string{ 124 "sync/atomic", 125 "maps", 126 "slices", 127 "cmp", 128 } 129 130 func genericPkgs(std []string) (pkgs []string) { 131 for _, pkg := range std { 132 for _, v := range genericList { 133 if pkg == v { 134 pkgs = append(pkgs, v) 135 } 136 } 137 } 138 return 139 } 140 141 func makepkg(fname string, tags []string, std []string) error { 142 //_ github.com/goplus/igop/pkg 143 var pkgs []string 144 for _, v := range std { 145 if strings.HasPrefix(v, "testing/") { 146 continue 147 } 148 if v == "log/syslog" || v == "net/rpc" || v == "net/rpc/jsonrpc" { 149 continue 150 } 151 pkgs = append(pkgs, fmt.Sprintf(`_ "github.com/goplus/igop/pkg/%v"`, v)) 152 } 153 pkgs = append(pkgs, fmt.Sprintf(`_ "github.com/goplus/igop/pkg/syscall"`)) 154 r := strings.NewReplacer("$TAGS", strings.Join(tags, "\n"), "$PKGS", strings.Join(pkgs, "\t\n")) 155 src := r.Replace(tmpl) 156 data, err := format.Source([]byte(src)) 157 if err != nil { 158 return err 159 } 160 return ioutil.WriteFile(fname, []byte(data), 0644) 161 } 162 163 var tmpl = `$TAGS 164 165 package pkg 166 167 import ( 168 $PKGS 169 ) 170 ` 171 172 // skip syscall 173 func stdList() []string { 174 cmd := exec.Command("go", "list", "std") 175 data, err := cmd.Output() 176 if err != nil { 177 panic(err) 178 } 179 var ar []string 180 for _, v := range strings.Split(string(data), "\n") { 181 if v == "" { 182 continue 183 } 184 if isSkipPkg(v) { 185 continue 186 } 187 ar = append(ar, v) 188 } 189 return ar 190 } 191 192 func isSkipPkg(pkg string) bool { 193 switch pkg { 194 case "syscall", "unsafe": 195 return true 196 case "runtime/cgo", "runtime/race": 197 return true 198 default: 199 if strings.HasPrefix(pkg, "vendor/") { 200 return true 201 } 202 for _, v := range strings.Split(pkg, "/") { 203 if v == "internal" { 204 return true 205 } 206 } 207 } 208 return false 209 } 210 211 // aix_ppc64 android_386 android_amd64 212 func checkRegAbi(list []string, ver string) (regabi []string, noregabi []string) { 213 for _, v := range list { 214 ar := strings.Split(v, "_") 215 if len(ar) != 2 { 216 continue 217 } 218 switch ver { 219 case "go1.17": 220 if ar[1] == "amd64" { 221 regabi = append(regabi, v) 222 continue 223 } 224 case "go1.18": 225 switch ar[1] { 226 case "amd64", "arm64", "ppc64", "ppc64le": 227 regabi = append(regabi, v) 228 continue 229 } 230 case "go1.19": 231 switch ar[1] { 232 case "amd64", "arm64", "ppc64", "ppc64le", "riscv64": 233 regabi = append(regabi, v) 234 continue 235 } 236 } 237 noregabi = append(noregabi, v) 238 } 239 return 240 } 241 242 func osarchList() []string { 243 //go tool dist list 244 cmd := exec.Command("go", "tool", "dist", "list") 245 data, err := cmd.Output() 246 if err != nil { 247 panic(err) 248 } 249 var ar []string 250 for _, v := range strings.Split(string(data), "\n") { 251 if v == "" { 252 continue 253 } 254 ar = append(ar, strings.Replace(v, "/", "_", 1)) 255 } 256 return ar 257 }