Skip to content

Commit

Permalink
Merge pull request #402 from gucio321/readme-codegen
Browse files Browse the repository at this point in the history
codegen: documentation and cmdline args cleanup
  • Loading branch information
gucio321 authored Dec 22, 2024
2 parents 523f067 + 83af167 commit e259c32
Show file tree
Hide file tree
Showing 37 changed files with 478 additions and 229 deletions.
33 changes: 16 additions & 17 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,22 @@ setup:
go build -o ../../codegen .

# Parameters:
# $1: prefix
# $2: go package name
# $3: include path (of header file)
# $4: definitions.json filepath
# $5: structs_and_enums.json filepath
# $6: typedefs_dict.json filepath
# $7: additional agruments to codegen call (e.g. -r option)
# $1: go package name
# $2: include path (of header file)
# $3: definitions.json filepath
# $4: structs_and_enums.json filepath
# $5: typedefs_dict.json filepath
# $6: additional agruments to codegen call (e.g. -r option)
define generate
@echo "Generating for $(1)"
mkdir -p $(2)
cat templates/cflags.go |sed -e "s/^package.*/package $(2)/g" > $(2)/cflags.go
cd $(2); \
../codegen -preset ../cmd/codegen/cimgui-go-preset.json -p $(1) -pkg $(2) -i ../$(3) -d ../$(4) -e ../$(5) -t ../$(6) $(7)
mkdir -p $(1)
cat templates/cflags.go |sed -e "s/^package.*/package $(1)/g" > $(1)/cflags.go
cd $(1); \
../codegen --preset ../cmd/codegen/cimgui-go-preset.json --package $(1) --include ../$(2) --definitions ../$(3) --enums ../$(4) --typedefs ../$(5) $(6)
endef

define imgui
$(call generate,cimgui,imgui,cwrappers/cimgui.h,cwrappers/cimgui_templates/definitions.json,cwrappers/cimgui_templates/structs_and_enums.json,cwrappers/cimgui_templates/typedefs_dict.json)
$(call generate,imgui,cwrappers/cimgui.h,cwrappers/cimgui_templates/definitions.json,cwrappers/cimgui_templates/structs_and_enums.json,cwrappers/cimgui_templates/typedefs_dict.json)
endef

## cimgui: generate imgui binding
Expand All @@ -37,7 +36,7 @@ imgui: setup
$(call imgui)

