blob: 7c9b778ad907386a65bade94f37b36dd253d22e3 [file]
# ~~~
# Copyright (c) 2018 Valve Corporation
# Copyright (c) 2018 LunarG, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ~~~
if(APPLE)
option(APPLE_USE_SYSTEM_ICD "Use system Vulkan ICD discovery instead of bundling MoltenVK" OFF)
if(APPLE_USE_SYSTEM_ICD)
message(STATUS "Using system Vulkan loader for ICD discovery")
else()
set(MOLTENVK_REPO_ROOT "MOLTENVK-NOTFOUND" CACHE PATH "Absolute path to a MoltenVK repo directory")
if(NOT MOLTENVK_REPO_ROOT)
message(FATAL_ERROR "Must define location of MoltenVK repo -- see BUILD.md")
endif()
message(STATUS "Using MoltenVK repo location at ${MOLTENVK_REPO_ROOT}")
# Source for the MoltenVK ICD library and JSON file
set(MOLTENVK_DIR ${MOLTENVK_REPO_ROOT})
# MoltenVK JSON File
execute_process(COMMAND mkdir -p ${PROJECT_BINARY_DIR}/staging-json)
execute_process(COMMAND sed -e "/\"library_path\":/s$:[[:space:]]*\"[[:space:]]*[\\.\\/]*$: \"..\\/..\\/..\\/Frameworks\\/$"
${MOLTENVK_DIR}/MoltenVK/icd/MoltenVK_icd.json
OUTPUT_FILE ${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json)
# ~~~
# Modify the ICD JSON file to adjust the library path.
# The ICD JSON file goes in the Resources/vulkan/icd.d directory, so adjust the
# library_path to the relative path to the Frameworks directory in the bundle.
# The regex does: substitute ':<whitespace>"<whitespace><all occurences of . and />' with:
# ': "../../../Frameworks/'
# ~~~
add_custom_target(MoltenVK_icd-staging-json ALL
COMMAND mkdir -p ${PROJECT_BINARY_DIR}/staging-json
COMMAND sed -e "/\"library_path\":/s$:[[:space:]]*\"[[:space:]]*[\\.\\/]*$: \"..\\/..\\/..\\/Frameworks\\/$"
${MOLTENVK_DIR}/MoltenVK/icd/MoltenVK_icd.json > ${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json
VERBATIM
DEPENDS "${MOLTENVK_DIR}/MoltenVK/icd/MoltenVK_icd.json"
)
set_source_files_properties(${PROJECT_BINARY_DIR}/staging-json/MoltenVK_icd.json PROPERTIES GENERATED TRUE)
endif()
find_library(COCOA NAMES Cocoa)
# Locate Interface Builder Tool, needed to build things like Storyboards outside of Xcode.
if(NOT XCODE)
# Make sure we can find the 'ibtool' program. If we can NOT find it we skip generation of this project.
find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
if(${IBTOOL} STREQUAL "IBTOOL-NOTFOUND")
message(SEND_ERROR "ibtool can not be found and is needed to compile the .xib files. "
"It should have been installed with the Apple developer tools. "
"The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin.")
endif()
endif()
endif()
if(ANDROID OR APPLE)
set(WSI_DISPLAY_DEFAULT_SETTING "OFF")
else()
set(WSI_DISPLAY_DEFAULT_SETTING "ON")
endif()
option(BUILD_WSI_DISPLAY_SUPPORT "Build DISPLAY WSI support" ${WSI_DISPLAY_DEFAULT_SETTING})
if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
find_package(PkgConfig REQUIRED QUIET) # Use PkgConfig to find Linux system libraries
if(BUILD_WSI_XCB_SUPPORT)
pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb)
pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir)
message(DEBUG "XCB_INCLUDE_DIRS = ${XCB_INCLUDE_DIRS}")
endif()
if(BUILD_WSI_XLIB_SUPPORT)
pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11)
pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir)
message(DEBUG "XLIB_INCLUDE_DIRS = ${XLIB_INCLUDE_DIRS}")
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
pkg_check_modules(WAYLAND_CLIENT REQUIRED IMPORTED_TARGET wayland-client)
pkg_get_variable(WAYLAND_INCLUDE_DIRS wayland-client includedir)
pkg_check_modules(WAYLAND_SCANNER REQUIRED wayland-scanner)
pkg_get_variable(WAYLAND_SCANNER_EXECUTABLE wayland-scanner wayland_scanner)
message(DEBUG "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}")
pkg_get_variable(WAYLAND_CLIENT_PATH wayland-client pkgdatadir)
message(DEBUG "WAYLAND_CLIENT_PATH = ${WAYLAND_CLIENT_PATH}")
set(WAYLAND_CODE_PROTOCOL ${WAYLAND_CLIENT_PATH}/wayland.xml)
pkg_check_modules(WAYLAND_PROTOCOLS REQUIRED wayland-protocols)
pkg_get_variable(WAYLAND_PROTOCOLS_PATH wayland-protocols pkgdatadir)
message(DEBUG "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}")
set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml)
add_custom_command(COMMENT "Generating wayland client protocol dispatch data"
OUTPUT wayland-client.c
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
private-code
${WAYLAND_CODE_PROTOCOL}
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL}
DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
add_custom_command(COMMENT "Generating xdg-shell protocol dispatch data"
OUTPUT xdg-shell-code.c
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
private-code
${XDG_SHELL_PROTOCOL}
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
MAIN_DEPENDENCY ${XDG_SHELL_PROTOCOL}
DEPENDS ${XDG_SHELL_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
add_custom_command(COMMENT "Generating xdg-shell protocol header"
OUTPUT xdg-shell-client-header.h
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
client-header
${XDG_SHELL_PROTOCOL}
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
MAIN_DEPENDENCY ${XDG_SHELL_PROTOCOL}
DEPENDS ${XDG_SHELL_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
set(XDG_DECORATION_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
add_custom_command(COMMENT "Generating xdg-decoration protocol dispatch data"
OUTPUT xdg-decoration-code.c
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
private-code
${XDG_DECORATION_PROTOCOL}
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
MAIN_DEPENDENCY ${XDG_DECORATION_PROTOCOL}
DEPENDS ${XDG_DECORATION_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
add_custom_command(COMMENT "Generating xdg-decoration protocol header"
OUTPUT xdg-decoration-client-header.h
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
client-header
${XDG_DECORATION_PROTOCOL}
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
MAIN_DEPENDENCY ${XDG_DECORATION_PROTOCOL}
DEPENDS ${XDG_DECORATION_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
set(WAYLAND_ADDITIONAL_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h)
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
pkg_check_modules(DirectFB REQUIRED QUIET IMPORTED_TARGET directfb)
endif()
endif()
if(BUILD_WSI_DISPLAY_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DISPLAY_KHR)
endif()
if(WIN32)
add_definitions(-DWIN32_LEAN_AND_MEAN -DNOMINMAX)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WIN32_KHR)
elseif(ANDROID)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_ANDROID_KHR)
elseif(APPLE)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_METAL_EXT)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
if(BUILD_WSI_XCB_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XCB_KHR)
endif()
if(BUILD_WSI_XLIB_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XLIB_KHR)
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WAYLAND_KHR)
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DIRECTFB_EXT)
endif()
link_libraries(${API_LOWERCASE} m)
else()
message(FATAL_ERROR "Unsupported Platform!")
endif()
if(NOT DEFINED ENABLED_CUBE_PLATFORMS)
message(FATAL_ERROR "There are no supported WSI platforms on this system, vkcube requires a WSI platform be available to be able to render its output")
endif()
if (COMPILE_CUBE_SHADERS)
# Try to find glslang in system paths or in an SDK if the VULKAN_SDK env-var is set
find_program(GLSLANG_VALIDATOR names glslang glslangValidator HINTS $ENV{GLSLANG_INSTALL_DIR} $ENV{VULKAN_SDK}/bin $ENV{VULKAN_SDK}/Bin)
add_custom_command(COMMENT "Compiling cube vertex shader"
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/cube.vert.inc
COMMAND ${GLSLANG_VALIDATOR} -V -x -o ${CMAKE_CURRENT_SOURCE_DIR}/cube.vert.inc
${PROJECT_SOURCE_DIR}/cube/cube.vert
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/cube/cube.vert
DEPENDS ${PROJECT_SOURCE_DIR}/cube/cube.vert ${GLSLANG_VALIDATOR})
add_custom_command(COMMENT "Compiling cube fragment shader"
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/cube.frag.inc
COMMAND ${GLSLANG_VALIDATOR} -V -x -o ${CMAKE_CURRENT_SOURCE_DIR}/cube.frag.inc
${PROJECT_SOURCE_DIR}/cube/cube.frag
MAIN_DEPENDENCY ${PROJECT_SOURCE_DIR}/cube/cube.frag
DEPENDS ${PROJECT_SOURCE_DIR}/cube/cube.frag ${GLSLANG_VALIDATOR})
endif()
if(WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
# vkcube / vkcube make use of M_PI and various other math defines.
add_compile_definitions(_USE_MATH_DEFINES)
endif()
# On Ubuntu 20.04, it was found that the validation layers fail to launch in vkcube & vkcubepp due to
# a missing dependency on libpthread. While newer Ubuntu versions use a glibc version where libpthread
# is integrated into libc, older ubuntu's do not so we need to link threads directly in order for
# validation layers to be loadable.
if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
find_package(Threads REQUIRED)
endif()
# ----------------------------------------------------------------------------
# vkcube
if(APPLE)
add_subdirectory(macOS/cube)
elseif (ANDROID)
add_library(vkcube MODULE)
target_sources(vkcube PRIVATE cube.c)
add_subdirectory(android)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
add_executable(vkcube)
target_sources(vkcube PRIVATE
cube.c
${PROJECT_SOURCE_DIR}/cube/cube.vert
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc
)
target_link_libraries(vkcube Threads::Threads)
if(BUILD_WSI_XCB_SUPPORT)
target_sources(vkcube PRIVATE xcb_loader.h)
target_include_directories(vkcube PRIVATE ${xcb_INCLUDE_DIRS})
endif()
if(BUILD_WSI_XLIB_SUPPORT)
target_sources(vkcube PRIVATE xlib_loader.h)
target_include_directories(vkcube PRIVATE ${XLIB_INCLUDE_DIRS})
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
target_include_directories(vkcube PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
target_sources(vkcube PRIVATE PRIVATE ${WAYLAND_ADDITIONAL_SOURCES})
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
target_link_libraries(vkcube PkgConfig::DirectFB)
endif()
include(CheckLibraryExists)
CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT)
if (NEED_RT)
target_link_libraries(vkcube rt)
endif()
elseif(WIN32)
add_executable(vkcube WIN32)
target_sources(vkcube PRIVATE
cube.c
${PROJECT_SOURCE_DIR}/cube/cube.vert
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc
)
else()
message(FATAL_ERROR "Unsupported Platform!")
endif()
target_compile_definitions(vkcube PRIVATE ${ENABLED_CUBE_PLATFORMS})
target_include_directories(vkcube PRIVATE .)
target_link_libraries(vkcube ${CMAKE_DL_LIBS} Vulkan::Headers)
if (ANDROID)
install(TARGETS vkcube DESTINATION ${CMAKE_INSTALL_LIBDIR})
elseif(APPLE)
install(
TARGETS vkcube
# Install runtime dependencies like the Vulkan::Loader so the app is self-contained
RUNTIME_DEPENDENCIES DESTINATION "cube/vkcube.app/Contents/Frameworks/"
BUNDLE DESTINATION "cube"
)
set_target_properties(vkcube PROPERTIES
INSTALL_RPATH @executable_path/../Frameworks
)
else()
install(TARGETS vkcube)
endif()
if (ANDROID)
return()
endif()
# ----------------------------------------------------------------------------
# vkcubepp
if(APPLE)
add_subdirectory(macOS/cubepp)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
add_executable(vkcubepp
cube.cpp
${PROJECT_SOURCE_DIR}/cube/cube.vert
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc)
target_link_libraries(vkcubepp Threads::Threads)
if(BUILD_WSI_XCB_SUPPORT)
target_sources(vkcubepp PRIVATE xcb_loader.h)
target_include_directories(vkcubepp PRIVATE ${xcb_INCLUDE_DIRS})
endif()
if(BUILD_WSI_XLIB_SUPPORT)
target_sources(vkcubepp PRIVATE xlib_loader.h)
target_include_directories(vkcubepp PRIVATE ${XLIB_INCLUDE_DIRS})
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
target_include_directories(vkcubepp PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
target_sources(vkcubepp PRIVATE ${WAYLAND_ADDITIONAL_SOURCES})
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
target_link_libraries(vkcubepp PkgConfig::DirectFB)
endif()
else()
add_executable(vkcubepp
WIN32
cube.cpp
${PROJECT_SOURCE_DIR}/cube/cube.vert
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc)
endif()
target_include_directories(vkcubepp PRIVATE .)
target_compile_definitions(vkcubepp PRIVATE ${ENABLED_CUBE_PLATFORMS})
target_link_libraries(vkcubepp ${CMAKE_DL_LIBS} Vulkan::Headers)
if(APPLE)
install(
TARGETS vkcubepp
# Install runtime dependencies like the Vulkan::Loader so the app is self-contained
RUNTIME_DEPENDENCIES DESTINATION "cube/vkcubepp.app/Contents/Frameworks/"
BUNDLE DESTINATION "cube"
)
set_target_properties(vkcubepp PROPERTIES
INSTALL_RPATH @executable_path/../Frameworks
)
else()
install(TARGETS vkcubepp)
endif()