Swift can’t compile code with OpenGL function pointers


(Kelvin Ma) #1

OpenGL functions are loaded at runtime by a function loader (like GLFW).
They’re defined in a header but obviously they don’t have definitions at
compile time so it causes a slew of linker errors when I try to build

    error: undefined reference to 'glEnable'
    error: undefined reference to 'glBlendFunc'
    error: undefined reference to 'glClearColor'
    clang: error: linker command failed with exit code 1 (use -v to see
invocation)
    ...

How do I build programs that use OpenGL functions?


(Joe Groff) #2

If the functions are exported by the OpenGL library you're linking against, then you may need to just use -lGL to link against it. That's not likely to be portable, though, since implementations vary in what they statically export. The macro metaprogramming used by GLFW and other libraries to dynamically load GL entry points is probably not going to get picked up by Swift's C importer, so you'd need to roll your own solution. Something like this might work as a start:

func loadGLFunction<T>(name: String) -> T {
#if os(macOS)
  return unsafeBitCast(dlsym(RTLD_DEFAULT, name), to: T.self)
#elseif os(Linux)
  return unsafeBitCast(glXGetProcAddress(name), to: T.self)
#elseif os(Windows)
  return unsafeBitCast(wglGetProcAddress(name), to: T.self)
#endif
}

enum GL {
  static let begin: @convention(c) (GLenum) -> Void = loadGLFunction("glBegin")
  static let end: @convention(c) () -> Void = loadGLFunction("glEnd")
  /*etc*/
}

-Joe

···

On Mar 30, 2017, at 7:47 AM, Kelvin Ma via swift-users <swift-users@swift.org> wrote:

OpenGL functions are loaded at runtime by a function loader (like GLFW). They’re defined in a header but obviously they don’t have definitions at compile time so it causes a slew of linker errors when I try to build

    error: undefined reference to 'glEnable'
    error: undefined reference to 'glBlendFunc'
    error: undefined reference to 'glClearColor'
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    ...

How do I build programs that use OpenGL functions?


(Kelvin Ma) #3

There are hundreds of gl functions… I have to rewrite the signatures for
all of them??

···

On Thu, Mar 30, 2017 at 11:31 AM, Joe Groff <jgroff@apple.com> wrote:

> On Mar 30, 2017, at 7:47 AM, Kelvin Ma via swift-users < > swift-users@swift.org> wrote:
>
> OpenGL functions are loaded at runtime by a function loader (like GLFW).
They’re defined in a header but obviously they don’t have definitions at
compile time so it causes a slew of linker errors when I try to build
>
> error: undefined reference to 'glEnable'
> error: undefined reference to 'glBlendFunc'
> error: undefined reference to 'glClearColor'
> clang: error: linker command failed with exit code 1 (use -v to see
invocation)
> ...
>
> How do I build programs that use OpenGL functions?

If the functions are exported by the OpenGL library you're linking
against, then you may need to just use -lGL to link against it. That's not
likely to be portable, though, since implementations vary in what they
statically export. The macro metaprogramming used by GLFW and other
libraries to dynamically load GL entry points is probably not going to get
picked up by Swift's C importer, so you'd need to roll your own solution.
Something like this might work as a start:

func loadGLFunction<T>(name: String) -> T {
#if os(macOS)
  return unsafeBitCast(dlsym(RTLD_DEFAULT, name), to: T.self)
#elseif os(Linux)
  return unsafeBitCast(glXGetProcAddress(name), to: T.self)
#elseif os(Windows)
  return unsafeBitCast(wglGetProcAddress(name), to: T.self)
#endif
}

enum GL {
  static let begin: @convention(c) (GLenum) -> Void =
loadGLFunction("glBegin")
  static let end: @convention(c) () -> Void = loadGLFunction("glEnd")
  /*etc*/
}

-Joe


(Elia Cereda) #4

Hi Kelvin,

Do you mind sharing the code you’re using? I’m looking back at some code I wrote a while back to learn OpenGL and I see that the implementation was pretty straightforward.

The OpenGL.GL module already provides the implementations for runtime functions such as glEnable, glBlendFunc and glClearColor. In my code I just import that and use those functions the same way you use any other function.

Elia Cereda

···

Il giorno 30 mar 2017, alle ore 16:47, Kelvin Ma via swift-users <swift-users@swift.org> ha scritto:

OpenGL functions are loaded at runtime by a function loader (like GLFW). They’re defined in a header but obviously they don’t have definitions at compile time so it causes a slew of linker errors when I try to build

    error: undefined reference to 'glEnable'
    error: undefined reference to 'glBlendFunc'
    error: undefined reference to 'glClearColor'
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    ...

How do I build programs that use OpenGL functions?
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Joe Groff) #5

Does GLFW expose any underlying loader mechanism or cached function pointer variables underneath the macros it defines? Possibly you could access those directly. Otherwise, code generation might be your best bet. You should be able to get types like GLenum or GLint just by importing them normally, since those are purely compile-time constructs.

-Joe

···

On Mar 30, 2017, at 9:40 AM, Kelvin Ma <kelvinsthirteen@gmail.com> wrote:

There are hundreds of gl functions… I have to rewrite the signatures for all of them??


(Kelvin Ma) #6

I’m also guessing I have to disable the default function loader GLFW
provides? What do I do about GL defined types such as GLenuum and GLint?

···

On Thu, Mar 30, 2017 at 11:40 AM, Kelvin Ma <kelvinsthirteen@gmail.com> wrote:

There are hundreds of gl functions… I have to rewrite the signatures for
all of them??

On Thu, Mar 30, 2017 at 11:31 AM, Joe Groff <jgroff@apple.com> wrote:

> On Mar 30, 2017, at 7:47 AM, Kelvin Ma via swift-users < >> swift-users@swift.org> wrote:
>
> OpenGL functions are loaded at runtime by a function loader (like
GLFW). They’re defined in a header but obviously they don’t have
definitions at compile time so it causes a slew of linker errors when I try
to build
>
> error: undefined reference to 'glEnable'
> error: undefined reference to 'glBlendFunc'
> error: undefined reference to 'glClearColor'
> clang: error: linker command failed with exit code 1 (use -v to see
invocation)
> ...
>
> How do I build programs that use OpenGL functions?

If the functions are exported by the OpenGL library you're linking
against, then you may need to just use -lGL to link against it. That's not
likely to be portable, though, since implementations vary in what they
statically export. The macro metaprogramming used by GLFW and other
libraries to dynamically load GL entry points is probably not going to get
picked up by Swift's C importer, so you'd need to roll your own solution.
Something like this might work as a start:

func loadGLFunction<T>(name: String) -> T {
#if os(macOS)
  return unsafeBitCast(dlsym(RTLD_DEFAULT, name), to: T.self)
#elseif os(Linux)
  return unsafeBitCast(glXGetProcAddress(name), to: T.self)
#elseif os(Windows)
  return unsafeBitCast(wglGetProcAddress(name), to: T.self)
#endif
}

enum GL {
  static let begin: @convention(c) (GLenum) -> Void =
loadGLFunction("glBegin")
  static let end: @convention(c) () -> Void = loadGLFunction("glEnd")
  /*etc*/
}

-Joe