libigl / libigl-example-project

A blank project example showing how to use libigl and cmake.
Mozilla Public License 2.0
142 stars 121 forks source link

Commenting out viewer.launch() causes linker errors with imgui/glad (no imgui/glad functions called) #33

Open olkido opened 2 years ago

olkido commented 2 years ago

I tried to build a libigil-based project by extending this example. The first thing I tried to do is add an imgui window pane/ menu. I noticed that simply adding the relevant includes and declaring a menu causes the project to not build unless there is an "active" call to viewer.launch() present in the main.cpp code. If the viewer is not launched (for example by commenting the viewer.launch() line out or adding a return() before it -- see the attached main.cpp), I get linker errors due to (it seems) glad.c not having been included among the source files. I found this very odd (why would simply commenting out viewer.launch() cause linker errors without any functions from imgui/glad being called) so I thought I would share. Is this a known phenomenon? I am using Xcode 13 (example project built via cmake 3.20.1) . Attaching pictures of my main.cpp and the build log.

Screenshot 2021-10-19 at 17 49 13 Screenshot 2021-10-19 at 17 51 33
danielepanozzo commented 2 years ago

I remember something similar happening to me on xcode a few years ago. Could you try the same setup but asking cmake to create a standard makefile instead of generating an xcode project and check if you still get the error?

jdumas commented 2 years ago

Just making sure, but did you add the CMake target igl::opengl_glfw_imgui to the target_link_libraries() command?

olkido commented 2 years ago

I remember something similar happening to me on xcode a few years ago. Could you try the same setup but asking cmake to create a standard makefile instead of generating an xcode project and check if you still get the error?

Yea without xcode it works. Could it be some xcode (buggy) 'trick' to reduce compilation time (by selectively ignoring files depending on code) ?

Just making sure, but did you add the CMake target igl::opengl_glfw_imgui to the target_link_libraries() command?

I did. If I make sure that viewer.launch() is “active” in the code, Xcode compiles it fine:)

[It's really not a big issue in practise (why would anyone include/declare imgui stuff without running a call to viewer.launch() .... ). We did run across it though while trying to debug something else entirely so I just thought I'd put it out there in case someone else also has this issue. ]

jdumas commented 2 years ago

Is this happening when LIBIGL_USE_STATIC_LIBRARY is ON, or OFF? Agree it is a strange issue...

olkido commented 2 years ago

Library is OFF (I didn’t set it to ON at any point).

best, — olga

On 19.10.2021, at 18:55, Jérémie Dumas @.***> wrote:

Is this happening when LIBIGL_USE_STATIC_LIBRARY is ON, or OFF? Agree it is a strange issue...

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-example-project/issues/33#issuecomment-946916815, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB4TWIDC4DQSW7FYWPA22C3UHWPJZANCNFSM5GJQD5WA. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

danielepanozzo commented 2 years ago

I can reproduce it on my machine, I have no idea of where this is coming from. I think @olkido is right, it is probably some further optimization that xcode is doing when compiling the project.

I suggest to close this issue, I don't think it is worth investigating further as it is anyhow a case that will not happen in plausible use cases.

olkido commented 2 years ago

Agreed on my side. Just wanted to have it mentioned.

best,

--

olga

Sent from a mobile device. Please excuse typos and brevity.

On Wed, Oct 20, 2021, 18:22 Daniele Panozzo @.***> wrote:

I can reproduce it on my machine, I have no idea of where this is coming from. I think @olkido https://github.com/olkido is right, it is probably some further optimization that xcode is doing when compiling the project.

I suggest to close this issue, I don't think it is worth investigating further as it is anyhow a case that will not happen in plausible use cases.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-example-project/issues/33#issuecomment-947828991, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB4TWIH2MJTK3ZZQMR6NAH3UH3UENANCNFSM5GJQD5WA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

avaxman commented 2 years ago

I literally had the same problem now and this solved it (I looked through the issues first before solving). But srsly wtf.

jdumas commented 2 years ago

This was bothering me so I investigated the issue a bit more. Just to recap:

The root of the issue turned out to be uninitialized symbols in glad.c. When commenting out viewer.launch(), the call to gladLoadGLLoader will not be compiled. But this function is responsible for initializing symbols such as glad_glActiveTexture (see here).

