diff --git a/.gitignore b/.gitignore index 029eb4e..8cad491 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,16 @@ source third_party/lib/libdawn.* third_party/lib/*.so third_party/lib/*.dylib +third_party/local/* + +# formatter files +.cmake-format.py + +# cmake build directories +out +build + +# clangd files +.cache +compile_commands.json + diff --git a/CMakeLists.txt b/CMakeLists.txt index 8629977..f857244 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,37 +3,44 @@ project(gpu) include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/webgpu.cmake") -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with LSP +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with + # LSP set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -option(USE_LOCAL_LIBS "Use local libraries instead of fetching from the internet" OFF) +option(USE_LOCAL_LIBS + "Use local libraries instead of fetching from the internet" OFF) # Ensure the build type is set if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build: Debug or Release" FORCE) + set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Choose the type of build: Debug or Release" FORCE) endif() option(FASTBUILD "Option to enable fast builds" OFF) if(FASTBUILD) - set(CMAKE_BUILD_TYPE None) # Avoid default flags of predefined build types - set(CMAKE_CXX_FLAGS "-O0") + set(CMAKE_BUILD_TYPE None) # Avoid default flags of predefined build types + set(CMAKE_CXX_FLAGS "-O0") endif() option(DEBUG "Option to enable debug flags" OFF) if(DEBUG) - set(CMAKE_BUILD_TYPE Debug) - set(CMAKE_CXX_FLAGS "-O0 -g") + set(CMAKE_BUILD_TYPE Debug) + set(CMAKE_CXX_FLAGS "-O0 -g") endif() if(WIN64) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWEBGPU_BACKEND_DAWN") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWEBGPU_BACKEND_DAWN") endif() include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/gpu.cmake") message(STATUS "CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}") -message(STATUS "Include directories for wgpu: ${CMAKE_CURRENT_SOURCE_DIR}/third_party/headers") +message( + STATUS + "Include directories for wgpu: ${CMAKE_CURRENT_SOURCE_DIR}/third_party/headers" +) add_library(gpud SHARED gpu.h) set_target_properties(gpud PROPERTIES LINKER_LANGUAGE CXX) diff --git a/cmake/example.cmake b/cmake/example.cmake index 7779a30..eba8e7c 100644 --- a/cmake/example.cmake +++ b/cmake/example.cmake @@ -1,4 +1,5 @@ -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with LSP +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # export compile_commands.json to use with + # LSP set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -9,37 +10,47 @@ get_filename_component(PROJECT_ROOT ${PROJECT_ROOT} DIRECTORY) set(FILEPATH_CURRENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}") set(FILEPATH_PROJECT_ROOT "${PROJECT_ROOT}/${FILENAME}") +# Include file finding utility script +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/find_gpu.cmake") + # Check if the file exists in the current directory -if(EXISTS ${FILEPATH_CURRENT_DIR}) - set(TARGET_FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -elseif(EXISTS ${FILEPATH_PROJECT_ROOT}) - set(TARGET_FILE_PATH ${PROJECT_ROOT}) -else() - message(FATAL_ERROR "File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../") +find_project_root(${CMAKE_CURRENT_SOURCE_DIR} ${FILENAME} + TARGET_FILE_PATH) +if("${TARGET_FILE_PATH}" STREQUAL "") + find_project_root(${FILEPATH_CURRENT_DIR} ${FILENAME} + TARGET_FILE_PATH) + if("${TARGET_FILE_PATH}" STREQUAL "") + message( + FATAL_ERROR + "File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../" + ) + endif() endif() # Ensure the build type is set if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build: Debug or Release" FORCE) + set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Choose the type of build: Debug or Release" FORCE) endif() # Define architecture and build type directories or file names if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH "x64") + set(ARCH "x64") else() - set(ARCH "x86") + set(ARCH "x86") endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(BUILD_TYPE "Debug") + set(BUILD_TYPE "Debug") else() - set(BUILD_TYPE "Release") + set(BUILD_TYPE "Release") endif() if(NOT TARGET gpu) - message(STATUS "GPU_LIB not found") - include("${TARGET_FILE_PATH}/cmake/webgpu.cmake") - include("${TARGET_FILE_PATH}/cmake/gpu.cmake") + message(STATUS "GPU_LIB not found") + include("${TARGET_FILE_PATH}/cmake/webgpu.cmake") + include("${TARGET_FILE_PATH}/cmake/gpu.cmake") endif() add_executable(${PROJECT_NAME} run.cpp) @@ -48,9 +59,10 @@ target_link_libraries(${PROJECT_NAME} PRIVATE wgpu) target_link_libraries(${PROJECT_NAME} PRIVATE webgpu) if(WIN32) -# Ensure DLL is copied if on Windows -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DLL_PATH} - $) -endif() \ No newline at end of file + # Ensure DLL is copied if on Windows + add_custom_command( + TARGET ${PROJECT_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL_PATH} + $) +endif() diff --git a/cmake/find_gpu.cmake b/cmake/find_gpu.cmake new file mode 100644 index 0000000..dccf7ee --- /dev/null +++ b/cmake/find_gpu.cmake @@ -0,0 +1,30 @@ +# file name to find +set(FILENAME "gpu.h") + +# Function to check for file existence up the directory hierarchy +function(find_project_root current_dir filename result_var) + set(found FALSE) # Flag to indicate if the file is found + set(current_check_dir "${current_dir}") # Start from the given directory + # using 1 is jsut to supress the cmane-format warning + foreach(i RANGE 0 2 1) + set(filepath "${current_check_dir}/${filename}") + + if(EXISTS "${filepath}") + set(${result_var} + "${current_check_dir}" + PARENT_SCOPE) + set(found TRUE) + break() + endif() + + # Move one level up + get_filename_component(current_check_dir "${current_check_dir}" + DIRECTORY) + endforeach() + + if(NOT found) + set(${result_var} + "" + PARENT_SCOPE) # Set to empty if not found + endif() +endfunction() diff --git a/cmake/gpu.cmake b/cmake/gpu.cmake index e257cbf..08db244 100644 --- a/cmake/gpu.cmake +++ b/cmake/gpu.cmake @@ -1,6 +1,3 @@ -# Specify the filename to search for -set(FILENAME "gpu.h") - get_filename_component(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) get_filename_component(PROJECT_ROOT ${PROJECT_ROOT} DIRECTORY) @@ -8,26 +5,32 @@ get_filename_component(PROJECT_ROOT ${PROJECT_ROOT} DIRECTORY) set(FILEPATH_CURRENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}") set(FILEPATH_PROJECT_ROOT "${PROJECT_ROOT}/${FILENAME}") +# Include file finding utility script +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/find_gpu.cmake") + # Check if the file exists in the current directory -if(EXISTS ${FILEPATH_CURRENT_DIR}) - set(TARGET_FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -elseif(EXISTS ${FILEPATH_PROJECT_ROOT}) - set(TARGET_FILE_PATH ${PROJECT_ROOT}) -else() - message(FATAL_ERROR "File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../") +find_project_root(${CMAKE_CURRENT_SOURCE_DIR} ${FILENAME} TARGET_FILE_PATH) +if("${TARGET_FILE_PATH}" STREQUAL "") + find_project_root(${FILEPATH_CURRENT_DIR} ${FILENAME} TARGET_FILE_PATH) + if("${TARGET_FILE_PATH}" STREQUAL "") + message( + FATAL_ERROR + "File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../" + ) + endif() endif() # Define architecture and build type directories or file names if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(ARCH "x64") + set(ARCH "x64") else() - set(ARCH "x86") + set(ARCH "x86") endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(BUILD_TYPE "Debug") + set(BUILD_TYPE "Debug") else() - set(BUILD_TYPE "Release") + set(BUILD_TYPE "Release") endif() add_library(webgpulib SHARED IMPORTED) @@ -38,22 +41,29 @@ add_dependencies(gpu webgpulib) target_include_directories(gpu INTERFACE ${TARGET_FILE_PATH}) # Add headers webgpu.h -target_include_directories(wgpu INTERFACE ${TARGET_FILE_PATH}/third_party/headers) -if(WIN32) - set(DLL_PATH "${TARGET_FILE_PATH}/third_party/lib/libdawn_${ARCH}_${BUILD_TYPE}.dll") - if(EXISTS ${DLL_PATH}) - file(COPY ${DLL_PATH} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - target_link_libraries(webgpulib INTERFACE ${DLL_PATH}) - else() - message(FATAL_ERROR "libdawn dll not found at: ${DLL_PATH}") -endif() -else() - find_library(LIBDAWN dawn REQUIRED PATHS "${TARGET_FILE_PATH}/third_party/lib") - if(LIBDAWN) - message(STATUS "Found libdawn: ${LIBDAWN}") - # Link against libdawn - target_link_libraries(webgpulib INTERFACE ${LIBDAWN}) - else() - message(FATAL_ERROR "libdawn not found") - endif() -endif() \ No newline at end of file +target_include_directories(wgpu + INTERFACE ${TARGET_FILE_PATH}/third_party/headers) +include(ExternalProject) + +set(DAWN_EXT_PREFIX "${TARGET_FILE_PATH}/third_party/local/dawn") + +ExternalProject_Add( + dawn_project + PREFIX ${DAWN_EXT_PREFIX} + GIT_REPOSITORY "https://dawn.googlesource.com/dawn" + GIT_TAG "main" + SOURCE_DIR "${DAWN_EXT_PREFIX}/source" + BINARY_DIR "${DAWN_EXT_PREFIX}/build" + INSTALL_DIR "${DAWN_EXT_PREFIX}/install" + GIT_SUBMODULES "" + # setting cmake args doesn't work and I don't know why + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -S ${DAWN_EXT_PREFIX}/source -B + ${DAWN_EXT_PREFIX}/build -DDAWN_FETCH_DEPENDENCIES=ON + -DDAWN_ENABLE_INSTALL=ON -DDAWN_BUILD_MONOLITHIC_LIBRARY=ON + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -G ${CMAKE_GENERATOR} + INSTALL_COMMAND ${CMAKE_COMMAND} --install . --prefix + ${DAWN_EXT_PREFIX}/install + LOG_INSTALL ON) +find_library(LIBDAWN dawn PATHS "${DAWN_EXT_PREFIX}/install/lib") +target_link_libraries(webgpulib INTERFACE ${LIBDAWN}) diff --git a/cmake/webgpu.cmake b/cmake/webgpu.cmake index 5a66cfc..3cefa4c 100644 --- a/cmake/webgpu.cmake +++ b/cmake/webgpu.cmake @@ -8,47 +8,54 @@ get_filename_component(PROJECT_ROOT ${PROJECT_ROOT} DIRECTORY) set(FILEPATH_CURRENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}") set(FILEPATH_PROJECT_ROOT "${PROJECT_ROOT}/${FILENAME}") +# Include file finding utility script +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/find_gpu.cmake") + # Check if the file exists in the current directory -if(EXISTS ${FILEPATH_CURRENT_DIR}) - set(TARGET_FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -elseif(EXISTS ${FILEPATH_PROJECT_ROOT}) - set(TARGET_FILE_PATH ${PROJECT_ROOT}) -else() - message(FATAL_ERROR "File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../") +find_project_root(${CMAKE_CURRENT_SOURCE_DIR} ${FILENAME} TARGET_FILE_PATH) +if("${TARGET_FILE_PATH}" STREQUAL "") + find_project_root(${FILEPATH_CURRENT_DIR} ${FILENAME} TARGET_FILE_PATH) + if("${TARGET_FILE_PATH}" STREQUAL "") + message( + FATAL_ERROR + "File ${FILENAME} not found in either ${CMAKE_CURRENT_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR}/../../" + ) + endif() endif() include(FetchContent) set(FETCHCONTENT_BASE_DIR "${TARGET_FILE_PATH}/third_party/fetchcontent") -set(WEBGPU_DIST_LOCAL_PATH "${TARGET_FILE_PATH}/third_party/local/WebGPU-distribution") +set(WEBGPU_DIST_LOCAL_PATH + "${TARGET_FILE_PATH}/third_party/local/WebGPU-distribution") if(USE_LOCAL_LIBS) - set(WEBGPU_DIST_GIT_REPO ${WEBGPU_DIST_LOCAL_PATH}) - message(STATUS "Using local WebGPU distribution: ${WEBGPU_DIST_LOCAL_PATH}") + set(WEBGPU_DIST_GIT_REPO ${WEBGPU_DIST_LOCAL_PATH}) + message(STATUS "Using local WebGPU distribution: ${WEBGPU_DIST_LOCAL_PATH}") else() - set(WEBGPU_DIST_GIT_REPO "https://github.com/eliemichel/WebGPU-distribution") + set(WEBGPU_DIST_GIT_REPO + "https://github.com/eliemichel/WebGPU-distribution") endif() option(WEBGPU_TAG "WebGPU distribution tag to use") -if (NOT WEBGPU_TAG) - set(WEBGPU_TAG "dawn") +if(NOT WEBGPU_TAG) + set(WEBGPU_TAG "dawn") endif() message(STATUS "Using WebGPU distribution tag: ${WEBGPU_TAG}") -if (WEBGPU_TAG STREQUAL "dawn") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWEBGPU_BACKEND_DAWN") - # use specific commit - # set(WEBGPU_TAG "1025b977e1927b6d0327e67352f90feb4bcf8274") - # set(WEBGPU_TAG "acf972b7b909f52e183bdae3971b93bb13d4a29e") - # add_compile_options(-UABSL_INTERNAL_AT_LEAST_CXX20) - # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -UABSL_INTERNAL_AT_LEAST_CXX20") - message(STATUS "Using Dawn backend") +if(WEBGPU_TAG STREQUAL "dawn") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWEBGPU_BACKEND_DAWN") + # use specific commit set(WEBGPU_TAG + # "1025b977e1927b6d0327e67352f90feb4bcf8274") set(WEBGPU_TAG + # "acf972b7b909f52e183bdae3971b93bb13d4a29e") + # add_compile_options(-UABSL_INTERNAL_AT_LEAST_CXX20) set(CMAKE_CXX_FLAGS + # "${CMAKE_CXX_FLAGS} -UABSL_INTERNAL_AT_LEAST_CXX20") + message(STATUS "Using Dawn backend") endif() FetchContent_Declare( - webgpu - GIT_REPOSITORY ${WEBGPU_DIST_GIT_REPO} - GIT_TAG ${WEBGPU_TAG} - GIT_SHALLOW TRUE -) -FetchContent_MakeAvailable(webgpu) \ No newline at end of file + webgpu + GIT_REPOSITORY ${WEBGPU_DIST_GIT_REPO} + GIT_TAG ${WEBGPU_TAG} + GIT_SHALLOW TRUE) +FetchContent_MakeAvailable(webgpu)