diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e3e2aa42..1b6c8262c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,10 +20,37 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -# All options defined here +### Dependencies +set(OpenGL_GL_PREFERENCE GLVND) +find_package(OpenGL) +if(OPENGL_FOUND) + add_definitions(-DXR_USE_GRAPHICS_API_OPENGL) +elseif(BUILD_ALL_EXTENSIONS) + message(FATAL_ERROR "OpenGL not found") +endif() + +if(NOT CMAKE_VERSION VERSION_LESS 3.7.0) + # Find the Vulkan headers + find_package(VulkanHeaders) + find_package(Vulkan) +endif() +if(VulkanHeaders_FOUND) + add_definitions(-DXR_USE_GRAPHICS_API_VULKAN) +elseif(BUILD_ALL_EXTENSIONS) + message(FATAL_ERROR "Vulkan headers not found") +endif() + +find_package(Threads REQUIRED) +find_package(JsonCpp) + +### All options defined here option(BUILD_LOADER "Build loader" ON) option(BUILD_ALL_EXTENSIONS "Build loader and layers with all extensions" OFF) -option(BUILD_LOADER_WITH_EXCEPTION_HANDLING "Enable exception handling in the loader. Leave this on unless your standard library is built to not throw." ON) +option( + BUILD_LOADER_WITH_EXCEPTION_HANDLING + "Enable exception handling in the loader. Leave this on unless your standard library is built to not throw." + ON +) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") option(DYNAMIC_LOADER "Build the loader as a .dll library" OFF) else() @@ -40,10 +67,9 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/conformance" AND NOT CMAKE_SYSTEM_NAME ST endif() include(CMakeDependentOption) -find_package(JsonCpp) -cmake_dependent_option(BUILD_WITH_SYSTEM_JSONCPP "Use system jsoncpp instead of vendored source" ON - "JSONCPP_FOUND" OFF) - +cmake_dependent_option( + BUILD_WITH_SYSTEM_JSONCPP "Use system jsoncpp instead of vendored source" ON "JSONCPP_FOUND" OFF +) # Several files use these compile-time OS switches if(WIN32) @@ -52,6 +78,19 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_definitions(-DXR_OS_LINUX) endif() +# This is a little helper library for setting up OpenGL +if(OPENGL_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/common/gfxwrapper_opengl.c") + add_library(openxr-gfxwrapper STATIC common/gfxwrapper_opengl.c common/gfxwrapper_opengl.h) + target_include_directories(openxr-gfxwrapper PUBLIC ${PROJECT_SOURCE_DIR}/external/include) + if(TARGET OpenGL::OpenGL) + target_link_libraries(openxr-gfxwrapper PUBLIC OpenGL::OpenGL) + elseif(TARGET OpenGL::GL) + target_link_libraries(openxr-gfxwrapper PUBLIC OpenGL::GL) + else() + target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_LIBRARIES}) + endif() +endif() + # Determine the presentation backend for Linux systems. # Use an include because the code is pretty big. if(CMAKE_SYSTEM_NAME STREQUAL "Linux") @@ -60,48 +99,49 @@ endif() # Several files use these compile-time platform switches if(WIN32) - add_definitions( -DXR_USE_PLATFORM_WIN32 ) -elseif( PRESENTATION_BACKEND MATCHES "xlib" ) - add_definitions( -DXR_USE_PLATFORM_XLIB ) -elseif( PRESENTATION_BACKEND MATCHES "xcb" ) - add_definitions( -DXR_USE_PLATFORM_XCB ) + add_definitions(-DXR_USE_PLATFORM_WIN32) +elseif(PRESENTATION_BACKEND MATCHES "xlib") + add_definitions(-DXR_USE_PLATFORM_XLIB) +elseif(PRESENTATION_BACKEND MATCHES "xcb") + add_definitions(-DXR_USE_PLATFORM_XCB) # TODO remove once conformance supports XCB set(BUILD_CONFORMANCE_TESTS OFF) -elseif( PRESENTATION_BACKEND MATCHES "wayland" ) - add_definitions( -DXR_USE_PLATFORM_WAYLAND ) +elseif(PRESENTATION_BACKEND MATCHES "wayland") + add_definitions(-DXR_USE_PLATFORM_WAYLAND) # TODO remove once conformance supports Wayland set(BUILD_CONFORMANCE_TESTS OFF) endif() -# Enable graphics API available to the build. -if (NOT CMAKE_VERSION VERSION_LESS 3.7.0) - # Find the Vulkan headers - find_package(VulkanHeaders) - if (VulkanHeaders_FOUND) - add_definitions(-DXR_USE_GRAPHICS_API_VULKAN) - endif() - # Find the Vulkan loader. - find_package(Vulkan) - # To use simply include ${Vulkan_LIBRARY} in your target_link_library or - # wherever you normally link your library files to your target. +add_library(openxr-all-supported INTERFACE) +if(BUILD_WITH_XLIB_HEADERS) + target_compile_definitions(openxr-all-supported INTERFACE XR_USE_PLATFORM_XLIB) endif() -if (BUILD_ALL_EXTENSIONS AND NOT VulkanHeaders_FOUND) - message(FATAL_ERROR "Vulkan headers not found") +if(BUILD_WITH_XCB_HEADERS) + target_compile_definitions(openxr-all-supported INTERFACE XR_USE_PLATFORM_XCB) +endif() + +if(BUILD_WITH_WAYLAND_HEADERS) + target_compile_definitions(openxr-all-supported INTERFACE XR_USE_PLATFORM_WAYLAND) endif() # Find glslc shader compiler. # On Android, the NDK includes the binary, so no external dependency. if(ANDROID) - file(GLOB glslc-folders ${ANDROID_NDK}/shader-tools/*) + file(GLOB glslc_folders ${ANDROID_NDK}/shader-tools/*) + find_program( + GLSL_COMPILER glslc + PATHS ${glslc_folders} + NO_DEFAULT_PATH + ) else() - file(GLOB glslc-folders $ENV{VULKAN_SDK}/*) + file(GLOB glslc_folders $ENV{VULKAN_SDK}/*) + find_program(GLSL_COMPILER glslc PATHS ${glslc_folders}) endif() -find_program(CMAKE_GLSL_COMPILER glslc PATHS ${glslc-folders} NO_DEFAULT_PATH) -if(CMAKE_GLSL_COMPILER) - message(STATUS "Found glslc: ${CMAKE_GLSL_COMPILER}") +if(GLSL_COMPILER) + message(STATUS "Found glslc: ${GLSL_COMPILER}") else() message(STATUS "Could NOT find glslc, using precompiled .spv files") endif() @@ -111,11 +151,11 @@ function(compile_glsl run_target_name) foreach(in_file IN LISTS ARGN) get_filename_component(glsl_stage ${in_file} NAME_WE) set(out_file ${CMAKE_CURRENT_BINARY_DIR}/${glsl_stage}.spv) - if(CMAKE_GLSL_COMPILER) + if(GLSL_COMPILER) # Run glslc if we can find it add_custom_command( OUTPUT ${out_file} - COMMAND ${CMAKE_GLSL_COMPILER} -mfmt=c -fshader-stage=${glsl_stage} ${in_file} -o ${out_file} + COMMAND ${GLSL_COMPILER} -mfmt=c -fshader-stage=${glsl_stage} ${in_file} -o ${out_file} DEPENDS ${in_file} ) else() @@ -126,21 +166,11 @@ function(compile_glsl run_target_name) endif() list(APPEND glsl_output_files ${out_file}) endforeach() - add_custom_target( - ${run_target_name} ALL - DEPENDS ${glsl_output_files} - ) - set_target_properties(${run_target_name} PROPERTIES FOLDER ${HELPER_FOLDER}) + add_custom_target(${run_target_name} ALL DEPENDS ${glsl_output_files}) + set_target_properties(${run_target_name} PROPERTIES FOLDER ${HELPER_FOLDER}) endfunction() -find_package(OpenGL) -if (OPENGL_FOUND) - add_definitions(-DXR_USE_GRAPHICS_API_OPENGL) -elseif(BUILD_ALL_EXTENSIONS) - message(FATAL_ERROR "OpenGL not found") -endif() - if(WIN32) add_definitions(-DXR_USE_GRAPHICS_API_D3D11) add_definitions(-DXR_USE_GRAPHICS_API_D3D12) @@ -155,8 +185,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/common_config.h.in ${CMAKE_CURRENT_BI add_definitions(-DOPENXR_HAVE_COMMON_CONFIG) # Be able to find pre-generated files, if used. -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include - ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}) add_definitions(-DXR_USE_TIMESPEC) @@ -166,9 +195,13 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/version.cmake) # Path separators ( : or ; ) are not handled well in CMake. # This seems like a reasonable approach. if(WIN32) - set(CODEGEN_PYTHON_PATH "${PROJECT_SOURCE_DIR}/specification/scripts;${PROJECT_SOURCE_DIR}/src/scripts;$ENV{PYTHONPATH}") + set(CODEGEN_PYTHON_PATH + "${PROJECT_SOURCE_DIR}/specification/scripts;${PROJECT_SOURCE_DIR}/src/scripts;$ENV{PYTHONPATH}" + ) else() - set(CODEGEN_PYTHON_PATH "${PROJECT_SOURCE_DIR}/specification/scripts:${PROJECT_SOURCE_DIR}/src/scripts:$ENV{PYTHONPATH}") + set(CODEGEN_PYTHON_PATH + "${PROJECT_SOURCE_DIR}/specification/scripts:${PROJECT_SOURCE_DIR}/src/scripts:$ENV{PYTHONPATH}" + ) endif() # General code generation macro used by several targets. @@ -179,22 +212,26 @@ macro(run_xr_xml_generate dependency output) list(APPEND GENERATED_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${output}") else() if(NOT PYTHON_EXECUTABLE) - message(FATAL_ERROR "Python 3 not found, but pre-generated ${CMAKE_CURRENT_SOURCE_DIR}/${output} not found") + message( + FATAL_ERROR + "Python 3 not found, but pre-generated ${CMAKE_CURRENT_SOURCE_DIR}/${output} not found" + ) endif() - add_custom_command(OUTPUT ${output} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" + add_custom_command( + OUTPUT ${output} + COMMAND + ${CMAKE_COMMAND} -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" ${PYTHON_EXECUTABLE} - ${PROJECT_SOURCE_DIR}/src/scripts/src_genxr.py - -registry ${PROJECT_SOURCE_DIR}/specification/registry/xr.xml - ${output} + ${PROJECT_SOURCE_DIR}/src/scripts/src_genxr.py + -registry ${PROJECT_SOURCE_DIR}/specification/registry/xr.xml + ${output} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS - "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" + DEPENDS "${PROJECT_SOURCE_DIR}/specification/registry/xr.xml" "${PROJECT_SOURCE_DIR}/specification/scripts/generator.py" "${PROJECT_SOURCE_DIR}/specification/scripts/reg.py" "${PROJECT_SOURCE_DIR}/src/scripts/${dependency}" "${PROJECT_SOURCE_DIR}/src/scripts/src_genxr.py" - ${ARGN} + ${ARGN} COMMENT "Generating ${output} using ${PYTHON_EXECUTABLE} on ${dependency}" ) set_source_files_properties(${output} PROPERTIES GENERATED TRUE) @@ -205,14 +242,23 @@ endmacro() # Layer JSON generation macro used by several targets. macro(gen_xr_layer_json filename layername libfile version desc genbad) - add_custom_command(OUTPUT ${filename} - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" + add_custom_command( + OUTPUT ${filename} + COMMAND + ${CMAKE_COMMAND} -E env "PYTHONPATH=${CODEGEN_PYTHON_PATH}" ${PYTHON_EXECUTABLE} - ${PROJECT_SOURCE_DIR}/src/scripts/generate_api_layer_manifest.py - -f ${filename} -n ${layername} -l ${libfile} -a ${MAJOR}.${MINOR} -v ${version} ${genbad} -d ${desc} + ${PROJECT_SOURCE_DIR}/src/scripts/generate_api_layer_manifest.py + -f ${filename} + -n ${layername} + -l ${libfile} + -a ${MAJOR}.${MINOR} + -v ${version} + ${genbad} + -d ${desc} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${PROJECT_SOURCE_DIR}/src/scripts/generate_api_layer_manifest.py - COMMENT "Generating API Layer JSON ${filename} using -f ${filename} -n ${layername} -l ${libfile} -a ${MAJOR}.${MINOR} -v ${version} ${genbad} -d ${desc}" + COMMENT + "Generating API Layer JSON ${filename} using -f ${filename} -n ${layername} -l ${libfile} -a ${MAJOR}.${MINOR} -v ${version} ${genbad} -d ${desc}" ) endmacro() @@ -221,13 +267,13 @@ set(GENERATED_OUTPUT) set(GENERATED_DEPENDS) run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table.h) run_xr_xml_generate(utility_source_generator.py xr_generated_dispatch_table.c) -add_custom_target(xr_global_generated_files DEPENDS - ${GENERATED_DEPENDS} -) +add_custom_target(xr_global_generated_files DEPENDS ${GENERATED_DEPENDS}) set_target_properties(xr_global_generated_files PROPERTIES FOLDER ${CODEGEN_FOLDER}) set(COMMON_GENERATED_OUTPUT ${GENERATED_OUTPUT}) +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") + if(BUILD_LOADER) add_subdirectory(loader) endif() @@ -243,6 +289,3 @@ endif() if(BUILD_CONFORMANCE_TESTS) add_subdirectory(conformance) endif() - - - diff --git a/src/api_layers/CMakeLists.txt b/src/api_layers/CMakeLists.txt index bba0fab95..4cfeadd7b 100644 --- a/src/api_layers/CMakeLists.txt +++ b/src/api_layers/CMakeLists.txt @@ -66,6 +66,7 @@ add_library(XrApiLayer_api_dump SHARED ) set_target_properties(XrApiLayer_api_dump PROPERTIES FOLDER ${API_LAYERS_FOLDER}) +target_link_libraries(XrApiLayer_api_dump PRIVATE openxr-all-supported) add_dependencies(XrApiLayer_api_dump generate_openxr_header xr_global_generated_files @@ -128,6 +129,7 @@ add_library(XrApiLayer_core_validation SHARED ) set_target_properties(XrApiLayer_core_validation PROPERTIES FOLDER ${API_LAYERS_FOLDER}) +target_link_libraries(XrApiLayer_core_validation PRIVATE openxr-all-supported) add_dependencies(XrApiLayer_core_validation generate_openxr_header xr_global_generated_files diff --git a/src/cmake/presentation.cmake b/src/cmake/presentation.cmake index 54af9f72f..55af81706 100644 --- a/src/cmake/presentation.cmake +++ b/src/cmake/presentation.cmake @@ -1,101 +1,137 @@ set(PRESENTATION_BACKENDS xlib xcb wayland) -set(PRESENTATION_BACKEND xlib CACHE STRING - "Presentation backend chosen at configure time") -set_property(CACHE PRESENTATION_BACKEND PROPERTY STRINGS - ${PRESENTATION_BACKENDS}) +set(PRESENTATION_BACKEND + xlib + CACHE STRING "Presentation backend chosen at configure time" +) +set_property(CACHE PRESENTATION_BACKEND PROPERTY STRINGS ${PRESENTATION_BACKENDS}) list(FIND PRESENTATION_BACKENDS ${PRESENTATION_BACKEND} index) if(index EQUAL -1) - message(FATAL_ERROR "Presentation backend must be one of - ${PRESENTATION_BACKENDS}") + message(FATAL_ERROR "Presentation backend must be one of ${PRESENTATION_BACKENDS}") endif() message(STATUS "Using presentation backend: ${PRESENTATION_BACKEND}") +find_package(X11) -if( PRESENTATION_BACKEND MATCHES "xlib" ) - find_package(X11 REQUIRED) - if ((NOT X11_Xxf86vm_LIB) OR (NOT X11_Xrandr_LIB)) - message(FATAL_ERROR "OpenXR xlib backend requires Xxf86vm and Xrandr") +find_package(PkgConfig) + +if(PKG_CONFIG_FOUND) + pkg_search_module(XCB xcb) + + pkg_search_module(WAYLAND_CLIENT wayland-client) +endif() + +include(CMakeDependentOption) +cmake_dependent_option( + BUILD_WITH_XLIB_HEADERS "Build with support for X11/Xlib-related features." ON "X11_FOUND" OFF +) +cmake_dependent_option( + BUILD_WITH_XCB_HEADERS "Build with support for XCB-related features." ON "X11_FOUND AND XCB_FOUND" OFF +) +cmake_dependent_option( + BUILD_WITH_WAYLAND_HEADERS "Build with support for Wayland-related features." ON "WAYLAND_CLIENT_FOUND" + OFF +) + +message(STATUS "BUILD_WITH_XLIB_HEADERS: ${BUILD_WITH_XLIB_HEADERS}") +message(STATUS "BUILD_WITH_XCB_HEADERS: ${BUILD_WITH_XCB_HEADERS}") +message(STATUS "BUILD_WITH_WAYLAND_HEADERS: ${BUILD_WITH_WAYLAND_HEADERS}") + +if(PRESENTATION_BACKEND MATCHES "xlib") + if(NOT BUILD_WITH_XLIB_HEADERS) + message( + FATAL_ERROR + "xlib backend selected, but BUILD_WITH_XLIB_HEADERS either disabled or unavailable due to missing dependencies." + ) + endif() + if(BUILD_TESTS AND (NOT X11_Xxf86vm_LIB OR NOT X11_Xrandr_LIB)) + message(FATAL_ERROR "OpenXR tests using xlib backend requires Xxf86vm and Xrandr") endif() - add_definitions( -DSUPPORT_X ) - add_definitions( -DOS_LINUX_XLIB ) - set( XLIB_LIBRARIES - ${X11_LIBRARIES} - ${X11_Xxf86vm_LIB} - ${X11_Xrandr_LIB} ) - -elseif( PRESENTATION_BACKEND MATCHES "xcb" ) - find_package(PkgConfig REQUIRED) - # XCB + XCB GLX is limited to OpenGL 2.1 - # add_definitions( -DOS_LINUX_XCB ) - # XCB + Xlib GLX 1.3 - add_definitions( -DOS_LINUX_XCB_GLX ) - - pkg_search_module(X11 REQUIRED x11) - pkg_search_module(XCB REQUIRED xcb) + if(TARGET openxr-gfxwrapper) + target_compile_definitions(openxr-gfxwrapper PUBLIC OS_LINUX_XLIB) + target_link_libraries(openxr-gfxwrapper PRIVATE ${X11_X11_LIB} ${X11_Xxf86vm_LIB} ${X11_Xrandr_LIB}) + + if(TARGET OpenGL::OpenGL AND TARGET OpenGL::GLX) + # OpenGL::OpenGL already linked, we just need to add GLX. + target_link_libraries(openxr-gfxwrapper PUBLIC OpenGL::GLX) + else() + target_link_libraries(openxr-gfxwrapper PUBLIC ${OPENGL_LIBRARIES} ${OPENGL_glx_LIBRARY}) + endif() + endif() +elseif(PRESENTATION_BACKEND MATCHES "xcb") + if(NOT BUILD_WITH_XCB_HEADERS) + message( + FATAL_ERROR + "xcb backend selected, but BUILD_WITH_XCB_HEADERS either disabled or unavailable due to missing dependencies." + ) + endif() pkg_search_module(XCB_RANDR REQUIRED xcb-randr) pkg_search_module(XCB_KEYSYMS REQUIRED xcb-keysyms) pkg_search_module(XCB_GLX REQUIRED xcb-glx) pkg_search_module(XCB_DRI2 REQUIRED xcb-dri2) pkg_search_module(XCB_ICCCM REQUIRED xcb-icccm) - set( XCB_LIBRARIES - ${XCB_LIBRARIES} - ${XCB_KEYSYMS_LIBRARIES} - ${XCB_RANDR_LIBRARIES} - ${XCB_GLX_LIBRARIES} - ${XCB_DRI2_LIBRARIES} - ${X11_LIBRARIES} ) - -elseif( PRESENTATION_BACKEND MATCHES "wayland" ) - find_package(PkgConfig REQUIRED) - pkg_search_module(WAYLAND_CLIENT REQUIRED wayland-client) + if(TARGET openxr-gfxwrapper) + # XCB + XCB GLX is limited to OpenGL 2.1 + # target_compile_definitions(openxr-gfxwrapper PUBLIC OS_LINUX_XCB ) + # XCB + Xlib GLX 1.3 + target_compile_definitions(openxr-gfxwrapper PUBLIC OS_LINUX_XCB_GLX) + + target_link_libraries(openxr-gfxwrapper PRIVATE ${X11_X11_LIB} ${XCB_KEYSYMS_LIBRARIES} ${XCB_RANDR_LIBRARIES}) + endif() +elseif(PRESENTATION_BACKEND MATCHES "wayland") + if(NOT BUILD_WITH_WAYLAND_HEADERS) + message( + FATAL_ERROR + "wayland backend selected, but BUILD_WITH_WAYLAND_HEADERS either disabled or unavailable due to missing dependencies." + ) + endif() + pkg_search_module(WAYLAND_EGL REQUIRED wayland-egl) pkg_search_module(WAYLAND_SCANNER REQUIRED wayland-scanner) pkg_search_module(WAYLAND_PROTOCOLS REQUIRED wayland-protocols>=1.7) pkg_search_module(EGL REQUIRED egl) - add_definitions( -DOS_LINUX_WAYLAND ) - set( WAYLAND_LIBRARIES - ${EGL_LIBRARIES} - ${WAYLAND_CLIENT_LIBRARIES} - ${WAYLAND_EGL_LIBRARIES} ) - - # generate wayland protocols - set(WAYLAND_PROTOCOLS_DIR ${PROJECT_SOURCE_DIR}/wayland-protocols/) - file(MAKE_DIRECTORY ${WAYLAND_PROTOCOLS_DIR}) - - pkg_get_variable(WAYLAND_PROTOCOLS_DATADIR wayland-protocols pkgdatadir) - pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner) - - set(PROTOCOL xdg-shell-unstable-v6) - set(PROTOCOL_XML - ${WAYLAND_PROTOCOLS_DATADIR}/unstable/xdg-shell/${PROTOCOL}.xml) - - if( EXISTS ${PROTOCOL_XML} ) - execute_process(COMMAND - ${WAYLAND_SCANNER} - code - ${PROTOCOL_XML} - ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.c) - execute_process(COMMAND - ${WAYLAND_SCANNER} - client-header - ${PROTOCOL_XML} - ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.h) - - set( WAYLAND_PROTOCOL_SRC - ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.c - ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.h ) - - include_directories(${WAYLAND_PROTOCOLS_DIR}) - else() - message(FATAL_ERROR - "xdg-shell-unstable-v6.xml not found in " - ${WAYLAND_PROTOCOLS_DATADIR} - "\nYour wayland-protocols package does not " - "contain xdg-shell-unstable-v6.") + if(TARGET openxr-gfxwrapper) + # generate wayland protocols + set(WAYLAND_PROTOCOLS_DIR ${PROJECT_BINARY_DIR}/wayland-protocols/) + file(MAKE_DIRECTORY ${WAYLAND_PROTOCOLS_DIR}) + + pkg_get_variable(WAYLAND_PROTOCOLS_DATADIR wayland-protocols pkgdatadir) + pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner) + + set(PROTOCOL xdg-shell-unstable-v6) + set(PROTOCOL_XML ${WAYLAND_PROTOCOLS_DATADIR}/unstable/xdg-shell/${PROTOCOL}.xml) + + if(NOT EXISTS ${PROTOCOL_XML}) + message(FATAL_ERROR "xdg-shell-unstable-v6.xml not found in " ${WAYLAND_PROTOCOLS_DATADIR} + "\nYour wayland-protocols package does not " "contain xdg-shell-unstable-v6." + ) + endif() + add_custom_command( + OUTPUT ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.c + COMMAND ${WAYLAND_SCANNER} code ${PROTOCOL_XML} ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.c + VERBATIM + ) + add_custom_command( + OUTPUT ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.h + COMMAND ${WAYLAND_SCANNER} client-header ${PROTOCOL_XML} ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.h + VERBATIM + ) + + target_sources(openxr-gfxwrapper + PRIVATE + ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.c + ${WAYLAND_PROTOCOLS_DIR}/${PROTOCOL}.h + ) + + target_include_directories(openxr-gfxwrapper PUBLIC ${WAYLAND_PROTOCOLS_DIR}) + target_link_libraries( + openxr-gfxwrapper PRIVATE ${EGL_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} + ) + target_compile_definitions(openxr-gfxwrapper PUBLIC OS_LINUX_WAYLAND) + target_link_libraries(openxr-gfxwrapper PRIVATE ${EGL_LIBRARIES} ${WAYLAND_CLIENT_LIBRARIES}) endif() endif() diff --git a/src/loader/CMakeLists.txt b/src/loader/CMakeLists.txt index 1a91ef9b8..54b87fe1a 100644 --- a/src/loader/CMakeLists.txt +++ b/src/loader/CMakeLists.txt @@ -15,22 +15,8 @@ # Author: # -#set (CMAKE_VERBOSE_MAKEFILE 1) - include(GNUInstallDirs) -# Use this feature for Windows to automatically generate an exports file for the DLL. -# See https://blog.kitware.com/create-dlls-on-windows-without-declspec-using-new-cmake-export-all-feature/ -include(GenerateExportHeader) -set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS false) - - -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(FALLBACK_CONFIG_DIRS "/etc/xdg" CACHE STRING - "Search path to use when XDG_CONFIG_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant.") - set(FALLBACK_DATA_DIRS "/usr/local/share:/usr/share" CACHE STRING - "Search path to use when XDG_DATA_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant.") -endif() if(WIN32) set(openxr_loader_RESOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/loader.rc) endif() @@ -42,9 +28,7 @@ endif() # List of all files externally generated outside of the loader that the loader # needs to build with. -SET(LOADER_EXTERNAL_GEN_FILES - ${COMMON_GENERATED_OUTPUT} -) +set(LOADER_EXTERNAL_GEN_FILES ${COMMON_GENERATED_OUTPUT}) run_xr_xml_generate(loader_source_generator.py xr_generated_loader.hpp) run_xr_xml_generate(loader_source_generator.py xr_generated_loader.cpp) @@ -86,111 +70,135 @@ add_library(openxr_loader ${LIBRARY_TYPE} if(BUILD_WITH_SYSTEM_JSONCPP) target_link_libraries(openxr_loader PRIVATE JsonCpp::JsonCpp) else() - target_sources(openxr_loader PRIVATE + target_sources(openxr_loader + PRIVATE ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_reader.cpp ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_value.cpp - ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_writer.cpp) + ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/src/lib_json/json_writer.cpp + ) target_include_directories(openxr_loader PRIVATE - # For jsoncpp - ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/include) + ${PROJECT_SOURCE_DIR}/src/external/jsoncpp/include + ) endif() set_target_properties(openxr_loader PROPERTIES FOLDER ${LOADER_FOLDER}) -set_source_files_properties( - ${LOADER_EXTERNAL_GEN_FILES} - PROPERTIES GENERATED TRUE -) -add_dependencies(openxr_loader - generate_openxr_header - xr_global_generated_files -) -target_include_directories(openxr_loader - PRIVATE - ${PROJECT_SOURCE_DIR}/src/common +set_source_files_properties(${LOADER_EXTERNAL_GEN_FILES} PROPERTIES GENERATED TRUE) +add_dependencies(openxr_loader generate_openxr_header xr_global_generated_files) +target_include_directories( + openxr_loader + PRIVATE ${PROJECT_SOURCE_DIR}/src/common - # for OpenXR headers - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_BINARY_DIR}/include + # for OpenXR headers + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR}/include - # for generated dispatch table, common_config.h - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_BINARY_DIR}/.. + # for generated dispatch table, common_config.h + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_BINARY_DIR}/.. - # for target-specific generated files - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} + # for target-specific generated files + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} ) + if(VulkanHeaders_FOUND) - target_include_directories(openxr_loader - PRIVATE ${Vulkan_INCLUDE_DIRS} - ) + target_include_directories(openxr_loader PRIVATE ${Vulkan_INCLUDE_DIRS}) endif() if(NOT BUILD_LOADER_WITH_EXCEPTION_HANDLING) - target_compile_definitions(openxr_loader - PRIVATE XRLOADER_DISABLE_EXCEPTION_HANDLING - ) + target_compile_definitions(openxr_loader PRIVATE XRLOADER_DISABLE_EXCEPTION_HANDLING) endif() -target_compile_definitions(openxr_loader - PRIVATE API_NAME="OpenXR" +target_link_libraries( + openxr_loader + PRIVATE openxr-all-supported ${CMAKE_DL_LIBS} + PUBLIC ${CMAKE_THREAD_LIBS_INIT} ) + +target_compile_definitions(openxr_loader PRIVATE API_NAME="OpenXR") + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_compile_definitions(openxr_loader - PRIVATE FALLBACK_CONFIG_DIRS="${FALLBACK_CONFIG_DIRS}" - PRIVATE FALLBACK_DATA_DIRS="${FALLBACK_DATA_DIRS}" - PRIVATE SYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}" + set(FALLBACK_CONFIG_DIRS + "/etc/xdg" + CACHE + STRING + "Search path to use when XDG_CONFIG_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant." + ) + set(FALLBACK_DATA_DIRS + "/usr/local/share:/usr/share" + CACHE + STRING + "Search path to use when XDG_DATA_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant." + ) + target_compile_definitions( + openxr_loader + PRIVATE + FALLBACK_CONFIG_DIRS="${FALLBACK_CONFIG_DIRS}" + FALLBACK_DATA_DIRS="${FALLBACK_DATA_DIRS}" + SYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}" ) - if(NOT(CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc")) + if(NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc")) target_compile_definitions(openxr_loader PRIVATE EXTRASYSCONFDIR="/etc") endif() set_target_properties(openxr_loader PROPERTIES SOVERSION "${MAJOR}" VERSION "${MAJOR}.${MINOR}.${PATCH}") - target_link_libraries(openxr_loader PRIVATE stdc++fs PUBLIC dl pthread m) + target_link_libraries( + openxr_loader + PRIVATE stdc++fs + PUBLIC m + ) - add_custom_target(libopenxr_loader.so.${MAJOR}.${MINOR} ALL - COMMAND ${CMAKE_COMMAND} -E create_symlink libopenxr_loader.so.${MAJOR}.${MINOR}.${PATCH} libopenxr_loader.so.${MAJOR}.${MINOR}) + add_custom_target( + libopenxr_loader.so.${MAJOR}.${MINOR} ALL + COMMAND ${CMAKE_COMMAND} -E create_symlink libopenxr_loader.so.${MAJOR}.${MINOR}.${PATCH} + libopenxr_loader.so.${MAJOR}.${MINOR} + ) set(XR_API_VERSION "${MAJOR}.${MINOR}") - configure_file("openxr.pc.in" "openxr.pc" @ONLY) + set(EXTRA_LIBS ${CMAKE_THREAD_LIBS_INIT}) + configure_file(openxr.pc.in openxr.pc @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/openxr.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") elseif(WIN32) - # WindowsStore (UWP) apps must be compiled with dynamic CRT linkage (default) - if (NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - foreach(configuration in CMAKE_C_FLAGS_DEBUG - CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_RELWITHDEBINFO - CMAKE_CXX_FLAGS_DEBUG - CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_RELWITHDEBINFO) - # If building DLLs, force static CRT linkage - if(DYNAMIC_LOADER) - if (${configuration} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${configuration} "${${configuration}}") - endif() - else() # Otherwise for static libs, link the CRT dynamically - if (${configuration} MATCHES "/MT") - string(REGEX REPLACE "/MT" "/MD" ${configuration} "${${configuration}}") + if(MSVC) + # WindowsStore (UWP) apps must be compiled with dynamic CRT linkage (default) + if(NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + foreach(configuration in CMAKE_C_FLAGS_DEBUG + CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_RELWITHDEBINFO) + # If building DLLs, force static CRT linkage + if(DYNAMIC_LOADER) + if(${configuration} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${configuration} "${${configuration}}") + endif() + else() # Otherwise for static libs, link the CRT dynamically + if(${configuration} MATCHES "/MT") + string(REGEX REPLACE "/MT" "/MD" ${configuration} "${${configuration}}") + endif() endif() - endif() - endforeach() - endif() + endforeach() + endif() - target_compile_options(openxr_loader PRIVATE) - if(MSVC) target_compile_options(openxr_loader PRIVATE /wd6386) endif() - generate_export_header(openxr_loader) - # set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS false) # Need to copy DLL to client directories so clients can easily load it. - if( (DYNAMIC_LOADER) AND (CMAKE_GENERATOR MATCHES "^Visual Studio.*") ) - file( TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader.dll COPY_DLL_SRC_PATH ) - file( TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader.pdb COPY_PDB_SRC_PATH ) - file( TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../tests/hello_xr/$/ COPY_DST_HELLO_XR_PATH ) - file( TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../tests/loader_test/$/ COPY_DST_LOADER_TEST_PATH ) - file( TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../conformance/conformance_test/$/ COPY_DST_CONFORMANCE_TEST_PATH ) - add_custom_command( TARGET openxr_loader POST_BUILD + if(DYNAMIC_LOADER AND (CMAKE_GENERATOR MATCHES "^Visual Studio.*")) + file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader.dll COPY_DLL_SRC_PATH) + file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/$/openxr_loader.pdb COPY_PDB_SRC_PATH) + file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../tests/hello_xr/$/ + COPY_DST_HELLO_XR_PATH + ) + file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../tests/loader_test/$/ + COPY_DST_LOADER_TEST_PATH + ) + file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/../conformance/conformance_test/$/ + COPY_DST_CONFORMANCE_TEST_PATH + ) + add_custom_command( + TARGET openxr_loader POST_BUILD COMMAND xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_HELLO_XR_PATH} COMMAND xcopy /Y /I ${COPY_PDB_SRC_PATH} ${COPY_DST_HELLO_XR_PATH} COMMAND xcopy /Y /I ${COPY_DLL_SRC_PATH} ${COPY_DST_LOADER_TEST_PATH} @@ -202,19 +210,29 @@ elseif(WIN32) endif() if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") - target_compile_options(openxr_loader - PRIVATE -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wpointer-arith - PRIVATE -fno-strict-aliasing -fno-builtin-memcmp "$<$:-fno-rtti>" - -ffunction-sections -fdata-sections + target_compile_options( + openxr_loader + PRIVATE -Wall + -Wextra + -Wno-unused-parameter + -Wno-missing-field-initializers + -Wpointer-arith + -fno-strict-aliasing + -fno-builtin-memcmp + "$<$:-fno-rtti>" + -ffunction-sections + -fdata-sections ) # For GCC version 7.1 or greater, we need to disable the implicit fallthrough warning since # there's no consistent way to satisfy all compilers until they all accept the C++17 standard - if (CMAKE_COMPILER_IS_GNUCC AND NOT (CMAKE_CXX_COMPILER_VERSION LESS 7.1)) + if(CMAKE_COMPILER_IS_GNUCC AND NOT (CMAKE_CXX_COMPILER_VERSION LESS 7.1)) target_compile_options(openxr_loader PRIVATE -Wimplicit-fallthrough=0) endif() endif() -install(TARGETS openxr_loader +install( + TARGETS openxr_loader LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/src/loader/openxr.pc.in b/src/loader/openxr.pc.in index 5d658bca5..5d2775ae1 100644 --- a/src/loader/openxr.pc.in +++ b/src/loader/openxr.pc.in @@ -6,6 +6,6 @@ includedir=${prefix}/include Name: @CMAKE_PROJECT_NAME@ Description: OpenXR Loader Version: @XR_API_VERSION@ -Libs: -L${libdir} -lopenxr_loader @PRIVATE_LIBS@ +Libs: -L${libdir} -lopenxr_loader @EXTRA_LIBS@ Cflags: -I${includedir} diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 2bf47da55..33990a6f6 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -16,6 +16,10 @@ # add_subdirectory(list) +if(OPENGL_FOUND AND NOT TARGET openxr-gfxwrapper) + return() +endif() + add_subdirectory(hello_xr) if(BUILD_LOADER) add_subdirectory(loader_test) diff --git a/src/tests/hello_xr/CMakeLists.txt b/src/tests/hello_xr/CMakeLists.txt index 55aeff987..bd6e3dcbe 100644 --- a/src/tests/hello_xr/CMakeLists.txt +++ b/src/tests/hello_xr/CMakeLists.txt @@ -57,14 +57,11 @@ if(VulkanHeaders_INCLUDE_DIRS) ${VulkanHeaders_INCLUDE_DIRS} ) endif() -if(OPENGL_FOUND) - target_sources(hello_xr - PRIVATE - ${PROJECT_SOURCE_DIR}/src/common/gfxwrapper_opengl.c - ) -endif() target_link_libraries(hello_xr openxr_loader) +if(TARGET openxr-gfxwrapper) + target_link_libraries(hello_xr openxr-gfxwrapper) +endif() if(CMAKE_SYSTEM_NAME STREQUAL "Windows") if(MSVC) target_compile_definitions(hello_xr PRIVATE _CRT_SECURE_NO_WARNINGS) @@ -73,8 +70,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") target_link_libraries(hello_xr d3d11 d3dcompiler dxgi ${OPENGL_gl_LIBRARY}) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") target_compile_options(hello_xr PRIVATE -Wall) - target_link_libraries(hello_xr m pthread GL ${XLIB_LIBRARIES} ${XCB_LIBRARIES} ${WAYLAND_LIBRARIES}) - target_sources(hello_xr PRIVATE ${WAYLAND_PROTOCOL_SRC}) + target_link_libraries(hello_xr m pthread) endif() if(Vulkan_LIBRARY) diff --git a/src/tests/list/CMakeLists.txt b/src/tests/list/CMakeLists.txt index 610948428..d255b695a 100644 --- a/src/tests/list/CMakeLists.txt +++ b/src/tests/list/CMakeLists.txt @@ -40,10 +40,11 @@ endif() if(CMAKE_SYSTEM_NAME STREQUAL "Linux") target_compile_options(runtime_list PRIVATE -Wall) - target_link_libraries(runtime_list openxr_loader m pthread GL ${XLIB_LIBRARIES} ${XCB_LIBRARIES} ${WAYLAND_LIBRARIES}) + target_link_libraries(runtime_list openxr_loader pthread) endif() set_target_properties(runtime_list PROPERTIES FOLDER ${TESTS_FOLDER}) +set_target_properties(runtime_list PROPERTIES OUTPUT_NAME openxr_runtime_list) install(TARGETS runtime_list diff --git a/src/tests/loader_test/CMakeLists.txt b/src/tests/loader_test/CMakeLists.txt index 1a89a8951..33ab87569 100644 --- a/src/tests/loader_test/CMakeLists.txt +++ b/src/tests/loader_test/CMakeLists.txt @@ -18,16 +18,16 @@ add_executable(loader_test loader_test_utils.cpp loader_test.cpp - ${PROJECT_SOURCE_DIR}/src/common/gfxwrapper_opengl.c ${PROJECT_SOURCE_DIR}/src/common/filesystem_utils.cpp - ${WAYLAND_PROTOCOL_SRC} ) set_target_properties(loader_test PROPERTIES FOLDER ${TESTS_FOLDER}) -add_dependencies(loader_test - generate_openxr_header -) -target_include_directories(loader_test +add_dependencies(loader_test generate_openxr_header) +if(TARGET openxr-gfxwrapper) + target_link_libraries(loader_test openxr-gfxwrapper) +endif() +target_include_directories( + loader_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR} PRIVATE ${PROJECT_BINARY_DIR}/src PRIVATE ${PROJECT_BINARY_DIR}/include @@ -45,10 +45,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") target_compile_options(loader_test PRIVATE /Zc:wchar_t /Zc:forScope /W4 /WX) target_link_libraries(loader_test openxr_loader opengl32 d3d11) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_compile_options(loader_test PRIVATE -Wall -Wno-unused-function -Wno-format-truncation) - target_link_libraries(loader_test -lstdc++fs openxr_loader m -lpthread GL ${XLIB_LIBRARIES} ${XCB_LIBRARIES} ${WAYLAND_LIBRARIES}) + target_compile_options( + loader_test PRIVATE -Wall -Wno-unused-function -Wno-format-truncation + ) + + target_link_libraries(loader_test -lstdc++fs openxr_loader m -lpthread) else() - MESSAGE(FATAL_ERROR "Unsupported Platform") + message(FATAL_ERROR "Unsupported Platform") endif() file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/resources)