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

Add new CMakeLists.txt to provide PhysXConfig.cmake #222

Open
wants to merge 17 commits into
base: 4.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Generated files (placed in source tree)
PxConfig.h

#GitHub C++ gitignore
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app

#EDITORS#
*.swp
*.swo
*.orig
*.*.orig
Session.vim
.eclimrc
*.project
*.cproject
*.ycm_extra_conf.pyc

116 changes: 116 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,121 @@
# NVIDIA PhysX SDK 4.1

# Improved CMake integration (contributed by @phcerdan)
- Provide PhysXConfig.cmake and exported targets file for build and install tree.
- Other projects can use find_package(PhysX) where PhysX_DIR can be a build tree or an install tree.
- The implementation only adds two new CMakeLists.txt that do not collide with
the existing build procedure of Nvidia. Instead of using python and the generate_projects scripts, now it solely uses CMake in a standard way.
- This allows PhysX to be used with modern standards of CMake, making it compatible
with FetchContent (add_subdirectory) and ExternalProject (find_package) commands.
- Snippets and Samples have not been integrated into the new build procedure.
- But added a simpler project to show find_package(PhysX) usage.
- The original build procedure is maintained compatible for easier integration with future upstream changes from NVidia.

## Example of CMake usage

# Build and optionally install PhysX with just CMake:
```bash
mkdir PhysX; cd PhysX
git clone https://github.com/phcerdan/PhysX src
mkdir build; cd build;
cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=release -DCMAKE_INSTALL_PREFIX:PATH=/tmp/physx ../src
ninja install
```

# Your project using PhysX (example added)

```cmake
find_package(PhysX REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE PhysX::PhysXCommon PhysX::PhysXExtensions)
```

You can also use FetchContent, or ExternalProjects for handling PhysX automatically.

When building your project, just provide `PhysX_DIR` to where the PhysXConfig.cmake is located (it could be from a build or an install tree)
```bash
cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DPhysX_DIR:PATH=/tmp/physx/PhysX/bin/cmake/physx ../src
```

## Using FetchContent (building at configure time)

