diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2023-12-08 19:24:34 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-08 19:24:34 +0800 |
| commit | 4321929879c1ed5b87ff95a99ca7da91e28d18fd (patch) | |
| tree | ae1460dcb652981468e6fa4897e87b697f2bda33 /cmake/SlangTarget.cmake | |
| parent | 9903688ccc0793259d43f95cae88bd1a8e178824 (diff) | |
WIP: CMake (#3326)
* More robust input and output selection in generator tools
* Add cmake build system
* Get slang-test running with cmake
* Bump lz4 and miniz dependencies
* Make cmake build more declarative
* Correct preprocessor logic in slang.h
* Add cuda test to compute/simple
* Remove empty cmake files
* output placement for cmake, and commenting
* Correct include paths in spirv-embed-generator
* Format cmake with gersemi
* Make cmake build clerer
* Neaten header generation
Also work around https://gitlab.kitware.com/cmake/cmake/-/issues/18399
by introducing correct_generated_properties to set the GENERATED flag in
the correct scope
* remove unused files
* use 3.20 to set GENERATOR property properly
* spelling
* more flexible linker arg setting
* replace slang-static with obj collection
* Set rpath and linker path correctly
* neaten generated file generation
* tests working with cmake build
* fix premake5 build
* comment and neaten cmake
* remove unnecessary dependency
* Build aftermath example only when aftermath is enabled
* Add slang-llvm and other dependencies
* Put modules alongside binaries
* Find slang-glslang correctly
* Better option handling
* comments
* add llvm build test
* Better option handling
* cmake wobble
* use UNICODE and _UNICODE
* remove other workflows
* use ccache
* neaten
* limit parallel for llvm build
* use ninja for build
* Windows and Darwin slang-llvm builds
* cache key
* verbose llvm build
* cl on windows
* sccache and cl.exe
* use cl.exe
* Correct package detection
* less verbosity
* Simplify miniz inclusion
* fix build with sccache
* Neaten llvm building
* neaten
* Neaten slang-llvm fetching
* more surgical workarounds
* Add ci action
* Get version from git
* better variable naming
* add missing include
* clean up after premake in cmake
* more docs on cmake build
* ci wobble
* add imgui target
* more selective source
* do not download swiftshader
* Some missing dependencies
* only build llvm on dispatch
* Disable /Zi in CI where sccache is present
* simplify
* set PIC for miniz
* set policies before project
* reengage workaround
* more runs on ci
* Add cmake presets
* Add cpack
* move iterator debug level to preset
* Correct lib flag
* simplify action
* Neaten cmake init
* Add todo
* Add simple test wrapper
* Add tests to workflow presets
* rename packing preset
* Correctly set definitions
* docs
* correct preset names
* Make slang-test depend on test-server/test-process
* neaten
* use workflow in actions
* install docs
* Correct module install dir
* debug dist workflow
* Install headers
* neaten header globbing
* Neaten dependency handling
* make lib and bin variables
* Do not set compiler for vs builds, unnecessary
* docs
* allow setting explicit source for target
* maintain archive subdir
* cmake docs
* install headers
* place targets into folders
* cmake docs
* nest external projects in folder
* remove name clash
* Neater external packages
* meta targets in folder structure
* cleaner slang-glslang dll
* Add missing static directive to slang-no-embedded-stdlib
* more robust module copying
* make slang-test the startup project
* folder tweak
* Make FETCH_BINARY the default on all platforms
* Set DEBUG_DIR
* add natvis files to source
* skip spirv tests
* remove test step from debug dist
* Add build to .gitignore
* redo warnings to be more like premake
* Update imgui
* clean more premake files
* Disable PCH for glslang, gcc throws a warning
* Add /MP for msvc builds
* warning wobble
* Add script to build llvm
* Add slang-llvm and generators components
* Build slang-llvm in ci
* comments
* fetch llvm with git
* better abi approximation for cache
* better sccache key
* formatting
* Correct logic around disabling problematic debug info for ccache
* exclude gcc and clang from windows ci
* Make dist workflows use system llvm
* naming
* restore normal dist builds
* formatting
* run tests in ci
* Correct slang-llvm url setting
* Rely on the system to find the test tool library
* actions matrix wiggle
* cope with OSX ancient bash
* Correct compilers on windows
* more ci debugging
* Correct rpath handling on OSX
* neaten
* correct path to slang-llvm
* Correct rpath separator on osx
* Find slang-llvm correctly
* smoke tests only on osx
* ci wobble
* Give MacOS module a dylib suffix
* get swiftshader correctly
* cope with bsd cp
* remove debug output
* full tests on osx
* ci wobble
* Add some vk tests to expected failures
* simplify ci
* ci wobble
* exclude dx12 tests from github ci
* remove cmake code for building llvm
* warnings
* warnings as errors for cl
* spirv-tools in path
* add aarch64 ci build
* Add SLANG_GENERATORS_PATH option for prebuilt generators
* neaten
* Correct generator target name
* remove yaml anchors because github actions does not support them
* Demote CMake in docs
Also add info on cross compiling
* Restore premake CI
* use minimal ci for cmake
* Write miniz_export for premake build
and .gitignore it
* Mention build config tool options in docs
* Remove redefined macro for miniz
* regenerate vs project
Diffstat (limited to 'cmake/SlangTarget.cmake')
| -rw-r--r-- | cmake/SlangTarget.cmake | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/cmake/SlangTarget.cmake b/cmake/SlangTarget.cmake new file mode 100644 index 000000000..44d6c945c --- /dev/null +++ b/cmake/SlangTarget.cmake @@ -0,0 +1,377 @@ +# +# A function to make target creation a little more declarative +# +# See the comments on the options below for usage +# +function(slang_add_target dir type) + set(no_value_args + # Don't include in the 'all' target + EXCLUDE_FROM_ALL + # This is loaded at runtime as a shared library + SHARED_LIBRARY_TOOL + # -Wextra + USE_EXTRA_WARNINGS + # don't set -Wall + USE_FEWER_WARNINGS + # Make this a Windows app, rather than a console app, only makes a + # difference when compiling for Windows + WIN32_EXECUTABLE + # Install this target for a non-component install + INSTALL + ) + set(single_value_args + # Set the target name, useful for multiple targets from the same + # directory. + # By default this is the name of the last directory component given + TARGET_NAME + # Set the output name, otherwise defaults to the target name + OUTPUT_NAME + # Set an explicit output directory relative to the cmake binary + # directory. otherwise defaults to the binary directory root. + # Outputs are always placed in a further subdirectory according to + # build config + OUTPUT_DIR + # If this is a shared library then the ${EXPORT_MACRO_PREFIX}_DYNAMIC and + # ${EXPORT_MACRO_PREFIX}_DYNAMIC_EXPORT macros are set for using and + # building respectively + EXPORT_MACRO_PREFIX + # The folder in which to place this target for IDE-based generators (VS + # and XCode) + FOLDER + # The working directory for debugging + DEBUG_DIR + # Install this target as part of a component + INSTALL_COMPONENT + ) + set(multi_value_args + # Use exactly these sources, instead of globbing from the directory + # argument + EXPLICIT_SOURCE + # Additional directories from which to glob source + EXTRA_SOURCE_DIRS + # Additional compile definitions + EXTRA_COMPILE_DEFINITIONS_PRIVATE + EXTRA_COMPILE_DEFINITIONS_PUBLIC + # Targets with which to link privately + LINK_WITH_PRIVATE + # Targets whose headers we use, but don't link with + INCLUDE_FROM_PRIVATE + # Any include directories other targets need to use this target + INCLUDE_DIRECTORIES_PUBLIC + # Add a dependency on the new target to the specified targets + REQUIRED_BY + # Add a dependency to the new target on the specified targets + REQUIRES + # Globs for any headers to install + PUBLIC_HEADERS + ) + cmake_parse_arguments( + ARG + "${no_value_args}" + "${single_value_args}" + "${multi_value_args}" + ${ARGN} + ) + + if(DEFINED ARG_UNPARSED_ARGUMENTS OR DEFINED ARG_KEYWORDS_MISSING_VALUES) + foreach(unparsed_arg ${ARG_UNPARSED_ARGUMENTS}) + message( + SEND_ERROR + "Unrecognized argument in slang_add_target: ${unparsed_arg}" + ) + endforeach() + foreach(bad_kwarg ${ARG_KEYWORDS_MISSING_VALUES}) + message( + SEND_ERROR + "Keyword argument missing values in slang_add_target: ${bad_kwarg}" + ) + endforeach() + return() + endif() + + # + # Set up some variables, including the target name + # + get_filename_component(dir_absolute ${dir} ABSOLUTE) + if(DEFINED ARG_TARGET_NAME) + set(target ${ARG_TARGET_NAME}) + else() + get_filename_component(target ${dir_absolute} NAME) + endif() + + # + # Find the source for this target + # + if(ARG_EXPLICIT_SOURCE) + list(APPEND source ${ARG_EXPLICIT_SOURCE}) + else() + slang_glob_sources(source ${dir}) + endif() + foreach(extra_dir ${ARG_EXTRA_SOURCE_DIRS}) + slang_glob_sources(source ${extra_dir}) + endforeach() + + # + # Create the target + # + set(library_types + STATIC + SHARED + OBJECT + MODULE + ALIAS + ) + if(type STREQUAL "EXECUTABLE") + add_executable(${target} ${source}) + elseif(type STREQUAL "LIBRARY") + add_library(${target} ${source}) + elseif(type IN_LIST library_types) + add_library(${target} ${type} ${source}) + else() + message( + SEND_ERROR + "Unsupported target type ${type} in slang_add_target" + ) + return() + endif() + + # + # Set the output directory + # + # We don't want the output directory to be sensitive to where + # slang_add_target is called from, so set it explicitly here. + # + if(DEFINED ARG_OUTPUT_DIR) + set(output_dir "${CMAKE_BINARY_DIR}/${ARG_OUTPUT_DIR}/$<CONFIG>") + else() + # Default to placing things in the cmake binary root. + # + # While it would be nice to place things according to their + # subdirectory, Windows' inflexibility in being able to find DLLs makes + # this tricky there. + set(output_dir "${CMAKE_BINARY_DIR}/$<CONFIG>") + endif() + set(archive_subdir ${library_subdir}) + if(type STREQUAL "MODULE") + set(library_subdir ${module_subdir}) + endif() + set_target_properties( + ${target} + PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${output_dir}/${archive_subdir}" + LIBRARY_OUTPUT_DIRECTORY "${output_dir}/${library_subdir}" + RUNTIME_OUTPUT_DIRECTORY "${output_dir}/${runtime_subdir}" + PDB_OUTPUT_DIRECTORY "${output_dir}/${runtime_subdir}" + ) + + # + # Set common compile options and properties + # + if(ARG_USE_EXTRA_WARNINGS) + set_default_compile_options(${target} USE_EXTRA_WARNINGS) + elseif(ARG_USE_FEWER_WARNINGS) + set_default_compile_options(${target} USE_FEWER_WARNINGS) + else() + set_default_compile_options(${target}) + endif() + + set_target_properties( + ${target} + PROPERTIES EXCLUDE_FROM_ALL ${ARG_EXCLUDE_FROM_ALL} + ) + + set_target_properties( + ${target} + PROPERTIES WIN32_EXECUTABLE ${ARG_WIN32_EXECUTABLE} + ) + + if(DEFINED ARG_OUTPUT_NAME) + set_target_properties( + ${target} + PROPERTIES OUTPUT_NAME ${ARG_OUTPUT_NAME} + ) + endif() + + if(DEFINED ARG_FOLDER) + set_target_properties(${target} PROPERTIES FOLDER ${ARG_FOLDER}) + endif() + + if(DEFINED ARG_DEBUG_DIR) + set_target_properties( + ${target} + PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ARG_DEBUG_DIR} + ) + endif() + + # + # Link and include from dependencies + # + target_link_libraries(${target} PRIVATE ${ARG_LINK_WITH_PRIVATE}) + + foreach(include_from ${ARG_INCLUDE_FROM_PRIVATE}) + target_include_directories( + ${target} + PRIVATE + $<TARGET_PROPERTY:${include_from},INTERFACE_INCLUDE_DIRECTORIES> + ) + endforeach() + + # + # Set our exported include directories + # + foreach(inc ${ARG_INCLUDE_DIRECTORIES_PUBLIC}) + get_filename_component(inc_abs ${inc} ABSOLUTE) + target_include_directories( + ${target} + PUBLIC "$<BUILD_INTERFACE:${inc_abs}>" + ) + endforeach() + + # + # Set up export macros + # + get_target_property(target_type ${target} TYPE) + if(DEFINED ARG_EXPORT_MACRO_PREFIX) + if( + target_type STREQUAL SHARED_LIBRARY + OR target_type STREQUAL MODULE_LIBRARY + ) + target_compile_definitions( + ${target} + PUBLIC "${ARG_EXPORT_MACRO_PREFIX}_DYNAMIC" + PRIVATE "${ARG_EXPORT_MACRO_PREFIX}_DYNAMIC_EXPORT" + ) + endif() + endif() + + # + # Other dependencies + # + foreach(requirer ${ARG_REQUIRED_BY}) + add_dependencies(${requirer} ${target}) + endforeach() + + if(DEFINED ARG_REQUIRES) + add_dependencies(${target} ${ARG_REQUIRES}) + endif() + + # + # Other preprocessor defines + # + if(ARG_EXTRA_COMPILE_DEFINITIONS_PRIVATE) + target_compile_definitions( + ${target} + PRIVATE ${ARG_EXTRA_COMPILE_DEFINITIONS_PRIVATE} + ) + endif() + if(ARG_EXTRA_COMPILE_DEFINITIONS_PUBLIC) + target_compile_definitions( + ${target} + PUBLIC ${ARG_EXTRA_COMPILE_DEFINITIONS_PUBLIC} + ) + endif() + + # + # Since we do a lot of dynamic loading, unconditionally set the build rpath + # to find our libraries. Ordinarily CMake would sort this out, but we do + # have libraries which at build time don't depend on any other shared + # libraries of ours but which do load them at runtime, hence the need to do + # this explicitly here. + # + if(CMAKE_SYSTEM_NAME MATCHES "Darwin") + set(ORIGIN "@loader_path") + else() + set(ORIGIN "$ORIGIN") + endif() + set_property( + TARGET ${target} + APPEND + PROPERTY BUILD_RPATH "${ORIGIN}/../${library_subdir}" + ) + set_property( + TARGET ${target} + APPEND + PROPERTY INSTALL_RPATH "${ORIGIN}/../${library_subdir}" + ) + + # On the same topic, give everything a dylib suffix on Mac OS + if(CMAKE_SYSTEM_NAME MATCHES "Darwin" AND type STREQUAL "MODULE") + set_property(TARGET ${target} PROPERTY SUFFIX ".dylib") + endif() + + # + # Mark headers for installation + # + if(ARG_PUBLIC_HEADERS) + if(NOT ARG_INSTALL) + message( + WARNING + "${target} was declared with PUBLIC_HEADERS but without INSTALL, the former will do nothing" + ) + endif() + + glob_append(public_headers ${ARG_PUBLIC_HEADERS}) + if(NOT public_headers) + message(WARNING "${target}'s PUBLIC_HEADER globs found no matches") + else() + set_target_properties( + ${target} + PROPERTIES PUBLIC_HEADER "${public_headers}" + ) + endif() + endif() + + # + # Mark for installation + # + if(ARG_INSTALL OR ARG_INSTALL_COMPONENT) + set(component_args) + if(ARG_INSTALL_COMPONENT) + set(component_args COMPONENT ${ARG_INSTALL_COMPONENT}) + endif() + set(exclude_arg) + if(NOT ARG_INSTALL) + set(exclude_arg EXCLUDE_FROM_ALL) + endif() + install( + TARGETS ${target} + EXPORT SlangTargets + ARCHIVE + DESTINATION ${archive_subdir} + ${component_args} + ${exclude_arg} + LIBRARY + DESTINATION ${library_subdir} + ${component_args} + ${exclude_arg} + RUNTIME + DESTINATION ${runtime_subdir} + ${component_args} + ${exclude_arg} + PUBLIC_HEADER + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ${component_args} + ${exclude_arg} + ) + endif() +endfunction() + +# Ideally we'd use CMAKE_INSTALL_LIBDIR and CMAKE_INSTALL_RUNTIMEDIR here, +# however some Slang functionality (specifically generating executables on +# Linux systems) relies on runtime libraries being at "$ORIGIN/../lib". This +# could be improved by setting at configure-time that path to be the relative +# path from CM_I_RD to CM_I_LD. +set(library_subdir lib) +set(runtime_subdir bin) + +# On Windows, because there's no RPATH, place modules in bin, next to the +# executables which load them (by deault, CMAKE will place them in lib and +# expect the application to seek them out there) +# +# This variable is used in the above function as and elsewhere for installing +# an imported module (slang-llvm from binary), hence why it's defined here. +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(module_subdir ${runtime_subdir}) +else() + set(module_subdir ${library_subdir}) +endif() |
