Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

llcppcfg print clang command error & fix llcppgtest liblzma fail #199

Merged
merged 4 commits into from
Mar 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/llcppcfg/llcppcfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func main() {
if tab {
flag |= llcppgcfg.WithTab
}
buf, err := llcppgcfg.GenCfg(name, flag, exts, excludeSubdirs)
buf, err := llcppgcfg.GenCfg(llcppgcfg.NewGenConfig(name, flag, exts, excludeSubdirs))
if err != nil {
log.Fatal(err)
}
Expand Down
52 changes: 35 additions & 17 deletions cmd/llcppcfg/llcppgcfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package llcppgcfg
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/fs"
"log"
"path/filepath"
"sort"
"strings"
Expand All @@ -14,6 +16,17 @@ import (
"github.com/goplus/llcppg/llcppg"
)

type GenConfig struct {
name string
flag FlagMode
exts []string
excludeSubdirs []string
}

func NewGenConfig(name string, flag FlagMode, exts, excludeSubdirs []string) *GenConfig {
return &GenConfig{name: name, flag: flag, exts: exts, excludeSubdirs: excludeSubdirs}
}

type llcppCfgKey string

const (
Expand Down Expand Up @@ -103,9 +116,9 @@ func getClangArgs(cflags string, relpath string) []string {
return args
}

func parseFileEntry(cflags, trimCflag, path string, d fs.DirEntry, exts []string, excludeSubdirs []string) *ObjFile {
func parseFileEntry(cflags, trimCflag, path string, d fs.DirEntry, exts []string, excludeSubdirs []string) (*ObjFile, error) {
if d.IsDir() || strings.HasPrefix(d.Name(), ".") {
return nil
return nil, errors.New("invalid file entry")
}
idx := len(exts)
for i, ext := range exts {
Expand All @@ -115,28 +128,28 @@ func parseFileEntry(cflags, trimCflag, path string, d fs.DirEntry, exts []string
}
}
if idx == len(exts) {
return nil
return nil, errors.New("invalid file ext")
}
relPath, err := filepath.Rel(trimCflag, path)
if err != nil {
relPath = path
}
if isExcludeDir(relPath, excludeSubdirs) {
return nil
return nil, errors.New("file in excluded directory")
}
args := getClangArgs(cflags, relPath)
clangCmd := cmdout.NewExecCommand("clang", args...)
outString, err := cmdout.GetOut(clangCmd, trimCflag)
if err != nil || outString == "" {
objFile := NewObjFile(relPath, relPath)
return objFile
if err != nil {
log.Println(outString)
return NewObjFile(relPath, relPath), errors.New(outString)
}
outString = strings.ReplaceAll(outString, "\\\n", "\n")
fields := strings.Fields(outString)
lines, objFileStr := findDepSlice(fields)
objFile := NewObjFileString(objFileStr)
objFile.Deps = append(objFile.Deps, lines...)
return objFile
return objFile, nil
}

func parseCFlagsEntry(cflags, cflag string, exts []string, excludeSubdirs []string) *CflagEntry {
Expand All @@ -150,11 +163,18 @@ func parseCFlagsEntry(cflags, cflag string, exts []string, excludeSubdirs []stri
var cflagEntry CflagEntry
cflagEntry.Include = trimCflag
cflagEntry.ObjFiles = make([]*ObjFile, 0)
cflagEntry.InvalidObjFiles = make([]*ObjFile, 0)
err := filepath.WalkDir(trimCflag, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
pObjFile := parseFileEntry(cflags, trimCflag, path, d, exts, excludeSubdirs)
pObjFile, err := parseFileEntry(cflags, trimCflag, path, d, exts, excludeSubdirs)
if err != nil {
if pObjFile != nil {
cflagEntry.InvalidObjFiles = append(cflagEntry.InvalidObjFiles, pObjFile)
}
return nil
}
if pObjFile != nil {
cflagEntry.ObjFiles = append(cflagEntry.ObjFiles, pObjFile)
}
Expand Down Expand Up @@ -203,19 +223,17 @@ func NormalizePackageName(name string) string {
return strings.Join(fields, "_")
}

func GenCfg(name string, flag FlagMode, exts []string, excludeSubdirs []string) (*bytes.Buffer, error) {
if len(name) == 0 {
func GenCfg(genCfg *GenConfig) (*bytes.Buffer, error) {
if len(genCfg.name) == 0 {
return nil, newEmptyStringError("name")
}
cfg := NewLLCppgConfig(name, flag)
expandCFlags := ExpandName(name, "", cfgCflagsKey)
sortIncludes(expandCFlags, cfg, exts, excludeSubdirs)

cfg := NewLLCppgConfig(genCfg.name, genCfg.flag)
expandCFlags := ExpandName(genCfg.name, "", cfgCflagsKey)
sortIncludes(expandCFlags, cfg, genCfg.exts, genCfg.excludeSubdirs)
cfg.Name = NormalizePackageName(cfg.Name)

buf := bytes.NewBuffer([]byte{})
jsonEncoder := json.NewEncoder(buf)
if flag&WithTab != 0 {
if genCfg.flag&WithTab != 0 {
jsonEncoder.SetIndent("", "\t")
}
err := jsonEncoder.Encode(cfg)
Expand Down
10 changes: 4 additions & 6 deletions cmd/llcppcfg/llcppgcfg/cfg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func Test_parseFileEntry(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := parseFileEntry(tt.args.cflags, tt.args.trimStr, tt.args.path, tt.args.d, tt.args.exts, tt.args.excludeSubdirs)
got, _ := parseFileEntry(tt.args.cflags, tt.args.trimStr, tt.args.path, tt.args.d, tt.args.exts, tt.args.excludeSubdirs)
if tt.want != nil && got != nil && !got.IsEqual(tt.want) {
t.Errorf("parseFileEntry() = %v, want %v", got, tt.want)
}
Expand Down Expand Up @@ -333,6 +333,7 @@ func Test_parseCFlagsEntry(t *testing.T) {
{OFile: "cJSON_Utils.o", HFile: "cJSON_Utils.h", Deps: []string{"cJSON.h"}},
{OFile: "cJSON.o", HFile: "cJSON.h", Deps: []string{}},
},
InvalidObjFiles: []*ObjFile{},
},
},
{
Expand Down Expand Up @@ -443,10 +444,7 @@ func Test_sortIncludes(t *testing.T) {
[]string{".h"},
[]string{},
},
[]string{
"a.h",
"b.h",
},
[]string{},
},
{
"deps/case4_recircle",
Expand Down Expand Up @@ -646,7 +644,7 @@ func TestGenCfg(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := GenCfg(tt.args.name, tt.args.flag, tt.args.exts, tt.args.excludeSubdirs)
got, err := GenCfg(NewGenConfig(tt.args.name, tt.args.flag, tt.args.exts, tt.args.excludeSubdirs))
if (err != nil) != tt.wantErr {
t.Errorf("GenCfg() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
11 changes: 5 additions & 6 deletions cmd/llcppcfg/llcppgcfg/cfg_test_data/bdw-gc/llcppg.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,22 @@
"include": [
"gc/gc_inline.h",
"gc_cpp.h",
"gc/gc_gcj.h",
"gc/javaxfc.h",
"gc/gc_backptr.h",
"gc/gc_mark.h",
"gc.h",
"gc/leak_detector.h",
"gc/javaxfc.h",
"gc/gc_cpp.h",
"gc/gc_disclaim.h",
"gc/gc_gcj.h",
"gc/leak_detector.h",
"gc/gc_typed.h",
"gc/gc.h",
"gc/gc_mark.h",
"gc/ec.h",
"gc/gc.h",
"gc/cord.h",
"gc/gc_pthread_redirects.h",
"gc/gc_tiny_fl.h",
"gc/gc_version.h",
"gc/gc_config_macros.h",
"gc/gc_allocator.h",
"gc/cord_pos.h"
],
"trimPrefixes": [],
Expand Down
3 changes: 2 additions & 1 deletion cmd/llcppcfg/llcppgcfg/cfg_test_data/deps/case3/b.h
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#include "a.h"
#include "a.h"
#include "c.h"
1 change: 1 addition & 0 deletions cmd/llcppcfg/llcppgcfg/cfg_test_data/deps/case3/c.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "b.h"
3 changes: 1 addition & 2 deletions cmd/llcppcfg/llcppgcfg/cfg_test_data/libffi/llcppg.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"cflags": "$(pkg-config --cflags libffi)",
"libs": "$(pkg-config --libs libffi)",
"include": [
"ffi.h",
"ffitarget.h"
"ffi.h"
Copy link
Contributor

@luoliwoshang luoliwoshang Mar 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

很棒的更新,在llcppg处理阶段也会抛出这个错误,提前避免问题,生成正确的include文件

libffi/3.4.6/include on  stable via C v15.0.0-clang 
❯ clang -MM ./ffitarget.h  
./ffitarget.h:26:2: error: "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
   26 | #error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
      |  ^
ffitarget.o: ffitarget.h
1 error generated.

],
"trimPrefixes": [],
"cplusplus": false,
Expand Down
18 changes: 15 additions & 3 deletions cmd/llcppcfg/llcppgcfg/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ func (p *IncludeList) AddCflagEntry(index int, entry *CflagEntry) {
p.AddIncludeForObjFile(objFile, index)
}
}
lenInvalidObjFiles := len(entry.InvalidObjFiles)
if lenInvalidObjFiles > 0 {
fmt.Println("Invlid header files:")
for idx, objFile := range entry.InvalidObjFiles {
if idx < lenInvalidObjFiles-1 {
fmt.Printf("\t\t%q,\n", objFile.HFile)
} else {
fmt.Printf("\t\t%q\n", objFile.HFile)
}
}
}
}

func (p *IncludeList) AddIncludeForObjFile(objFile *ObjFile, index int) {
Expand All @@ -88,15 +99,16 @@ func (p *IncludeList) AddIncludeForObjFile(objFile *ObjFile, index int) {
}

type CflagEntry struct {
Include string
ObjFiles []*ObjFile
Include string
ObjFiles []*ObjFile
InvalidObjFiles []*ObjFile
}

func (c *CflagEntry) IsEmpty() bool {
if len(c.Include) == 0 {
return true
}
if len(c.ObjFiles) == 0 {
if len(c.ObjFiles) == 0 && len(c.InvalidObjFiles) == 0 {
return true
}
return false
Expand Down
25 changes: 25 additions & 0 deletions cmd/llcppcfg/llcppgcfg/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ func TestIncludeList_AddCflagEntry(t *testing.T) {
_, inc := newCflags("cfg_test_data/same_rel")
inc0 := filepath.Join(inc, "libcjson/include")
inc1 := filepath.Join(inc, "stdcjson/include")
_, depsInc := newCflags("cfg_test_data/deps")
case3Inc := filepath.Join(depsInc, "case3")
type fields struct {
include []string
absPathMap map[string]struct{}
Expand Down Expand Up @@ -387,6 +389,29 @@ func TestIncludeList_AddCflagEntry(t *testing.T) {
},
[]string{},
},
{
"deps/case3",
fields{
make([]string, 0),
make(map[string]struct{}),
make(map[string]struct{}),
},
[]args{
{
0,
&CflagEntry{
Include: case3Inc,
ObjFiles: []*ObjFile{},
InvalidObjFiles: []*ObjFile{
{OFile: "a.h", HFile: "a.h", Deps: []string{}},
{OFile: "b.h", HFile: "b.h", Deps: []string{}},
{OFile: "c.h", HFile: "c.h", Deps: []string{}},
},
},
},
},
[]string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion cmdout/cmdout.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ func GetOut(cmd *exec.Cmd, dir string) (string, error) {
return "", newNilError()
}
outBuf := bytes.NewBufferString("")
errBuff := bytes.NewBufferString("")
cmd.Stdin = os.Stdin
cmd.Stdout = outBuf
cmd.Stderr = errBuff
cmd.Env = os.Environ()
if len(dir) > 0 {
cmd.Dir = dir
}
err := cmd.Run()
if err != nil {
return outBuf.String(), err
return errBuff.String(), err
}
return outBuf.String(), nil
}
Expand Down
Loading