nanogui
nanogui copied to clipboard
Conan package for nanogui
Hello, Do you know about Conan? Conan is modern dependency manager for C++. And will be great if your library will be available via package manager for other developers.
Here you can find example, how you can create package for the library.
If you have any questions, just ask :-)
I tried to conan package it myself but kept having issues with nanovg linking. Would love to see a working package as it perfectly fit the libary to be on a package manager.
What kind of problems did you get? do you have a link for your recipe?
Yes I actually managed to make it work on OSX. I'm pretty new to conan so be gentle. But it works here. I have to figure out how to assign the dependencies to nanogui without needing to add it to each projects.
Here is the repository: https://bintray.com/melmass/MTB
So:
conan remote add MTB https://api.bintray.com/conan/melmass/MTB
You need to use the right package order, here is my conanfile.txt
for instance:
[requires]
eigen/3.3.4@conan/stable
nanovg/1.1@melmass/MTB
nanogui/1.1@melmass/MTB
[generators]
cmake
Here you can read how you can specify dependencies for your library: http://docs.conan.io/en/latest/mastering/conditional.html
Oh please support conan. Nanogui dependencies collide if you are using glad yourself or glfw.
@p-groarke I'm not sure how supporting conan would solve this. See the compilation docs on GLFW. NanoGUI merges the GLFW objects into the built library. I don't know conan well, but if you had something like
[requires]
glfw/version/tag
glad/version/tag
by using NanoGUI, I think it would just replace them with nanogui/version/tag
sort of thing.
@ZaMaZaN4iK perhaps you can shed some light on a couple of things to help determine whether or not NanoGUI is capable.
Required NanoGUI Changes
Currently, the NanoGUI installation is really only very useful for getting the python bindings installed. The C++ stuff gets installed, but not all of the features (e.g., third party headers) are installed.
-
The install scripts do not install the GLFW, NanoVG, or GLAD headers. This can be solved by NanoGUI performing the following header install (with say
/usr/local
asPREFIX
):PREFIX/ include/ nanogui/ ... all nanogui headers ... third_party/ GLFW/ nanovg.h etc
-
Correspondingly,
find_package(nanogui)
would need to set bothPREFIX/include/nanogui
andPREFIX/include/nanogui/third_party
as include locations. I know how to do both of these, but it'll take a little effort. -
We'd need to switch to full target-based "config" style for the installation, particularly for the requisite
NANOGUI_GLAD
compiler directives. AKAtarget_compile_definitions
. I think this can also be done.
Questions About Conan
I don't know Conan well, but I work with a similar package manager spack
. They have some concepts in there that NanoGUI would need.
- Since NanoGUI merges GLFW and NanoVG, and statically links against GLAD, is there a way to denote
conflicts("glfw")
etc -- explicitly specify conflicting packages? - On a similar note,
spack
has a notion of "providers". This comes in with things like MPI. So the alternative to specifyingconflicts
would be to make GLFW, NanoVG, and GLAD "virtual" classes, for which NanoGUIprovides("glfw")
etc.- This would be particularly useful for people using NanoGUI, because if you take the
conflicts
approach then any other projects they use that need GLFW will be disallowed altogether. With theprovides
interface, the idea would be to specifynanogui.so
as the GLFW library to other packages.
- This would be particularly useful for people using NanoGUI, because if you take the
- NanoGUI vendors Eigen internally to ensure that it can always build on its own -- its designed to build as a submodule rather than require users install it. @melMass mentioned that order is important, how can we know when Eigen is explicitly requested so that we can use that version of Eigen rather than the vendored copy?
- Is there anything in Conan with respect to python bindings? If not, we can just disable the python side altogether (which would also be easier).
So first questions about conan. I just created a conan dependency for glad, ~~I think the only dependency missing would be Eigen. I'll bug them about it ;)~~ (they have a conan package as well).
- You expose your dependencies through conan. GLFW is already available, so you'll say "requires GLFW3.2" for example. I also need GLFW, lets say 3.3, so I do the same. When I include your package, conan automagically fixes the conflict and includes the latest version. Both our projects are linked with 1 and only 1 library.
- If I understand correctly what your saying, that is exactly the problem conan fixes. No need to "block" your users ability to use the same libraries. Worst case conan fails and will explain the mismatch version.
- Until Eigen is provided on conan, that seems fine. Personally I use cmake
ExternalProject_Add
for my dependencies that don't have conan packages. So it works cross platform (on Windows as well) and the user doesn't have to do anything. It is better and more flexible than submodules. - I'm not sure about the bindings, however the conan build script is python itself. So you can pretty much do what you want. For example, I am working on a conan dependency that downloads a java jar, then downloads a json swagger API online and generates a c++ project and compiles it. It is very flexible.
There is a cppcon talk about conan, you might want to check them out. From what I understand, you want to enforce your dependency versions to your users. That is problematic to me :)
Good day
There is a small but very important difference here that is easy to overlook: NanoGUI does not link against GLFW, it "is" GLFW. By "is", the meaning here is that when nanogui.so
is built, the objects from GLFW are merged in. This is done to guarantee that NanoGUI can build anywhere from its intended usage: as a submodule. AKA GLFW does not need to be installed by the user. The same happens for NanoVG, and GLAD (when compiled) is linked statically.
The implication: you cannot link against GLFW and NanoGUI in the same project. Doing so will give you duplicate symbols. This is what I am talking about with a "conflicts" (blocking GLFW), or a "provider" interface. The "provider" route requires making changes to the GLFW conan package though, for something that is probably altogether not very common.
For Eigen, it's really just a matter of making sure the requested one is the one included when NanoGUI builds. That's more solvable than the GLFW problem, it's just a cmake configuration.
Can't both projects link statically to the same library? I'm pretty sure I've encountered this sort of problem before and haven't had an issue. It's been a while I've used static libraries though. However, you can specify static linking in your conan project. I believe it might link transitively: you link statically to glfw, i need link statically to glfw, I get your glfw symbols.
It is worth experimenting with. If there are conan issues with this sort of scenario, the devs are very friendly and I would bring it up to them.
Is there a reason why you would still link statically to glfw? You mention your users not having to install the library, but that problem is what conan fixes for you. Your users don't have to install anything. All libraries are installed in a predictable location whatever the platform it is. All your users do is
conan install .. --build missing
before running cmake. Thats it. It works :D
edit: They will probably want to use -s build_type=Debug
as well. But really there isn't more to it than that.
Ok, so I think I'm failing at communicating this point. I included too much information. In one sentence: NanoGUI does not link against GLFW, nor NanoVG, the full source of GLFW and NanoVG are compiled directly into NanoGUI. The static linking is only for GLAD.
What it comes down to: NanoGUI is currently self-contained. While having it supported in something like conan
would be nice, if changing NanoGUI to be compatible with conan
requires that it no longer remains self-contained, that's kind of a deal-breaker.
I went back and spliced in a manually linked GLFW, and you get warnings like this
$ ./mytest
objc[23402]: Class GLFWWindowDelegate is implemented in both /usr/local/opt/glfw/lib/libglfw.3.dylib (0x1028bcb08) and /Users/sven/Desktop/nanogui-test/jericho_clang_build/lib/nanogui/libnanogui.dylib (0x102845448). One of the two will be used. Which one is undefined.
...
Synopsis: I think I misremembered linking errors for this undefined behavior warning. Though things seem to work, it's a terrible idea to accept that as "OK". This can lead to more difficult bugs down the line.
One option would be to enable a CMake bypass for GLFW specifically (also requested in #297). This is kind of the core need to being able to package NanoGUI, in my opinion. Something like -DNANOGUI_SYSTEM_GLFW
, which would then resort to finding the system GLFW and if that fails then error the compilation. I don't know how many bypasses of this nature would be required in order to get NanoGUI conan-ready.
I think the two fixes you really need are
- Allow an external GLFW to be specified instead of compiling it in manually.
- Make NanoGUI install the NanoVG headers under
include/nanogui/third_party
, and in the header directories specified by CMake, set bothinclude/nanogui
andinclude/nanogui/third_party
. That needs to be done to prevent overwriting an existing NanoVG installation.
Basically, I'm happy to answer questions about the build system since I know it pretty well, but I'm not interested in writing the packaging script for something that doesn't need to be packaged.
I'll end my part of this discussion mentioning this talk from one of conan's creator : https://www.youtube.com/watch?v=67Am8Z6irjA
I really recommend you watch it, he explains in a much more eloquent way than I ever could why embedding your dependencies is bad. Cheers and good luck with nanogui!
Cross-ref #347 .
I will be working on updating / enabling external GLFW. Specifically, the GLFW stuff will include CMake updates related to installation as well.
This will pave the way for interested parties to maintain a conan package if they so desire, however I will not be involved in this at least at this time. NanoGUI can be enabled in Conan, but
- Conan defaults to static, a GUI library typically should be shared. I'm not sure what the right decision on shared vs static conan option should be default value since most conan packages default to static.
- NanoGUI does not have version numbers. You will have to use dates associated with commits (this was advised to me on the #conan cpplang slack channel, which is a great resource if you want to tackle this).
The dependencies for this repository should be
- Eigen3
- GLFW3
- ??? NanoVG ???
- This would require a CMake bypass on NanoGUI's part. This would add complexity that is undesirable in my opinion, especially if the
conanfile.py
is not tracked here (which is not my call, but I doubt @wjakob wants to take on that responsibility -- that also forces him to maintain the binaries on bintray). - Perhaps table this until it is possible to do Eigen and GLFW.
- This would require a CMake bypass on NanoGUI's part. This would add complexity that is undesirable in my opinion, especially if the
GLAD, even if it has a conan package, should not be done. You should let NanoGUI continue to build that locally. I can explain if you want, but the short version: GLAD is generated from a website with many options / profiles available; the one in NanoGUI is the one that should be used (though we could update GLAD here if needed).
I will post back after the PR that would enable this functionality so that interested parties can communicate / collaborate if desired (ideally somebody commits to maintaining one remote rather than a litany of them).
If you desire NanoGUI // Conan, please comment on anything else that you may need in CMakeLists.txt
to enable it. If you do, I can add it to the PR that updates the build system if it makes sense for NanoGUI independent of Conan (e.g., there will be no conan_basic_setup(...)
or anything going on, you will have to filter that in as shown in the docs.