For now, the `CONFIGURATION_TYPES` of Nvidia PhysX are not default.
In order to "map" the standard CMake build/config types between a project and PhysX
we have to do extra work.
The following `CMake` gist configure and build PhysX using the variable `PHYSX_CONFIG_TYPE` (default to `release`)
to build PhysX with the chosen config type.
Also provides a install script to install PhysX with the project.
TODO(phcerdan): this installation script might require more flexibility and testing.
See [conversation](https://discourse.cmake.org/t/mapping-cmake-build-type-and-cmake-configuration-types-between-project-subdirectories/192/2)
that inspired this approach (thanks to @craig.scott)

```cmake
# Fetch physx (CMake phcerdan branch)
include(FetchContent)
FetchContent_Declare(
physx
GIT_REPOSITORY https://github.com/phcerdan/PhysX
GIT_TAG cmake_for_easier_integration
)
FetchContent_GetProperties(physx)
if(NOT physx_POPULATED)
message(STATUS " Populating PhysX...")
FetchContent_Populate(physx)
message(STATUS " Configuring PhysX...")
execute_process(
COMMAND ${CMAKE_COMMAND}
-S ${physx_SOURCE_DIR}/physx/
-B ${physx_BINARY_DIR}
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
WORKING_DIRECTORY ${physx_BINARY_DIR}
COMMAND_ECHO STDOUT
# OUTPUT_FILE ${physx_BINARY_DIR}/configure_output.log
# ERROR_FILE ${physx_BINARY_DIR}/configure_output.log
RESULT_VARIABLE result_config
)
if(result_config)
message(FATAL_ERROR "Failed PhysX configuration")
# see configuration log at:\n ${physx_BINARY_DIR}/configure_output.log")
endif()
# PhysX is always on release mode, but can be explicitly changed by user:
set(PHYSX_CONFIG_TYPE "release" CACHE INTERNAL "Config/build type for PhysX")
message(STATUS "Building PhysX... with CONFIG: ${PHYSX_CONFIG_TYPE}")
execute_process(
COMMAND ${CMAKE_COMMAND}
--build ${physx_BINARY_DIR}
--config ${PHYSX_CONFIG_TYPE}
WORKING_DIRECTORY ${physx_BINARY_DIR}
COMMAND_ECHO STDOUT
# OUTPUT_FILE ${physx_BINARY_DIR}/build_output.log
# ERROR_FILE ${physx_BINARY_DIR}/build_output.log
RESULT_VARIABLE result_build
)
message(STATUS " PhysX build complete")
if(result_build)
message(FATAL_ERROR "Failed PhysX build")
# see build log at:\n ${physx_BINARY_DIR}/build_output.log")
endif()
# add_subdirectory(${physx_SOURCE_DIR}/physx ${physx_BINARY_DIR})
endif()
# create rule to install PhysX when installing this project
install (CODE "
execute_process(
COMMAND ${CMAKE_COMMAND}
--build ${physx_BINARY_DIR}
--config ${PHYSX_CONFIG_TYPE}
--target install
WORKING_DIRECTORY ${physx_BINARY_DIR}
COMMAND_ECHO STDOUT
)")
# find_package works
find_package(PhysX REQUIRED
PATHS ${physx_BINARY_DIR}/sdk_source_bin
NO_DEFAULT_PATH
)
```


Copyright (c) 2019 NVIDIA Corporation. All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
5 changes: 3 additions & 2 deletions externals/cmakemodules/GetCompilerAndPlatform.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,10 @@ FUNCTION (GetPlatformBinName PLATFORM_BIN_NAME LIBPATH_SUFFIX)
ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "android")
SET(RETVAL "android.${ANDROID_ABI}.fp-soft")
ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "linux")
IF (${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "x86_64-unknown-linux-gnu" OR ${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "x86_64-linux-gnu")
IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
SET(RETVAL "linux.clang")
ELSEIF(${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "aarch64-unknown-linux-gnueabi" OR ${CMAKE_LIBRARY_ARCHITECTURE} STREQUAL "aarch64-linux-gnu")
ELSEIF(${CMAKE_CXX_COMPILER_ID} MATCHES "^ARM.*"
OR ${CMAKE_CXX_COMPILER} MATCHES "arm")
SET(RETVAL "linux.aarch64")
ENDIF()
ENDIF()
Expand Down
2 changes: 1 addition & 1 deletion externals/cmakemodules/NvidiaBuildOptions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,4 @@ FUNCTION(StripPackmanVersion IN_VERSION _OUTPUT_VERSION)
OUT_V2 ${OUT_V})

SET(${_OUTPUT_VERSION} ${OUT_V2} PARENT_SCOPE)
ENDFUNCTION(StripPackmanVersion)
ENDFUNCTION(StripPackmanVersion)
179 changes: 179 additions & 0 deletions physx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in the
## documentation and/or other materials provided with the distribution.
## * Neither the name of NVIDIA CORPORATION nor the names of its
## contributors may be used to endorse or promote products derived
## from this software without specific prior written permission.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## Copyright (c) 2018-2019 NVIDIA Corporation. All rights reserved.
## Copyright (c) 2019 Pablo Hernandez-Cerdan

cmake_minimum_required(VERSION 3.13)
# Change options for CMAKE_BUILD_TYPE and set default.
# Same values than CMAKE_CONFIGURATION_TYPES
# From https://gitlab.kitware.com/cmake/cmake/issues/19401
get_property(multiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT multiConfig AND NOT DEFINED CMAKE_BUILD_TYPE)
set(default_build_type "release")
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Choose the type of build.")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"release" "profile" "checked" "debug")

Choose a reason for hiding this comment

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

I'm not aware of what "checked" and ''profile" are. If they are not standard, is there any documentation?

I would also add RelWithDebInfo and MinSizeRel https://cmake.org/cmake/help/v3.0/variable/CMAKE_BUILD_TYPE.html.

Copy link
Author

Choose a reason for hiding this comment

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

The only thing I haven't understood (even before this PR) is the libPhysXGPU status, and I'm not a PhysX expert since I still have to start using it. If I got it right, the only way to have a proper GPU / CUDA support is using the closed-source libraries? When I first tried to compile the project, I think that that library was compiled. Can you please provide more details about it?

I am not from NVidia, but from what I understand yes, libPhysXGpu (PhysXDevice in Windows...) are indeed close source and distributed by Nvidia in a binary form with each update of this repository. Only these GPU kernels are closed source, the rest is open source and is compiled when you build the project.

Following up, these libraries are distributed for the 4 non-standard configurations of Nvidia: release, profile, checked, debug. Each one having their own compiler flags.
Your request of adding the standard RelWithDebInfo etc, will have the problem of not having a matching GPU library with the same configuration. So, I would discard it for now.

Choose a reason for hiding this comment

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

Your comment makes totally sense, thanks for the clarification.

endif()

file(READ "version.txt" PHYSX_VERSION)
project(PhysX
LANGUAGES C CXX
VERSION ${PHYSX_VERSION})
message(STATUS "PhysX VERSION: ${PHYSX_VERSION}")
cmake_policy(SET CMP0057 NEW) # Enable IN_LIST
cmake_policy(SET CMP0077 NEW) # option() does nothing when variable is alredy set

# PhysXSDK options:
option(PX_BUILDSNIPPETS "Generate the snippets" OFF)
option(PX_BUILDPUBLICSAMPLES "Generate the samples" OFF)
option(PX_CMAKE_SUPPRESS_REGENERATION "Disable zero_check projects" OFF)
# PhysX options:
option(PX_SCALAR_MATH "Disable SIMD math" OFF)
option(PX_GENERATE_STATIC_LIBRARIES "Generate static libraries" OFF)
if(NOT DEFINED BUILD_SHARED_LIBS)
if(PX_GENERATE_STATIC_LIBRARIES)
set(BUILD_SHARED_LIBS OFF)
else()
set(BUILD_SHARED_LIBS ON)
endif()
else()
if(BUILD_SHARED_LIBS EQUAL PX_GENERATE_STATIC_LIBRARIES)
message(FATAL_ERROR "Contradictory options: BUILD_SHARED_LIBS and PX_GENERATE_STATIC_LIBRARIES have both the same value: ${BUILD_SHARED_LIBS}")
endif()
endif()
Comment on lines +69 to +79

Choose a reason for hiding this comment

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

What about adding this variable in CACHE so that downstream users can easily switch them with ccmake or cmake gui?

Copy link
Author

Choose a reason for hiding this comment

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

Users can do that with the PX_GENERATE_STATIC_LIBRARIES option (stored in the CACHE already). I would prefer to keep changes from current NVidia setup at a minimum to facilitate future integration.

Choose a reason for hiding this comment

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

Ow that's right, I missed it!

message(STATUS "BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}")
message(STATUS " PX_GENERATE_STATIC_LIBRARIES: ${PX_GENERATE_STATIC_LIBRARIES}")
option(PX_EXPORT_LOWLEVEL_PDB "Export low level pdb's" OFF)
option(PX_GENERATE_GPU_PROJECTS_ONLY "Generate GPU projects only. (Untested)" OFF)
mark_as_advanced(PX_GENERATE_GPU_PROJECTS_ONLY)

set(PUBLIC_RELEASE OFF)
# Enable folder properties
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

if(CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES debug checked profile release)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Reset config to what we need"
FORCE)

set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "")
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "")

