Skip to content
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

Linking against multiple versions of PhysX #213

Open
asdasdasdasdasdf opened this issue Oct 30, 2019 · 5 comments
Open

Linking against multiple versions of PhysX #213

asdasdasdasdasdf opened this issue Oct 30, 2019 · 5 comments

Comments

@asdasdasdasdasdf
Copy link

I work with a large code base which uses PhysX for multiple isolated purposes within the same executable. The cost to upgrade from one version of PhysX to the next for this code base is very high. I would like to be able to take advantage of new features of PhysX in some areas of my code but in order to do so currently I'd need to upgrade the entire code base. My question/request is for there to be a viable upgrade path which does not require me to upgrade everything at once.

To be clear, obviously I can't have a single physics world partly simulated by 3.3.4 and partly by 4.1. What I want is to be able to have two unrelated worlds using different versions of PhysX linked into the same binary without violating the one definition rule.

One way to achieve this might be to put each version in its own namespace. I could apply this retroactively to my own fork of older versions but I'd like to not have to fork each new version to make this change. I suspect namespace aliases, possibly protected by compiler directives, could be used to keep the behavior as it is now for users that just want everything in the physx namespace but I haven't properly considered it.

@diegoferigo
Copy link

If the CMake targets would be properly exported, you could just install the two versions in different prefixes, and then in your code you could just use find_package(PhysX 4.1 REQUIRED) and maybe play a little with the CMAKE_INSTALL_PREFIX.

In this way you can have two separated installed versions and your software, thanks to the properties associated with the imported targets, would find the right headers and link against the right libraries, without any need to hardcode any path in downstream code.

I opened #208 to ask the implementation of this feature, let's see if the maintainers will consider it.

@asdasdasdasdasdf
Copy link
Author

I think what you're describing is subtly different, If I understand you correctly you want your software to have different make targets (I'm not super familiar with make so my terminology might be off) so that you can build it targeting PhysX version 4.1 OR PhysX version 4.2. My situation is that I want to be able to target PhysX 4.1 AND 4.2 simultaneously in the same binary without violating the one definition rule.

Please correct me if I've misunderstood.

@diegoferigo
Copy link

diegoferigo commented Nov 8, 2019

Sorry, probably my comment was not very clear if you're not familiar with CMake. It is as I wrote in the previous comment, the make <target> is something different. You can find few links to the documentation in #208 if you want to learn more.

Sources

If you need to use two PhysX version, I think that you can either:

  1. Clone twice the repository pointing to the two versions you need, and follow the documented steps to build and install (inside the repo folder)
  2. There's an undocumented way in which you can specify an external CMAKE_INSTALL_PREFIX while installing the CMake project. The prefix can be an external folder and you can select two different directories for the two versions. In this way, you just clone the repo once, install it, checkout to the second version you need, and install it in a different prefix.

Configure downstream project

In both ways, you get and installed tree in two different locations. You have to tell to your compile units (assuming you're using CMake as well) where to find the headers and the libraries in the filesystem. Right now you have to hardcode the include directory and the location to the libraries. It works, but it quite hacky for a downstream project.

Instead, if the upstream repository would have the support on a proper find_package in CONFIG mode, with properly exported targets, downstream users could avoid to hardcode paths and delegate CMake to do all the dirty work. Users only would need to find the right version for their needs (which can be more that one in a single project, as in your case) and link against the imported targets.


In your case, assuming you're on GNU/Linux, you have to follow the first case to configure your downstream project.

I'm not sure if upstream developers have a better solution.

@asdasdasdasdasdf
Copy link
Author

I'm on windows but I think this is a c++ issue not a build system or OS issue. Ultimately I could build physx 3.3.4 and physx 4.1 each manually and put them in different folders and manually configure an application to link in the dlls from both folders. The problem is that I would end up with two definitions of physx::PxVec3 (for example) which I don't think c++ will allow (and if it did it would cause a problem when the two definitions don't agree).

It seems to me like #208 is about automating the process to do the steps which I described doing manually but doesn't offer a solution to the resulting issue with trying to link conflicting dlls. Hopefully I'm not misunderstanding?

@diegoferigo
Copy link

diegoferigo commented Nov 18, 2019

If I understood what you mean, I think in your use case what discussed would work. I will make a short example, let me know if your need is different.

Assume a project with lib3 linking against physx 3.X, and lib4 linking against physx 4.X. If they both reside in different subfolders, and physx for both branches would support exported CMake targets, you could have the following:

project/
├── CMakeLists.txt
├── lib3
│   └── CMakeLists.txt
└── lib4
    └── CMakeLists.txt

In both libX CMakeLists.txt, you could have:

find_package(PhysX X.Y)
[...]
target_link_library(libX PhysX::Component [...])

They would link against a different version of the library. #222 is a first step towards it, thanks to @phcerdan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants