Skip to content

Conversation

@davvid
Copy link
Contributor

@davvid davvid commented Jan 7, 2026

Windows expects cmake packaging files in the cmake/ directory.
Linux/UNIX expects cmake packaging files in $libdir/cmake/<name>/.

Export targets into a pxr:: namespace so that the targets
are named "pxr::arch", "pxr::tf", and so on.

This structure allows find_package(pxr) to find a custom usd
installation when its install prefix has been added to the
CMAKE_PREFIX_PATH environment variable.

Ref: https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure
Related-to: https://github.com/aousd/build-ig-initiatives/issues/15
Related-to: https://github.com/aousd/build-ig-initiatives/issues/10

davvid added 2 commits January 6, 2026 22:23
Declare which languages we use to avoid spending time setting up the
C compiler, which is not used in this project.
Windows expects cmake packaging files in the cmake/ directory.
Linux/UNIX expects cmake packaging files in $libdir/cmake/<name>/.

Export targets into a pxr:: namespace so that the targets
are named "pxr::arch", "pxr::tf", and so on.

This structure allows find_package(pxr) to find a custom usd
installation by when its install prefix has been added to the
CMAKE_PREFIX_PATH environment variable.

Ref: https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure
@jesschimein
Copy link
Collaborator

Filed as internal issue #USD-11757

❗ Please make sure that a signed CLA has been submitted!

(This is an automated message. See here for more information.)

if (WIN32)
set(pxr_cmake_dir "cmake")
else()
set(pxr_cmake_dir "${CMAKE_INSTALL_LIBDIR}/cmake/pxr")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so I'm clear - windows conventions and linux conventions differ not only in the prefix (ie, "lib" on linux), but also in the suffix? ie, an extra level of directories with the library name on linux is needed, but not on windows?

So the correct intended values (assuming default value for ${CMAKE_INSTALL_LIBDIR}) are:

windows: cmake
linux: lib/cmake/pxr

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's correct. CMake will search for lib/cmake/pxr/pxrConfig.cmake in $CMAKE_PREFIX_PATH (or its typical search locations) when find_package(pxr) is used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange.... but yep, I see from the config-mode-search-procedures doc you linked that windows searches "plain" cmake dir first. Well, best to stick with established conventions for each platform...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference of anyone else interested (including my future self) - the config directory search order breaks down like this by platform, if we ignore the CPS directories introduced in 4+ (for simplicity / clarity):

CMake config-mode-search order

(3.25 <= CMAKE_VERSION < 4)

Windows

Windows-only section

  • <prefix>/
  • <prefix>/(cmake|CMake)/
  • <prefix>/<name>*/
  • <prefix>/<name>*/(cmake|CMake)/
  • <prefix>/<name>*/(cmake|CMake)/<name>*/

Shared Linux + Windows section

  • <prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/
  • <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/
  • <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/

Linux

Linux-only section

  • <prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/
  • <prefix>/(lib/<arch>|lib*|share)/<name>*/
  • <prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/

Shared Linux + Windows section

  • <prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/
  • <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/
  • <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/

Apple

Apple-only section

  • <prefix>/<name>.framework/Resources/
  • <prefix>/<name>.framework/Resources/CMake/
  • <prefix>/<name>.framework/Versions/*/Resources/
  • <prefix>/<name>.framework/Versions/*/Resources/CMake/
  • <prefix>/<name>.app/Contents/Resources/
  • <prefix>/<name>.app/Contents/Resources/CMake/

Copy link
Contributor

@pmolodo pmolodo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good, though I'm a bit worried about the introduction of a baked @CMAKE_INSTALL_PREFIX@. (See comment below).

Also - got me thinking if maybe we should consider proposing openusdConfig.cmake instead of pxrConfig.cmake. (Also see comment below).

"${PROJECT_BINARY_DIR}/pxrConfig.cmake"
DESTINATION "${CMAKE_INSTALL_PREFIX}"
DESTINATION "${PXR_CMAKE_INSTALL_DESTINATION}"
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I see that as a side effect of making this work with DESTDIR, we're now making this a relative path, which recent cmake documentation recommends. (Possibly for this exact reason...)

endif()
set(PXR_LIBRARIES "")
set(PXR_INCLUDE_DIRS "${PXR_CMAKE_DIR}/include")
set(PXR_INCLUDE_DIRS "@CMAKE_INSTALL_PREFIX@/include")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about this change - by going with the template value for @CMAKE_INSTALL_PREFIX@, are we baking in an absolute path and making this less portable? ${PXR_CMAKE_DIR} was calculated from ${CMAKE_CURRENT_LIST_FILE}, which is portable.

