anholt / libepoxy

Epoxy is a library for handling OpenGL function pointer management for you
Other
680 stars 161 forks source link

1.5.2 macOS run time failure "Couldn't open libOpenGL.so.0: dlopen(libOpenGL.so.0, 5): image not found" #176

Closed ilovezfs closed 6 years ago

ilovezfs commented 6 years ago

Regressed by https://github.com/anholt/libepoxy/pull/170

==> /usr/bin/clang test.c -L/usr/local/Cellar/libepoxy/1.5.2/lib -lepoxy -framework OpenGL -o test
test.c:12:5: warning: implicit declaration of function 'CGLChoosePixelFormat' is invalid in C99 [-Wimplicit-function-declaration]
    CGLChoosePixelFormat( attribs, &pix, &npix );
    ^
test.c:13:5: warning: implicit declaration of function 'CGLCreateContext' is invalid in C99 [-Wimplicit-function-declaration]
    CGLCreateContext(pix, (void*)0, &ctx);
    ^
test.c:16:5: warning: implicit declaration of function 'CGLReleasePixelFormat' is invalid in C99 [-Wimplicit-function-declaration]
    CGLReleasePixelFormat(pix);
    ^
test.c:17:5: warning: implicit declaration of function 'CGLReleaseContext' is invalid in C99 [-Wimplicit-function-declaration]
    CGLReleaseContext(pix);
    ^
4 warnings generated.
==> ls -lh test
-rwxr-xr-x  1 joe  admin   8.6K May 29 08:16 test
==> file test
test: Mach-O 64-bit executable x86_64
==> ./test
Couldn't open libOpenGL.so.0: dlopen(libOpenGL.so.0, 5): image not found
/usr/local/Homebrew/Library/Homebrew/debrew.rb:11:in `raise'
BuildError: Failed executing: ./test 

The test block runs

  test do
    (testpath/"test.c").write <<~EOS

      #include <epoxy/gl.h>
      #include <OpenGL/CGLContext.h>
      #include <OpenGL/CGLTypes.h>
      int main()
      {
          CGLPixelFormatAttribute attribs[] = {0};
          CGLPixelFormatObj pix;
          int npix;
          CGLContextObj ctx;

          CGLChoosePixelFormat( attribs, &pix, &npix );
          CGLCreateContext(pix, (void*)0, &ctx);

          glClear(GL_COLOR_BUFFER_BIT);
          CGLReleasePixelFormat(pix);
          CGLReleaseContext(pix);
          return 0;
      }
    EOS
    system ENV.cc, "test.c", "-L#{lib}", "-lepoxy", "-framework", "OpenGL", "-o", "test"
    system "ls", "-lh", "test"
    system "file", "test"
    system "./test"
  end

The problem is that although OPENGL_LIB gets defined for __APPLE__ at https://github.com/anholt/libepoxy/blob/791b28c186882eb8d56f1002acda1dbb4ac00de3/src/dispatch_common.c#L178 as

#define OPENGL_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"

it then gets redefined generically in the else at https://github.com/anholt/libepoxy/blob/791b28c186882eb8d56f1002acda1dbb4ac00de3/src/dispatch_common.c#L199 as

#define OPENGL_LIB "libOpenGL.so.0"

As a workaround in the Homebrew formula, I can

    inreplace "src/dispatch_common.c", '#define OPENGL_LIB "libOpenGL.so.0"', ""

A proper fix will probably involve guarding the generic #define OPENGL_LIB "libOpenGL.so.0" with an ifndef, or reorganizing the directives a bit.

Ref: https://github.com/Homebrew/homebrew-core/pull/28037

CC @ebassi @nwnk

nwnk commented 6 years ago

Honestly we should start by hooking up some macos builders in Travis, and writing some more tests for it.

ebassi commented 6 years ago

The OSX builder on the free Travis instance is permanently backed up, but I can try enabling it.

nwnk commented 6 years ago

@ebassi I think they end up being effectively serialized. I switched xserver's travis to only make one runner for whatever the newest OSX is, and that's usually quick enough. If we wanted more elaborate coverage we could set up the yml to start the full OSX test matrix only on specially named git branches.

ebassi commented 6 years ago

@nwnk I've added the osx builder on the Travis CI matrix, and massaged the build script so that it runs; need to run the test suite as well, and check if the build options matrix is working as intended

ebassi commented 6 years ago

@ilovezfs Could you have a look at #178 and check if that fixes the build for you?

Additionally, it would be great to have a small test case we can add to the suite, so that we can run it on macOS and ensure we're not regressing at run time.

To be fair, though, it seems that the errors you're seeing when building your test code are actually coming from macOS; it's hard to find some documentation that is not hopelessly outdated on how to build OpenGL code with C and Carbon.

ilovezfs commented 6 years ago

178 looks good. See https://gist.github.com/ilovezfs/9a1619a0d47d51277427c4af3b59cff0

Those warnings seem to be caused by a missing #include <OpenGL/OpenGL.h> in the test. If add that then I get

==> /usr/bin/clang test.c -L/usr/local/Cellar/libepoxy/1.5.3-alpha1/lib -lepoxy -framework OpenGL -o test
test.c:18:23: warning: incompatible pointer types passing 'CGLPixelFormatObj' (aka 'struct _CGLPixelFormatObject *') to parameter of type 'CGLContextObj _Nonnull' (aka 'struct _CGLContextObject *') [-Wincompatible-pointer-types]
    CGLReleaseContext(pix);
                      ^~~
/System/Library/Frameworks/OpenGL.framework/Headers/OpenGL.h:53:45: note: passing argument to parameter 'ctx' here
extern void CGLReleaseContext(CGLContextObj ctx) OPENGL_AVAILABLE(10_5);
                                            ^
1 warning generated.

So something is still a bit off with our test.

ebassi commented 6 years ago

@ilovezfs Thanks for testing; I've added your test to #179, with a fix for the wrong use of CGLReleaseContext(). Could you please add some licensing notes for the test, so I can accurately credit the authors?

ilovezfs commented 6 years ago

The test is from the original formula added in https://github.com/Homebrew/legacy-homebrew/pull/34345

From the comments, the test was written by @scoopr. See https://github.com/Homebrew/legacy-homebrew/pull/34345#issuecomment-74938134 https://github.com/scoopr/homebrew/commit/ae259fa3eb91884c8b88c5b6f8b0866419a4dc5c

ilovezfs commented 6 years ago

Yup, your revised test runs without warnings or errors:

==> /usr/bin/clang test.c -L/usr/local/Cellar/libepoxy/1.5.3-alpha1/lib -lepoxy -framework OpenGL -o test
==> ls -lh test
-rwxr-xr-x  1 joe  admin   8.6K May 30 01:45 test
==> file test
test: Mach-O 64-bit executable x86_64
==> ./test
ilovezfs commented 6 years ago

In terms of licensing, it's all BSD 2-clause "Simplified" License. See https://github.com/Homebrew/homebrew-core/#license

ebassi commented 6 years ago

@ilovezfs Brilliant, thanks!

ilovezfs commented 6 years ago

You're welcome!