Now why is this a problem for Xcode and not Makefile generators? Well, libtool has the following linking option:

-c    Include common symbols as definitions with respect to the table of contents.  This is seldom the intended behav-
      ior  for linking from a library, as it forces the linking of a library member just because it uses an uninitial-
      ized global that is undefined at that point in the linking.  This option is included only because this  was  the
      original behavior of ranlib.  This option is not the default.

(See this Stack Overflow thread for a related discussion)

What happened is that Xcode linked libglad.a without this option, while the Makefile project linked libglad.a with the -c option enabled. If the option is not provided, and gladLoadGLLoader() is not called, symbols such as glad_glActiveTexture will be stripped from libglad.a, leading to undefined references in the final binary.

Finally, the reason this is only an issue when you link against igl::opengl_glfw_imgui, is that this project will be compiling some files that call glad's OpenGL symbols (in the file imgui_impl_opengl3.cpp).

The discrepancy between the Xcode project and the Makefile is either a CMake bug, or a Xcode idiosyncrasy. But in any case there is probably nothing to fix. Either compile libigl statically, or call viewer.launch() in another unused function in your project as a workaround.

avaxman commented 2 years ago

Thanks! perhaps worth adding a disclaimer somewhere though that other people won’t waste more time on this.

On 08.01.2022, at 23:55, Jérémie Dumas @.***> wrote:

This was bothering me so I investigated the issue a bit more. Just to recap:

This only happens when libigl is compiled in header-only mode. This only happens with the Xcode generator on macOS (using the Makefile generator on macOS will work). The root of the issue turned out to be uninitialized symbols in glad.c. When commenting out viewer.launch(), the call to gladLoadGLLoader https://github.com/libigl/libigl/blob/54a4e4bafd7307c7b3b360c22082450fe752203f/include/igl/opengl/glfw/Viewer.cpp#L180 will not be compiled. But this function https://github.com/libigl/libigl-glad/blob/09b4969c56779f7ddf8e6176ec1873184aec890f/src/glad.c#L989 is responsible for initializing symbols such as glad_glActiveTexture https://github.com/libigl/libigl-glad/blob/09b4969c56779f7ddf8e6176ec1873184aec890f/src/glad.c#L383 (see here https://github.com/libigl/libigl-glad/blob/09b4969c56779f7ddf8e6176ec1873184aec890f/src/glad.c#L591).

Now why is this a problem for Xcode and not Makefile generators? Well, libtool has the following linking option:

-c Include common symbols as definitions with respect to the table of contents. This is seldom the intended behav- ior for linking from a library, as it forces the linking of a library member just because it uses an uninitial- ized global that is undefined at that point in the linking. This option is included only because this was the original behavior of ranlib. This option is not the default. (See this Stack Overflow thread https://stackoverflow.com/questions/19398742/os-x-linker-unable-to-find-symbols-from-a-c-file-which-only-contains-variables for a related discussion)

What happened is that Xcode linked libglad.a without this option, while the Makefile project linked libglad.a with the -c option enabled. If the option is not provided, and gladLoadGLLoader() is not called, symbols such as glad_glActiveTexture will be stripped from libglad.a, leading to undefined references in the final binary.

Finally, the reason this is only an issue when you link against igl::opengl_glfw_imgui, is that this project will be compiling some files that call glad's OpenGL symbols (in the file imgui_impl_opengl3.cpp https://github.com/libigl/libigl-imgui/blob/7e1053e750b0f4c129b046f4e455243cb7f804f3/CMakeLists.txt#L15).

The discrepancy between the Xcode project and the Makefile is either a CMake bug, or a Xcode idiosyncrasy. But in any case there is probably nothing to fix. Either compile libigl statically, or call viewer.launch() in another unused function in your project as a workaround.

— Reply to this email directly, view it on GitHub https://github.com/libigl/libigl-example-project/issues/33#issuecomment-1008171774, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACERY6HDU5UMSO5DUUFZXKDUVC6GVANCNFSM5GJQD5WA. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you commented.

jdumas commented 2 years ago

Well a simple fix would be to stop pretending the Viewer can be compiled as a header-only library... but I guess we can also add an entry in the FAQ. EDIT: Done.