I can see that with your changes, we now have a variable number of parent paths to get to the "install root" - so using ${CMAKE_CURRENT_LIST_FILE} becomes trickier... but we want to avoid baking in absolute paths.

Perhaps we want to do a set(PXR_CMAKE_INSTALL_DESTINATION "@PXR_CMAKE_INSTALL_DESTINATION@"), and then figure out how many parent directories up we need to go up based on the number of elements in that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...though if we do keep it, we might consider replacing

get_filename_component(PXR_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)

with just

set(PXR_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about this change - by going with the template value for @CMAKE_INSTALL_PREFIX@, are we baking in an absolute path and making this less portable? ${PXR_CMAKE_DIR} was calculated from ${CMAKE_CURRENT_LIST_FILE}, which is portable.

That's true. I like the idea of making these new changes in a brand-new openusd-config.cmake file instead of pxrConfig.cmake since it gives us an easier way to have a clean break with less backwards-compatibility concerns.

My recommendation would be that we don't need a PXR_CMAKE_DIR variable at all. Likewise PXR_INCLUDE_DIRS and PXR_LIBRARIES -- those variables are all remnants of the old way of doing cmake w/ path variables. We shouldn't need to expose these variables at all. Downstream projects should use the exported targets to build against openusd instead of manually configuring path variables, so there's no reason to provide them.

Not providing these variables in the newly-proposedopenusd-config.cmake seems like a good way forward.

endif()
set(PXR_LIBRARIES "")
set(PXR_INCLUDE_DIRS "${PXR_CMAKE_DIR}/include")
set(PXR_INCLUDE_DIRS "@CMAKE_INSTALL_PREFIX@/include")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... also - this is also effectively changing the location of PXR_INCLUDE_DIRS, right? Whereas previously it was the equivalent of ${CMAKE_INSTALL_PREFIX}/cmake/include, it's now just ${CMAKE_INSTALL_PREFIX}/include, right?

The latter seems correct, since there doesn't seem to be a ${CMAKE_INSTALL_PREFIX}/cmake/include... but that means this is also effectively a bug fix for PXR_INCLUDE_DIRS?

install(
EXPORT pxrTargets
DESTINATION "${PXR_CMAKE_INSTALL_DESTINATION}"
NAMESPACE "pxr::"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This got me thinking...

  • Hmm, maybe we should use "openusd::", since I think that's what we use, and that would be more in keeping with how other cmake packages are named (ie, the cmake package for OpenEXR is OpenEXR, no ilm).

  • ...though, we should probably change the name of the config file itself to be openusdConfig.cmake then, not pxrConfig.cmak

  • hmm, that would be a pretty big breaking change

  • ...OR... maybe we could leave the pxrConfig.cmake, for backward compatibility, and make a NEW openusdConfig.cmake, that has all our nice / modern fixes, without worrying about breaking backward compatibility. With the eventual goal being to remove pxrConfig.cmake altogether, and only create openusdConfig.cmake going forward.

Thoughts? Increases the CI / testing burden, and maintenance while supporting both, but could make it easier to get "future-focused", backwards-incompatible changes in.

endif()

include("${PXR_CMAKE_DIR}/cmake/pxrTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/pxrTargets.cmake")
Copy link
Contributor

@pmolodo pmolodo Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We get rid of the only 2 places where we use PXR_CMAKE_DIR, so we could consider getting rid of the var definition as well... but I guess it's a potentially useful var, so keeping it makes sense too. (Plus it's possible it's already used downstream...)

EDIT

I suppose if we DO keep PXR_CMAKE_DIR, though, we should consider swapping

get_filename_component(PXR_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)

for just

set(PXR_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}")

@davvid
Copy link
Contributor Author

davvid commented Jan 14, 2026

Further discussion in https://github.com/aousd/build-ig-initiatives/issues/24 is leaning towards mostly leaving pxrConfig.cmake as-is and updating the cmake packaging to start providing a new openusd-config.cmake with namespaced targets.

The goal may be that we'll make it so that find_package(openusd) becomes the suggested way of building against this package via cmake.

We'll open a new PR later once the initiative has had further discussion and I'll make sure to incorporate all of the helpful review notes from this PR as part of that work.

@davvid davvid closed this Jan 14, 2026
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

Successfully merging this pull request may close these issues.

3 participants