# bgfx.cmake - bgfx building in cmake # Written in 2017 by Joshua Brookover # # To the extent possible under law, the author(s) have dedicated all copyright # and related and neighboring rights to this software to the public domain # worldwide. This software is distributed without any warranty. # # You should have received a copy of the CC0 Public Domain Dedication along with # this software. If not, see . include(CMakeParseArguments) include(${CMAKE_CURRENT_LIST_DIR}/util/ConfigureDebugging.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../bgfxToolUtils.cmake) function(add_bgfx_shader FILE FOLDER) get_filename_component(FILENAME "${FILE}" NAME_WE) string(SUBSTRING "${FILENAME}" 0 2 TYPE) if("${TYPE}" STREQUAL "fs") set(TYPE "FRAGMENT") elseif("${TYPE}" STREQUAL "vs") set(TYPE "VERTEX") elseif("${TYPE}" STREQUAL "cs") set(TYPE "COMPUTE") else() set(TYPE "") endif() if(NOT "${TYPE}" STREQUAL "") set(COMMON FILE ${FILE} ${TYPE} INCLUDES ${BGFX_DIR}/src) set(OUTPUTS "") set(OUTPUTS_PRETTY "") set(OUTPUT_FILES "") set(COMMANDS "") if(WIN32) # dx11 set(DX11_OUTPUT ${BGFX_DIR}/examples/runtime/shaders/dx11/${FILENAME}.bin) if(NOT "${TYPE}" STREQUAL "COMPUTE") _bgfx_shaderc_parse( DX11 ${COMMON} WINDOWS PROFILE s_5_0 O 3 OUTPUT ${DX11_OUTPUT} ) else() _bgfx_shaderc_parse( DX11 ${COMMON} WINDOWS PROFILE s_5_0 O 1 OUTPUT ${DX11_OUTPUT} ) endif() list(APPEND OUTPUTS "DX11") set(OUTPUTS_PRETTY "${OUTPUTS_PRETTY}DX11, ") endif() if(APPLE) # metal set(METAL_OUTPUT ${BGFX_DIR}/examples/runtime/shaders/metal/${FILENAME}.bin) _bgfx_shaderc_parse(METAL ${COMMON} OSX PROFILE metal OUTPUT ${METAL_OUTPUT}) list(APPEND OUTPUTS "METAL") set(OUTPUTS_PRETTY "${OUTPUTS_PRETTY}Metal, ") endif() # essl if(NOT "${TYPE}" STREQUAL "COMPUTE") set(ESSL_OUTPUT ${BGFX_DIR}/examples/runtime/shaders/essl/${FILENAME}.bin) _bgfx_shaderc_parse(ESSL ${COMMON} ANDROID PROFILE 100_es OUTPUT ${ESSL_OUTPUT}) list(APPEND OUTPUTS "ESSL") set(OUTPUTS_PRETTY "${OUTPUTS_PRETTY}ESSL, ") endif() # glsl set(GLSL_OUTPUT ${BGFX_DIR}/examples/runtime/shaders/glsl/${FILENAME}.bin) if(NOT "${TYPE}" STREQUAL "COMPUTE") _bgfx_shaderc_parse(GLSL ${COMMON} LINUX PROFILE 140 OUTPUT ${GLSL_OUTPUT}) else() _bgfx_shaderc_parse(GLSL ${COMMON} LINUX PROFILE 430 OUTPUT ${GLSL_OUTPUT}) endif() list(APPEND OUTPUTS "GLSL") set(OUTPUTS_PRETTY "${OUTPUTS_PRETTY}GLSL, ") # spirv if(NOT "${TYPE}" STREQUAL "COMPUTE") set(SPIRV_OUTPUT ${BGFX_DIR}/examples/runtime/shaders/spirv/${FILENAME}.bin) _bgfx_shaderc_parse(SPIRV ${COMMON} LINUX PROFILE spirv OUTPUT ${SPIRV_OUTPUT}) list(APPEND OUTPUTS "SPIRV") set(OUTPUTS_PRETTY "${OUTPUTS_PRETTY}SPIRV, ") endif() # wgsl set(WGSL_OUTPUT ${BGFX_DIR}/examples/runtime/shaders/wgsl/${FILENAME}.bin) _bgfx_shaderc_parse(WGSL ${COMMON} LINUX PROFILE wgsl OUTPUT ${WGSL_OUTPUT}) list(APPEND OUTPUTS "WGSL") set(OUTPUTS_PRETTY "${OUTPUTS_PRETTY}WGSL") foreach(OUT ${OUTPUTS}) list(APPEND OUTPUT_FILES ${${OUT}_OUTPUT}) list(APPEND COMMANDS COMMAND "bgfx::shaderc" ${${OUT}}) get_filename_component(OUT_DIR ${${OUT}_OUTPUT} DIRECTORY) file(MAKE_DIRECTORY ${OUT_DIR}) endforeach() file(RELATIVE_PATH PRINT_NAME ${BGFX_DIR}/examples ${FILE}) add_custom_command( MAIN_DEPENDENCY ${FILE} OUTPUT ${OUTPUT_FILES} ${COMMANDS} COMMENT "Compiling shader ${PRINT_NAME} for ${OUTPUTS_PRETTY}" ) endif() endfunction() function(add_example ARG_NAME) # Parse arguments cmake_parse_arguments(ARG "COMMON" "" "DIRECTORIES;SOURCES" ${ARGN}) # Get all source files list(APPEND ARG_DIRECTORIES "${BGFX_DIR}/examples/${ARG_NAME}") set(SOURCES "") set(SHADERS "") foreach(DIR ${ARG_DIRECTORIES}) if(APPLE) file(GLOB GLOB_SOURCES ${DIR}/*.mm) list(APPEND SOURCES ${GLOB_SOURCES}) endif() file(GLOB GLOB_SOURCES ${DIR}/*.c ${DIR}/*.cpp ${DIR}/*.h ${DIR}/*.sc) list(APPEND SOURCES ${GLOB_SOURCES}) file(GLOB GLOB_SHADERS ${DIR}/*.sc) list(APPEND SHADERS ${GLOB_SHADERS}) endforeach() # Add target if(ARG_COMMON) add_library( example-${ARG_NAME} STATIC EXCLUDE_FROM_ALL ${SOURCES} ${DEAR_IMGUI_SOURCES} ${MESHOPTIMIZER_SOURCES} ) target_include_directories( example-${ARG_NAME} PUBLIC ${BGFX_DIR}/examples/common ${DEAR_IMGUI_INCLUDE_DIR} ${MESHOPTIMIZER_INCLUDE_DIR} ) target_link_libraries( example-${ARG_NAME} PUBLIC bgfx bx bimg bimg_decode ${DEAR_IMGUI_LIBRARIES} ${MESHOPTIMIZER_LIBRARIES} ) if(BGFX_WITH_WAYLAND) target_compile_definitions(example-${ARG_NAME} PUBLIC ENTRY_CONFIG_USE_WAYLAND=1) endif() if(BGFX_WITH_GLFW) find_package(glfw3 REQUIRED) target_link_libraries(example-${ARG_NAME} PUBLIC glfw) target_compile_definitions(example-${ARG_NAME} PUBLIC ENTRY_CONFIG_USE_GLFW=1) elseif(BGFX_WITH_SDL) find_package(SDL2 REQUIRED) target_link_libraries(example-${ARG_NAME} PUBLIC ${SDL2_LIBRARIES}) target_compile_definitions(example-${ARG_NAME} PUBLIC ENTRY_CONFIG_USE_SDL=1) elseif(UNIX AND NOT APPLE AND NOT ANDROID) target_link_libraries(example-${ARG_NAME} PUBLIC X11) endif() if(ANDROID) target_include_directories(example-${ARG_NAME} PRIVATE ${BGFX_DIR}/3rdparty/native_app_glue) target_link_libraries(example-${ARG_NAME} INTERFACE android EGL GLESv2) endif() if(BGFX_BUILD_EXAMPLES) if(IOS OR WIN32) # on iOS we need to build a bundle so have to copy the data rather than symlink # and on windows we can't create symlinks add_custom_command( TARGET example-${ARG_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${BGFX_DIR}/examples/runtime/ $ ) else() # For everything else symlink some folders into our output directory add_custom_command( TARGET example-${ARG_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink ${BGFX_DIR}/examples/runtime/font $/font ) add_custom_command( TARGET example-${ARG_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink ${BGFX_DIR}/examples/runtime/images $/images ) add_custom_command( TARGET example-${ARG_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink ${BGFX_DIR}/examples/runtime/meshes $/meshes ) add_custom_command( TARGET example-${ARG_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink ${BGFX_DIR}/examples/runtime/shaders $/shaders ) add_custom_command( TARGET example-${ARG_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink ${BGFX_DIR}/examples/runtime/text $/text ) add_custom_command( TARGET example-${ARG_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink ${BGFX_DIR}/examples/runtime/textures $/textures ) endif() endif() else() if(ANDROID) add_library(example-${ARG_NAME} SHARED ${SOURCES}) else() add_executable(example-${ARG_NAME} WIN32 ${SOURCES}) endif() if(NOT BGFX_INSTALL_EXAMPLES) set_property(TARGET example-${ARG_NAME} PROPERTY EXCLUDE_FROM_ALL ON) endif() target_link_libraries(example-${ARG_NAME} PUBLIC example-common) configure_debugging(example-${ARG_NAME} WORKING_DIR ${BGFX_DIR}/examples/runtime) if(MSVC) set_target_properties(example-${ARG_NAME} PROPERTIES LINK_FLAGS "/ENTRY:\"mainCRTStartup\"") endif() if(BGFX_CUSTOM_TARGETS) add_dependencies(examples example-${ARG_NAME}) endif() if(IOS) set_target_properties( example-${ARG_NAME} PROPERTIES MACOSX_BUNDLE ON MACOSX_BUNDLE_GUI_IDENTIFIER example-${ARG_NAME} MACOSX_BUNDLE_BUNDLE_VERSION 0 MACOSX_BUNDLE_SHORT_VERSION_STRING 0 XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer" ) endif() endif() target_compile_definitions( example-${ARG_NAME} PRIVATE "-D_CRT_SECURE_NO_WARNINGS" # "-D__STDC_FORMAT_MACROS" # "-DENTRY_CONFIG_IMPLEMENT_MAIN=1" # ) # Configure shaders if(NOT ARG_COMMON AND NOT IOS AND NOT EMSCRIPTEN AND NOT ANDROID ) foreach(SHADER ${SHADERS}) add_bgfx_shader(${SHADER} ${ARG_NAME}) endforeach() source_group("Shader Files" FILES ${SHADERS}) endif() if(NOT ARG_COMMON AND EMSCRIPTEN) set_target_properties( example-${ARG_NAME} PROPERTIES LINK_FLAGS "-s PRECISE_F32=1 -s TOTAL_MEMORY=268435456 -s ENVIRONMENT=web --memory-init-file 1 --emrun" SUFFIX ".html" ) endif() # Directory name set_target_properties(example-${ARG_NAME} PROPERTIES FOLDER "bgfx/examples") endfunction() # Build all examples target if(BGFX_CUSTOM_TARGETS) add_custom_target(examples) set_target_properties(examples PROPERTIES FOLDER "bgfx/examples") endif() # Add common library for examples if(BGFX_BUILD_EXAMPLE_COMMON) add_example( common COMMON DIRECTORIES ${BGFX_DIR}/examples/common/debugdraw ${BGFX_DIR}/examples/common/entry ${BGFX_DIR}/examples/common/font ${BGFX_DIR}/examples/common/imgui ${BGFX_DIR}/examples/common/nanovg ${BGFX_DIR}/examples/common/ps ) endif() # Only add examples if set, otherwise we still need exmaples common for tools if(BGFX_BUILD_EXAMPLES) # Add examples set(BGFX_EXAMPLES 00-helloworld 01-cubes 02-metaballs 03-raymarch 04-mesh 05-instancing 06-bump 07-callback 08-update 09-hdr 10-font 11-fontsdf 12-lod 13-stencil 14-shadowvolumes 15-shadowmaps-simple 16-shadowmaps 17-drawstress 18-ibl 19-oit 20-nanovg # 21-deferred 22-windows 23-vectordisplay 24-nbody 25-c99 26-occlusion 27-terrain 28-wireframe 29-debugdraw 30-picking 31-rsm 32-particles 33-pom 34-mvs 35-dynamic 36-sky # 37-gpudrivenrendering 38-bloom 39-assao 40-svt # 41-tess 42-bunnylod 43-denoise 44-sss 45-bokeh 46-fsr 47-pixelformats 48-drawindirect 49-hextile 50-headless 51-gpufont ) foreach(EXAMPLE ${BGFX_EXAMPLES}) add_example(${EXAMPLE}) endforeach() if(BGFX_INSTALL_EXAMPLES) install(DIRECTORY ${BGFX_DIR}/examples/runtime/ DESTINATION examples) foreach(EXAMPLE ${BGFX_EXAMPLES}) install(TARGETS example-${EXAMPLE} DESTINATION examples) endforeach() endif() endif()