1
0
Fork 0
golang-modernc-libc/genheaders.go
Daniel Baumann 32b8eb3fd7
Adding upstream version 1.65.7.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-19 21:29:57 +02:00

144 lines
2.7 KiB
Go

//go:build ignore
// +build ignore
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
"modernc.org/cc/v3"
ccgo "modernc.org/ccgo/v3/lib"
)
var (
goos = runtime.GOOS
goarch = runtime.GOARCH
)
func fail(err error) {
fmt.Fprintf(os.Stderr, "%v (%v: %v:)\n", err, origin(3), origin(2))
os.Exit(1)
}
func main() {
_, _, hostSysIncludes, err := cc.HostConfig(os.Getenv("CCGO_CPP"))
if err != nil {
fail(err)
}
if err := libcHeaders(hostSysIncludes); err != nil {
fail(err)
}
}
type echoWriter struct {
w bytes.Buffer
}
func (w *echoWriter) Write(b []byte) (int, error) {
os.Stdout.Write(b)
return w.w.Write(b)
}
func runcc(args ...string) ([]byte, error) {
args = append([]string{"ccgo"}, args...)
// fmt.Printf("%q\n", args)
var out echoWriter
err := ccgo.NewTask(args, &out, &out).Main()
return out.w.Bytes(), err
}
func libcHeaders(paths []string) error {
const cfile = "gen.c"
return filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
return nil
}
path = filepath.Clean(path)
if strings.HasPrefix(path, ".") {
return nil
}
dir := path
ok := false
for _, v := range paths {
full := filepath.Join(v, dir+".h")
if fi, err := os.Stat(full); err == nil && !fi.IsDir() {
ok = true
break
}
}
if !ok {
return nil
}
var src string
switch filepath.ToSlash(path) {
case "fts":
src = `
#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>
`
default:
src = fmt.Sprintf("#include <%s.h>\n", dir)
}
src += "static char _;\n"
fn := filepath.Join(dir, cfile)
if err := ioutil.WriteFile(fn, []byte(src), 0660); err != nil {
return err
}
defer os.Remove(fn)
dest := filepath.Join(path, fmt.Sprintf("%s_%s_%s.go", filepath.Base(path), goos, goarch))
base := filepath.Base(dir)
argv := []string{
fn,
"-crt-import-path", "",
"-export-defines", "",
"-export-enums", "",
"-export-externs", "X",
"-export-fields", "F",
"-export-structs", "",
"-export-typedefs", "",
"-header",
"-hide", "_OSSwapInt16,_OSSwapInt32,_OSSwapInt64",
"-ignore-unsupported-alignment",
"-o", dest,
"-pkgname", base,
}
out, err := runcc(argv...)
if err != nil {
fmt.Fprintf(os.Stderr, "%s: %s%s\n", path, out, err)
} else {
fmt.Fprintf(os.Stdout, "%s\n%s", path, out)
}
return nil
})
}
func origin(skip int) string {
pc, fn, fl, _ := runtime.Caller(skip)
f := runtime.FuncForPC(pc)
var fns string
if f != nil {
fns = f.Name()
if x := strings.LastIndex(fns, "."); x > 0 {
fns = fns[x+1:]
}
}
return fmt.Sprintf("%s:%d:%s", filepath.Base(fn), fl, fns)
}