-
Notifications
You must be signed in to change notification settings - Fork 747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modularize presets for ffmpeg #669
Conversation
BTW, the builds fail, let's make them pass! :) |
Argh.
I'd tend to prefer 1. It's less likely than a library defines an object named Global or G than named like the library itself. And we'd conform to the Java casing convention. |
I see, but we'd have like opencv_core_global and such after all, not too
interesting...
|
|
That won't work well when we need to use more than one |
Other option: |
That could work, but we'd end up with names like this:
Not exactly the most user-friendly naming scheme... |
Ok. |
Packages and outer classes are namespaces. If we want to be rigorous, we should try to match the C/C++ namespace concept, which means:
Concerning the constraints, we must define:
So the solution would be one preset-level package matching the unnamed namespace, and containing one special class for the global symbols. If we want to avoid a constant name for this class (like We would end up with the following classes:
But that would need some changes in JavaCPP: sharing of the global class between libraries and mapping of namespaces to class or package. And that will not suppress definitively the risk of clash between the global class name (FFmpeg, OpenCV...) and a class defined in the unnamed namespace of the presets, but that would limit the odds and we could always work around by adjusting the names. What do you think ? |
The concept of C++ namespaces doesn't map well to Java packages. What would
you do, for example, for instances of std::vector and such?
|
Namespaces can also span multiple native libraries, and we can have multiple namespaces in any given header file. It's quite a mess really. So we'd basically have to load all libraries to make sure we get everything for any given class. Also, trying to map namespaces doesn't solve the problem of where to put functions and variables that don't belong to a class. We'd need to come up with "global" classes for each namespace! We can map Java packages much more easily to native libraries, where each library contains lists of dependencies and symbols, similarly to how a Java package contains lists of imports and classes, especially when constrained by a Java module. How about something like this where we basically replace "javacpp" with the name of the submodules themselves and move the global classes to a "global" package alongside "helper" and "presets"? It would make it clear that we're accessing global functions via import statements without appending something clunky like "global" to the class names.
In cases like TensorFlow where there is only a single fat library we could also drop the last component of the package name, so we'd get instead And while we're at it also remove "javacpp-presets" from the groupId of the submodules since they are no longer limited to bindings generated exclusively with JavaCPP. @SamCarlberg Any opinions? In any case, I'll merge this PR, rename the branch to something like |
Before commenting your suggestion and giving up the idea of mapping namespaces, I'd like to understand why it's a bad idea. If we do not map symbol tables and put symbols from different C++ namespace in the same package or same outer class, how can we handle cases where the same library defines both I don't understand the question about std::vector. Yes, namespaces can span multiple libraries. If a library exports Yes a library can export Yes I agree this has nothing to do with the problem of finding a name for the global class. And this class should be different for each namespace indeed since two global functions with same name can exist in two different namespaces. A C++ program doesn't use the symbol of one library or another, it uses the symbol of a namespace. It's the silent job of the linker to find the symbol in a library or another. So I'm just wondering if we couldn't abstract away the concept of library in Java too and only keep the concepts of presets (= JPMS modules) and namespaces. |
Well, if you really want to try something, go for it. I'm not going to stop you. Think about it though, C++ namespaces are just a lazy way of naming things with "::" instead of "_" like we have to do in C. Nothing more, nothing else. It doesn't offer anything beyond that! Look just for example at imgproc.hpp: Everything's in "cv". There is no "cv::imgproc" namespace. What would you do about that? |
Does that mean "It's a good idea, but the needed changes are too deep for little benefit and we don't have the resources" or " It's a clearly bad idea, I won't take time arguing with this guy" ? We are talking about reorganisation of packages, which is needed for JPMS, I'm just suggesting ideas so that the result is the most logical we can do and so that the solution will last.
Put all in the |
Exactly, so it's part of the name and I wonder if we should not keep it. We could prefix the names replacing |
The point is, you'll need to figure out what your priorities are, for example, below. I can't decide that for you.
Since pretty much all OpenCV modules define identifiers in the root "cv" namespace, all libraries will have to be loaded together at once, effectively turning them into a single fat library, and that is how the Python bindings work, but you said that's not something you wanted to do. |
I think I see. This is not a problem for classes in the cv package. Classes in the same package could have a
I don't know what you are referencing but yes, loading all opencv libraries when you need just the core functionalities must be avoided. |
About your suggestion for the new package layout:
|
Ideally, the triplet of global, helper and presets classes should be only 1 class, but because we're generating one from the other, this isn't possible. That's basically the only reason why it's split in 3, and isn't related to other helper classes such as |
Ok. Technically, I don't see much reason in using separate packages. There may be cases where libraries are not meant to be loaded at the same time, for instance different flavours of the same library exporting different implementations for the same symbols. But we can always configure a special case for these libraries using the Practically, it may be nice to keep things separated just for the clarity of documentation. So no strong opinion about this here. If ever you want to keep the door open for mapping C++ namespaces one day (when it's important to preserve them), the layout could be:
We can imagine a parameter in the presets saying if we want a "library-wise" or "namespace-wise" layout. BTW, we need to change |
Hum, so you want to mix library names with namespaces. Even C++ doesn't do that, it just ignores library names and hopes the linker resolves everything. I don't see this working nicely. FYI, the Panama team is mapping the names of header files to class names for C right now: We can already specify a FQN for the |
… "." as relative to `target` (pull bytedeco/javacpp-presets#669)
There were actually 2 independent points in my last post:
In fact, with your last layout suggestion:
and if we activate some "keepNamespace" option in the presets, we could have the exact same layout but with:
and with global class
in lieu of the C++ Again, this is not something "I want", just some ideas for the future that should be kept in mind when making choices now for JPMS support. To link my 2 points, another idea is to have a second option "keepLibraryNames", that when turned off gets rid of the library names in the package names, and replaces the library name by the module name in the global class name. This could be the default behaviour for mono-library modules. |
We can name classes whatever we want, that's not an issue, but what do we gain doing this? Your imports are going to look a little different, and that's it. If you want to do this for the case where we have clashing names, they are still going to clash when trying to import them together. People are not going to like to use FQNs just because instead of giving them different names you put them in different packages! Anyway, would you have an actual example that exemplifies the usefulness of tinkering with names like that inconsistently between libraries? |
No I don't right now. Let's give up point 2. |
Ok, so let's try again with my last proposal? It should actually be easier to refactor projects that way than what we tried before. As for the library component in the package name, yes, let's leave it there for consistency. It only changes the import statements, which BTW provide a useful hint about which libraries we're actually loading. BTW, if you're wondering about what happens with namespaces, they are not thrown away completely. They still show up in the documentation: @Namespace(value="cv")
@NoOffset
public static class opencv_core.Mat
extends opencv_core.AbstractMat http://bytedeco.org/javacpp-presets/opencv/apidocs/org/bytedeco/javacpp/opencv_core.Mat.html |
No description provided.