endif()

# Disable zero_check projects. The default for Switch and XboxOne is ON.
if(PX_CMAKE_SUPPRESS_REGENERATION)
set(CMAKE_SUPPRESS_REGENERATION TRUE)
endif()

### Set PHYSX_ROOT_DIR to PROJECT_SOURCE_DIR
if(DEFINED PHYSX_ROOT_DIR)
message(WARNING "PHYSX_ROOT_DIR is externally defined, but it will be overwritten in this CMakeLists. DEPRECATED")
message("PHYSX_ROOT_DIR (externally set --not used--): ${PHYSX_ROOT_DIR}")
message("PHYSX_ROOT_DIR (currently set): ${PROJECT_SOURCE_DIR}")
endif()
set(PHYSX_ROOT_DIR ${PROJECT_SOURCE_DIR})

### Set TARGET_BUILD_PLATFORM using CMAKE_SYSTEM_NAME
# for compatibility with current CMake files,
# for cross-complation, CMAKE_SYSTEM_NAME can be set when running cmake
if(DEFINED TARGET_BUILD_PLATFORM)
if(TARGET_BUILD_PLATFORM STREQUAL "switch" OR
TARGET_BUILD_PLATFORM STREQUAL "playstation" OR
TARGET_BUILD_PLATFORM STREQUAL "ios")
message(FATAL_ERROR "switch, playstation and ios builds are not valid because have not been tested. Use official repository for these.")
endif()
message(INFO "TARGET_BUILD_PLATFORM (externally set --not used--): ${TARGET_BUILD_PLATFORM}")
endif()

set(TARGET_BUILD_PLATFORM "")
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(TARGET_BUILD_PLATFORM "windows")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(TARGET_BUILD_PLATFORM "linux")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(TARGET_BUILD_PLATFORM "mac")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
set(TARGET_BUILD_PLATFORM "android")
endif()

