AllenDang / cimgui-go

Auto generated Go wrapper for Dear ImGui via cimgui
MIT License
349 stars 51 forks source link

Allow building C dependencies from source #157

Open 5aji opened 1 year ago

5aji commented 1 year ago

Currently the program expects to be able to link to the static libraries in lib/. While this saves build time for fresh builds it limits the targets to just four (linux/amd64 windows/amd64 darwin/arm64 darwin/amd64). Ideally we should be able to target any platform and any architecture without needing to modify the repository (linux/arm and windows/arm64).

This also affects cross-compilation. The darwin static libraries are built with a new linker flag (-fobjc-msgsend-selector-stubs) that adds additional symbols that are expected to exist when linking. When using OSXCross with the latest SDK I get the following linker errors:

/usr/lib/go/pkg/tool/linux_amd64/link: running arm64-apple-darwin22.2-c++ failed: exit status 1
Undefined symbols for architecture arm64:
  "_objc_msgSend$IBeamCursor", referenced from:
      __glfwPlatformCreateStandardCursor in libglfw3.a(cocoa_window.m.o)
  "_objc_msgSend$UTF8String", referenced from:
      __glfwPlatformGetClipboardString in libglfw3.a(cocoa_window.m.o)
      _getMonitorName in libglfw3.a(cocoa_monitor.m.o)
  "_objc_msgSend$activateIgnoringOtherApps:", referenced from:
      __glfwPlatformFocusWindow in libglfw3.a(cocoa_window.m.o)
  "_objc_msgSend$addItem:", referenced from:
      _createMenuBar in libglfw3.a(cocoa_init.m.o)
  "_objc_msgSend$addItemWithTitle:action:keyEquivalent:", referenced from:
      _createMenuBar in libglfw3.a(cocoa_init.m.o)
... etc

There are workarounds discussed but they have compromises since the flag will cause an error on older versions of XCode.

If I could build the GLFW files from source that would resolve this problem since they wouldn't link against these missing symbols for most architectures. This change also prevents older devices and SDKs from working for native builds.

Ideally we provide the user with a choice:

AllenDang commented 1 year ago

@kschamplin I think all the build scripts are already there, you could modify and do the compile on all supported system.

gucio321 commented 1 year ago

Im wondering why go doesn't build from source automatically if ptebuilt binary doesn't exist

5aji commented 1 year ago

cimgui.go only references static libraries, so if the platform isn't the ones that have the static library built, it can't be built.

// #cgo CPPFLAGS: -DCIMGUI_DEFINE_ENUMS_AND_STRUCTS
// #cgo amd64,linux LDFLAGS: ${SRCDIR}/lib/linux/x64/cimgui.a
// #cgo amd64,windows LDFLAGS: -L${SRCDIR}/lib/windows/x64 -l:cimgui.a
// #cgo amd64,darwin LDFLAGS: ${SRCDIR}/lib/macos/x64/cimgui.a
// #cgo arm64,darwin LDFLAGS: ${SRCDIR}/lib/macos/arm64/cimgui.a
import "C"

Same with GLFW. this is fine if you want "precompiled" easy binaries but has two downsides:

  1. only works with those platforms. If I want a new platform, I have to download the repository and use CMake to create the static library.
  2. not secure - could be attacked by a malicious library (not that I think that would happen)

My proposal to fix this is to add a build tag of some kind (can be off by default for compatibility) that excludes the cimgui.go file and adds a new cimgui_compile.go file that adds the C and header files needed. This is more complex for GLFW but since there are plans (#153) to isolate that we can just use something like go-glfw with a backend wrapper instead which does all the hard work of setting up CGO to build the files.