Skip to content
Open
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
15 changes: 10 additions & 5 deletions cmd/genbindings/clangfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"log"
"os"
"path/filepath"
"strings"
)

Expand Down Expand Up @@ -211,10 +212,14 @@ func filterAst(in io.Reader) (*AstNode, error) {
}

func writeCache(ast *AstNode, inputHeader string) {
// Create parent directory for the cache file (handles versioned subdir like qt5.15/)
astPath := filteredAstPath(inputHeader)
if err := os.MkdirAll(filepath.Dir(astPath), 0755); err != nil {
panic("could not create cache directory for " + inputHeader + ": " + err.Error())
}
// Write a compressed version of the AST to disk - the AST is generally
// highly redundant a compresses by a factor of 10-20x - the typical Qt file
// is 5-10MB and compresses to ~300-600kB
astPath := filteredAstPath(inputHeader)
compressedFile, err := os.Create(astPath)
if err != nil {
panic("could not create filtered AST cache for " + inputHeader + ": " + err.Error())
Expand Down Expand Up @@ -261,22 +266,22 @@ func readCache(inputHeader string) (*AstNode, error) {
// Get or create the filtered AST from either the given input header or a version
// When changing this function, make sure to clear the on-disk cache:
// rm -rf cachedir/*.filtered.json.gz
func getFilteredAst(inputHeader, clangBin string, cflags []string) *AstNode {
func getFilteredAst(inputHeader, clangBin string, cflags []string) (*AstNode, error) {
ast, err := readCache(inputHeader)
if err != nil {
if !os.IsNotExist(err) {
panic("could not open filtered AST cache for " + inputHeader + ": " + err.Error())
return nil, fmt.Errorf("could not read filtered AST cache for %s: %w", inputHeader, err)
}

// If the file does not exist, we need to create it
// First, we need to create the AST cache
ast, err = clangExec(clangBin, inputHeader, cflags)
if err != nil {
panic("could not create AST cache for " + inputHeader + ": " + err.Error())
return nil, fmt.Errorf("could not parse clang AST for %s: %w", inputHeader, err)
}

writeCache(ast, inputHeader)
}

return ast
return ast, nil
}
12 changes: 11 additions & 1 deletion cmd/genbindings/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,11 @@ func parseHeaders(includeFiles []string, clangBin string, cflags []string, match
}()

result[i] = &CppParsedHeader{Filename: includeFile}
ast := getFilteredAst(includeFile, clangBin, cflags)
ast, err := getFilteredAst(includeFile, clangBin, cflags)
if err != nil {
log.Printf("Skipping %s: %v", includeFile, err)
return
}
// Convert it to our intermediate format
parseHeader(ast, "", result[i], matcher)
}(i, includeFile)
Expand Down Expand Up @@ -160,6 +164,9 @@ func generate(packageName string, srcDirs []string, allowHeaderFn func(string) b
processHeaders := parseHeaders(includeFiles, clangBin, cflags, matcher)

for _, parsed := range processHeaders {
if parsed == nil {
continue
}
// AST transforms on our IL
astTransformChildClasses(parsed) // must be first
astTransformApplyQuirks(packageName, parsed) // must be before optional/overload expansion
Expand All @@ -177,6 +184,9 @@ func generate(packageName string, srcDirs []string, allowHeaderFn func(string) b
//

for _, parsed := range processHeaders {
if parsed == nil {
continue
}

log.Printf("Processing %q...", parsed.Filename)

Expand Down