define implot
$(call generate,cimplot,implot,cwrappers/cimplot.h,cwrappers/cimplot_templates/definitions.json,cwrappers/cimplot_templates/structs_and_enums.json,cwrappers/cimplot_templates/typedefs_dict.json,-r ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
$(call generate,implot,cwrappers/cimplot.h,cwrappers/cimplot_templates/definitions.json,cwrappers/cimplot_templates/structs_and_enums.json,cwrappers/cimplot_templates/typedefs_dict.json,--ref-enums ../cwrappers/cimgui_templates/structs_and_enums.json --ref-typedefs ../cwrappers/cimgui_templates/typedefs_dict.json)
endef

## implot: generate implot binding
Expand All @@ -46,7 +45,7 @@ implot: setup
$(call implot)

define imnodes
$(call generate,cimnodes,imnodes,cwrappers/cimnodes.h,cwrappers/cimnodes_templates/definitions.json,cwrappers/cimnodes_templates/structs_and_enums.json,cwrappers/cimnodes_templates/typedefs_dict.json,-r ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
$(call generate,imnodes,cwrappers/cimnodes.h,cwrappers/cimnodes_templates/definitions.json,cwrappers/cimnodes_templates/structs_and_enums.json,cwrappers/cimnodes_templates/typedefs_dict.json,--ref-enums ../cwrappers/cimgui_templates/structs_and_enums.json --ref-typedefs ../cwrappers/cimgui_templates/typedefs_dict.json)
endef

## imnodes: generate imnodes binding
Expand All @@ -55,7 +54,7 @@ imnodes: setup
$(call imnodes)

define immarkdown
$(call generate,cimmarkdown,immarkdown,cwrappers/cimmarkdown.h,cwrappers/cimmarkdown_templates/definitions.json,cwrappers/cimmarkdown_templates/structs_and_enums.json,cwrappers/cimmarkdown_templates/typedefs_dict.json,-r ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
$(call generate,immarkdown,cwrappers/cimmarkdown.h,cwrappers/cimmarkdown_templates/definitions.json,cwrappers/cimmarkdown_templates/structs_and_enums.json,cwrappers/cimmarkdown_templates/typedefs_dict.json,--ref-enums ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
endef

## immarkdown: generate immarkdown binding
Expand All @@ -64,7 +63,7 @@ immarkdown: setup
$(call immarkdown)

define imguizmo
$(call generate,cimguizmo,imguizmo,cwrappers/cimguizmo.h,cwrappers/cimguizmo_templates/definitions.json,cwrappers/cimguizmo_templates/structs_and_enums.json,cwrappers/cimguizmo_templates/typedefs_dict.json,-r ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
$(call generate,imguizmo,cwrappers/cimguizmo.h,cwrappers/cimguizmo_templates/definitions.json,cwrappers/cimguizmo_templates/structs_and_enums.json,cwrappers/cimguizmo_templates/typedefs_dict.json,-re ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
endef

## imguizmo: generate imguizmo binding
Expand All @@ -73,7 +72,7 @@ imguizmo: setup
$(call imguizmo)

define imcte
$(call generate,cimcte,ImGuiColorTextEdit,cwrappers/cimCTE.h,cwrappers/cimCTE_templates/definitions.json,cwrappers/cimCTE_templates/structs_and_enums.json,cwrappers/cimCTE_templates/typedefs_dict.json,-r ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
$(call generate,ImGuiColorTextEdit,cwrappers/cimCTE.h,cwrappers/cimCTE_templates/definitions.json,cwrappers/cimCTE_templates/structs_and_enums.json,cwrappers/cimCTE_templates/typedefs_dict.json,-re ../cwrappers/cimgui_templates/structs_and_enums.json -rt ../cwrappers/cimgui_templates/typedefs_dict.json)
endef

## imcte: generate ImGuiColorTextEdit binding
Expand Down
149 changes: 149 additions & 0 deletions cmd/codegen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# codegen

Codegen is a cimgui-go-featured GO code generator.

Cod is generated basing on several JSON config files and refers to a shared library compiled from C source.

# Usage

```console
[codegen (0) ]$ go run . --help
Usage: codegen [FLAG]...

Flags:
-lg, --log-generated Log about functions that was generated. (type: bool; default: false)
-lng, --log-not-generated Log about functions that was NOT generated. (type: bool; default: false)
-d, --definitions definitions.json file path (type: string)
-e, --enums structs_and_enums.json file path (type: string)
-t, --typedefs typedefs_dict.json file path (type: string)
-re, --ref-enums structs_and_enums.json file path for reference package (see README.md). (type: string)
-rt, --ref-typedefs typedefs_dict.json file path for reference package (see README.md). (type: string)
-p, --preset Preset of custom (manual) generator rules. See go doc github.com/AllenDang/cimgui-go/cmd/codegen.Preset for more details. (in form of json file) (type: string)
-rp, --ref-pkg name for refTypedefs package name (type: string; default: imgui)
-pkg, --package name for current package (type: string)
-i, --include Include header file (source project's header) (type: string)
-h, --help show help (type: bool)
```

# Configuration

```console
[codegen (0) ]$ go doc Preset
type Preset struct {
// SkipFuncs functions (from definitions.json) to be skipped
// e.g. they are temporarily hard-coded
SkipFuncs map[CIdentifier]bool
// SkipStructs allows to specify struct names that will be skipped.
SkipStructs map[CIdentifier]bool
// SkipMethods struct names from structs_and_enums.json.
// structures that's METHODS should be skipped
SkipMethods map[CIdentifier]bool
// SkipTypedefs typedefs from typedefs_dict.json to be skipped
// e.g. for hardcoded typedefs or typedefs which are obvious (e.g. ImU16 becomes uint16 without extra type information)
SkipTypedefs map[CIdentifier]bool
// TypedefsPoolSize sets a default size for callbacks pool.
// Rembmber to set this as it defaults to 0 and you'll get no callbacks!
TypedefsPoolSize int
// TypedefsCustomPoolSizes allows to override TypedefsPoolSize for certain types.
TypedefsCustomPoolSizes map[CIdentifier]int
// Replace is a map for C -> Go names conversion.
// It allows you to force-rename anything (including functions and enums)
Replace map[CIdentifier]GoIdentifier
// TrimPrefix allows to remove unwanted prefixes from everything during C->Go renaming.
// NOTE: order sensitive!
// NOTE: Case sensitive
TrimPrefix []string
// OriginReplace allows to force-replace function name with some other name.
// Introduced to replace TextEditor_GetText -> TextEditor_GetText_alloc
// but could be re-used to force use of another function than json tells us to use.
//
// It differs from Replace - Replace renames an identifier in general (changes its name but refers to the same function).
// This allows to absolutely abandon the source C function and use some OTHER C function.
OriginReplace map[CIdentifier]CIdentifier
// DefaultArgReplace is used in C-side default args generation (gencpp.go).
// cimgui-go uses this to change FLT_MIN with igGet_FLT_MIN()
// NOTE: Iterated randomly!
DefaultArgReplace map[CIdentifier]CIdentifier
// DefaultArgArbitraryValue is similar to the above DefaultArgReplace, but
// associates default arg name with any arbitrary value.
// cimgui-go uses this to set text_end to 0
DefaultArgArbitraryValue map[CIdentifier]CIdentifier
// ExtraCGOPreamble allows to specify additional C code elements in Go files.
// For example could be used to Include extra files.
// For ease of use, its in form of []string. These lines will be merged and prefixed (if appliable) with '//'
ExtraCGOPreamble []string
// InternalFiles allows to specify files that are considered Internal.
// If an identifier is found in such a file, it will be generated but its
// name will be prefixed with InternalPrefix
InternalFiles []string
// InternalPrefix is a prefix for identifiers from InternalFiles.
InternalPrefix string
// PackagePath is an import path of the package.
// This is base path. flags.PackageName will be added.
// Example:
// "github.com/AllenDang/cimgui-go"
// If enerated with -pkg imgui, import path
// is supposed to be "github.com/AllenDang/cimgui-go/imgui"
PackagePath string
// SimpleTypes are used for simple (go-convertable) custom types (wrappers will be generated by simpleW/simpleR).
// Example:
// ImS16 is defined as short in C code, so Go can easily convert it via int16()
// Expected format is:
// "ImS16": ["int16", "C.ImS16", "pkgname"]
// where:
// - ImS16 is a C type name
// - int16 is a Go-friendly type name
// - C.ImS16 is a cgo compatible type name
// - pkgname is a source package for the type (in this case int16 is a builtin so it should be empty)
// See also: simpleW
SimpleTypes map[CIdentifier][3]GoIdentifier
// SimplePtrTypes are just like SimpleTypes but for pointer types.
// Example:
// "ImS16": ["int16", "C.ImS16", "pkgname"]
SimplePtrTypes map[CIdentifier][3]GoIdentifier
// WrappableTypes are types that implement a special interface
// github.com/AllenDang/cimgui-go/internal.WrappableType[CTYPE, SELF]
// In short they are supposed to have 2 methods:
// - ToC() CTYPE which returns SELF converted to CTYPE
// - FromC(CTYPE) SELF which restores SELF from CTYPE.
//
// Key is a C type name, value is a list:
// - Go name
// - C name
// - package where the type is defined
// Example syntax:
// "ImVec2": ["Vec2", "C.ImVec2", "imgui"]
WrappableTypes map[CIdentifier][3]GoIdentifier
}
Preset is a set of rules iperative to XXX_templates/ json files. They are
used to manually set some properties of the generator.
```

# How it works?

Assume you have a C project which exports its public API in a header (`.h`) file.
What this module does not cover is the first step:
1. You need JSON files describing functions in your C project. This is at the moment done by https://github.com/cimgui lua cpp2ffi.lua script which
however is highly single-purpose and you probably will not be able to use it for your project. You need to handle this yourself for now.
Let us know if you find/create an universal solution for that. For specification of the JSON files see [here](#C-Configuration)
2. Then you need a another JSON file called "preset" (see [here](#Configuration)) which will tell the generator more about your project.
e.g. its github path, ids you want to exclude (if you're need for some reason - we do for imgui), prefixes to remove, etc.
3. Execute codegen. Do `codegen -lng --preset your_preset.json -e structs_and_enums.json -t typedefs_dict.json -d definitions.json -i your_header.h -pkg your_package_name`.
This will create several files in your current directory that should contain operational code.

## Reference packages

Sometimes you may want to generate one package basing on another package wrapped by this
(I mean imgui plugin for example).
Example:
`header.h` contains symbol `A`. Then you have `header2.h` with a function using this symbol `A`.
On go sied you have `package1.A` and you want to generate `header2.h` in `package2` and
use `package1.A` in it. This is where `--ref*` flags comes in. You specify header1's json files as reference files
and package1 as reference package. Then you generate package2 and it will use package1's symbols.

# C Configuration

:warning: Disclaimer: this is NOT our design and we are not able to modify this.
The layout of these files is enforced by https://github.com/cimgui which we're using for generation.

The minimalistic working configuration is present in [here](./testdata) review it yourself.
8 changes: 4 additions & 4 deletions cmd/codegen/arguments_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ func getArgWrapper(
_, isRefEnum := context.refEnumNames[pureType]

if isEnum || isRefEnum {
srcPkg := context.flags.packageName
srcPkg := context.flags.PackageName
if isRefTypedef {
srcPkg = context.flags.refPackageName
srcPkg = context.flags.RefPackageName
}

goType := prefixGoPackage(pureType.renameGoIdentifier(context), GoIdentifier(srcPkg), context)
Expand Down Expand Up @@ -268,9 +268,9 @@ for i, %[1]sV := range %[1]sArg {

_, shouldSkipRefTypedef := context.preset.SkipTypedefs[pureType]
if context.typedefsNames[pureType] || (isRefTypedef && !shouldSkipRefTypedef) {
srcPkg := context.flags.packageName
srcPkg := context.flags.PackageName
if isRefTypedef {
srcPkg = context.flags.refPackageName
srcPkg = context.flags.RefPackageName
}

goType := prefixGoPackage(pureType.renameGoIdentifier(context), GoIdentifier(srcPkg), context)
Expand Down
48 changes: 20 additions & 28 deletions cmd/codegen/flags.go
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
package main

import "flag"
import "github.com/cosiner/flag"

type flags struct {
showGenerated bool
showNotGenerated bool

defJsonPath,
enumsJsonpath,
typedefsJsonpath,
refEnumsJsonPath,
refTypedefsJsonPath,
presetJsonPath,
refPackageName, // name for refTypedefs (default: imgui)
packageName, // name for current package (e.g. imgui, implot)
prefix,
include string
ShowGenerated bool `names:"-lg, --log-generated" usage:"Log about functions that was generated." default:"false"`
ShowNotGenerated bool `names:"-lng, --log-not-generated" usage:"Log about functions that was NOT generated." default:"false"`
Verbose bool `names:"--verbose" usage:"Verbose output (dump literally everything it could dump)." default:"false`

DefJsonPath string `names:"-d, --definitions" usage:"definitions.json file path"`
EnumsJsonpath string `names:"-e, --enums" usage:"structs_and_enums.json file path"`
TypedefsJsonpath string `names:"-t, --typedefs" usage:"typedefs_dict.json file path"`

RefEnumsJsonPath string `names:"-re, --ref-enums" usage:"structs_and_enums.json file path for reference package (see README.md)."`
RefTypedefsJsonPath string `names:"-rt, --ref-typedefs" usage:"typedefs_dict.json file path for reference package (see README.md)."`

PresetJsonPath string `names:"-p, --preset" usage:"Preset of custom (manual) generator rules. See go doc github.com/AllenDang/cimgui-go/cmd/codegen.Preset for more details. (in form of json file)"`

// name for refTypedefs (default: imgui)
RefPackageName string `names:"-rp, --ref-pkg" usage:"name for refTypedefs package name" default:"imgui"`
// name for current package (e.g. imgui, implot)
PackageName string `names:"-pkg, --package" usage:"name for current package"`
Include string `names:"-i, --include" usage:"Include header file (source project's header)"`
}

func parse() *flags {
flags := &flags{}
flag.BoolVar(&flags.showGenerated, "generated", false, "Log about functions that was generated.")
flag.BoolVar(&flags.showNotGenerated, "not-generated", true, "Log about functions that was NOT generated.")

flag.StringVar(&flags.defJsonPath, "d", "", "definitions json file path")
flag.StringVar(&flags.enumsJsonpath, "e", "", "structs and enums json file path")
flag.StringVar(&flags.typedefsJsonpath, "t", "", "typedefs dict json file path")
flag.StringVar(&flags.refEnumsJsonPath, "r", "", "reference structs and enums json file path")
flag.StringVar(&flags.refTypedefsJsonPath, "rt", "", "reference typedefs_dict.json file path")
flag.StringVar(&flags.presetJsonPath, "preset", "", "Preset of custom (manual) generator rules. See go doc github.com/AllenDang/cimgui-go/cmd/codegen.Preset for more details.")
flag.StringVar(&flags.refPackageName, "refPkg", "imgui", "name for refTypedefs package name")
flag.StringVar(&flags.packageName, "pkg", "", "name for current package")
flag.StringVar(&flags.prefix, "p", "", "prefix for the generated file")
flag.StringVar(&flags.include, "i", "", "include header file")
flag.Parse()
flag.ParseStruct(flags)

return flags
}
11 changes: 11 additions & 0 deletions cmd/codegen/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ func FormatGo(s string, ctx *Context) string {
ExtraRules: true,
})
if err != nil {
if ctx.flags.Verbose {
glg.Debugf(string(s))
}

glg.Fatalf("Unable to format go code: %v", err)
}

Expand All @@ -26,6 +30,13 @@ func FormatGo(s string, ctx *Context) string {
TabWidth: 8,
FormatOnly: false,
})
if err != nil {
if ctx.flags.Verbose {
glg.Debugf(string(s))
}

glg.Fatalf("Unable to goimports code: %v", err)
}

return string(sBytes)
}
12 changes: 6 additions & 6 deletions cmd/codegen/function_deffiniton.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
type FuncDef struct {
// FuncName is a cimgui name of the function
FuncName CIdentifier `json:"ov_cimguiname"`
// FuncName is an original Dear ImGui's name of the function
// OriginalFuncName is an original Dear ImGui's name of the function
OriginalFuncName CIdentifier `json:"original_func_name"`
// Args represents a plain string list of function arguments
Args string `json:"args"`
Expand All @@ -24,12 +24,12 @@ type FuncDef struct {
// Comment on function
Comment string `json:"comment"`

Constructor bool `json:"constructor"`
Destructor bool `json:"destructor"`
StructSetter bool `json:"struct_setter"`
StructGetter bool `json:"struct_getter"`
Constructor bool
Destructor bool
StructSetter bool
StructGetter bool

InvocationStmt string `json:"invocation_stmt"`
InvocationStmt string

// Ret determines a type of returned value
Ret CIdentifier `json:"ret"`
Expand Down
Loading

0 comments on commit e259c32

Please sign in to comment.