### Set CMake folders
set(CMAKEMODULES_PATH ${PROJECT_SOURCE_DIR}/../externals/cmakemodules/
CACHE INTERNAL "Path to CMakeModules")
set(CMAKEMODULES_NAME "CMakeModules" CACHE INTERNAL "CMakeModules name")
set(CMAKEMODULES_VERSION "1.27" CACHE INTERNAL "CMakeModules version from generation batch")
# CMAKE_MODULE_PATH is empty by default
list(APPEND CMAKE_MODULE_PATH ${CMAKEMODULES_PATH})

### Set platform specific files
set(PROJECT_CMAKE_FILES_DIR source/compiler/cmake)
set(PROJECT_CMAKE_FILES_ABSOLUTE_DIR ${PHYSX_ROOT_DIR}/${PROJECT_CMAKE_FILES_DIR})
# The following files define all the flags specific to platforms, compilers and build configurations.
# The file is included in the source/ subdirectory
set(PLATFORM_CMAKELISTS "${PHYSX_ROOT_DIR}/${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/CMakeLists.txt")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# INSTALL PATHS
# XXX(phcerdan) CMAKE_INSTALL_PREFIX by definition has to point to the root folder of the installation
# but the upstream python configuration adds PhysX to the CMAKE_INSTALL_PREFIX, which is not standard,
# and then hack it to install PxShared in parallel to PhysX. Solved here:
set(PHYSX_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/PhysX CACHE INTERNAL "Install path to install PhysX")
set(PXSHARED_PATH ${PROJECT_SOURCE_DIR}/../pxshared CACHE INTERNAL "Path to PxShared source")
set(PXSHARED_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/PxShared CACHE INTERNAL "Path to install PxShared")

# Set PX_ROOT_LIB_DIR (used in cmake files)
string(TOLOWER ${CMAKE_C_COMPILER_ID} compiler_id)
# No need to add TARGET_BUILD_PLATFORM and compiler_id in the folder structure
# set(PX_ROOT_LIB_DIR "${PHYSX_INSTALL_PREFIX}/bin/${TARGET_BUILD_PLATFORM}\.${compiler_id}")
set(PX_ROOT_LIB_DIR "${PHYSX_INSTALL_PREFIX}/bin")

# We add CMakeLists.txt in the source folders, following standard CMake practices
# Add PhysX SDK Source code to solution
set(BUILD_SOURCE_FOLDER ${CMAKE_CURRENT_BINARY_DIR}/sdk_source_bin)
add_subdirectory(source ${BUILD_SOURCE_FOLDER})

# TODO(phcerdan) Snippets and Samples are not integrated with the new CMake procedure
# But check the project_using_physx for hints on how to integrate it.
if(PX_BUILDSNIPPETS)
# Add Snippets projects into the solution
add_subdirectory(${PHYSX_ROOT_DIR}/snippets/compiler/cmake ${CMAKE_CURRENT_BINARY_DIR}/sdk_snippets_bin)

message("Added Snippets")
endif()

if(PX_BUILDPUBLICSAMPLES)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR
CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Add samples projects into the solution
add_subdirectory(${PHYSX_ROOT_DIR}/samples/compiler/cmake ${CMAKE_CURRENT_BINARY_DIR}/sdk_samples_bin)

message("Added Samples")
endif()
endif()

4 changes: 2 additions & 2 deletions physx/buildtools/presets/public/linux.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<cmakeSwitch name="PX_GENERATE_STATIC_LIBRARIES" value="True" comment="Generate static libs" />
</CMakeSwitches>
<CMakeParams>
<cmakeParam name="CMAKE_INSTALL_PREFIX" value="install/linux/PhysX" comment="Install path relative to PhysX SDK root" />
<cmakeParam name="CMAKE_INSTALL_PREFIX" value="install/linux" comment="Install path relative to PhysX SDK root" />
</CMakeParams>
</preset>
</preset>
2 changes: 1 addition & 1 deletion physx/compiler/public/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,4 @@ ENDIF()
IF(TARGET_BUILD_PLATFORM STREQUAL "switch")
FILE(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/ALL_BUILD.vcxproj.user" INPUT "${CMAKE_MODULE_PATH}/switch/Microsoft.Cpp.${NX_TARGET_DEVKIT}.user.props" CONDITION 1)
FILE(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/INSTALL.vcxproj.user" INPUT "${CMAKE_MODULE_PATH}/switch/Microsoft.Cpp.${NX_TARGET_DEVKIT}.user.props" CONDITION 1)
ENDIF()
ENDIF()
Loading