1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 02:08:27 +08:00

Merge topic 'ispc_lang_support'

5ece12b7e4 gitlab-ci: add ISPC to the Fedora CI image
8976817d6d ISPC: Update help documentation to include ISPC
2368f46ba4 ISPC: Support building with the MSVC toolchain
e783bf8aa6 ISPC: Support ISPC header generation byproducts and parallel builds
34cc6acc81 Add ISPC compiler support to CMake
419d70d490 Refactor some swift only logic to be re-used by other languages

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5065
This commit is contained in:
Brad King
2020-09-01 13:15:29 +00:00
committed by Kitware Robot
67 changed files with 1042 additions and 40 deletions

View File

@@ -1,4 +1,5 @@
set(BUILD_CursesDialog ON CACHE BOOL "")
set(BUILD_QtDialog ON CACHE BOOL "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")

View File

@@ -1 +1,2 @@
set(CMake_TEST_ISPC "ON" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")

View File

@@ -1 +1,2 @@
set(CMake_TEST_ISPC "ON" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora31_common.cmake")

View File

@@ -1 +1,2 @@
set(CMake_TEST_ISPC "ON" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")

View File

@@ -3,3 +3,6 @@ MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
COPY install_deps.sh /root/install_deps.sh
RUN sh /root/install_deps.sh
COPY install_ispc.sh /root/install_ispc.sh
RUN sh /root/install_ispc.sh

View File

@@ -0,0 +1,14 @@
#!/bin/sh
set -e
readonly version="1.13.0"
readonly sha256sum="8ab1189bd5db596b3eee9d9465d3528b6626a7250675d67102761bb0d284cd21"
readonly filename="ispc-v$version-linux"
readonly tarball="$filename.tar.gz"
echo "$sha256sum $tarball" > ispc.sha256sum
curl -OL "https://github.com/ispc/ispc/releases/download/v$version/$tarball"
sha256sum --check ispc.sha256sum
tar --strip-components=1 -C /usr/local -xf "$tarball" "$filename/bin/ispc"

View File

@@ -30,7 +30,7 @@
### Fedora
.fedora31:
image: "kitware/cmake:ci-fedora31-x86_64-2020-06-01"
image: "kitware/cmake:ci-fedora31-x86_64-2020-08-18"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"

View File

@@ -1048,6 +1048,7 @@ syn keyword cmakeVariable contained
\ CMAKE_HOST_UNIX
\ CMAKE_HOST_WIN32
\ CMAKE_IGNORE_PATH
\ CMAKE_ISPC_HEADER_DIRECTORY
\ CMAKE_IMPORT_LIBRARY_PREFIX
\ CMAKE_IMPORT_LIBRARY_SUFFIX
\ CMAKE_INCLUDE_CURRENT_DIR

View File

@@ -9,7 +9,8 @@ Enable a language (CXX/C/OBJC/OBJCXX/Fortran/etc)
Enables support for the named language in CMake. This is
the same as the :command:`project` command but does not create any of the extra
variables that are created by the project command. Example languages
are ``CXX``, ``C``, ``CUDA``, ``OBJC``, ``OBJCXX``, ``Fortran``, and ``ASM``.
are ``CXX``, ``C``, ``CUDA``, ``OBJC``, ``OBJCXX``, ``Fortran``,
``ISPC``, and ``ASM``.
If enabling ``ASM``, enable it last so that CMake can check whether
compilers for other languages like ``C`` work for assembly too.

View File

@@ -88,7 +88,7 @@ The options are:
Selects which programming languages are needed to build the project.
Supported languages include ``C``, ``CXX`` (i.e. C++), ``CUDA``,
``OBJC`` (i.e. Objective-C), ``OBJCXX``, ``Fortran``, and ``ASM``.
``OBJC`` (i.e. Objective-C), ``OBJCXX``, ``Fortran``, ``ISPC``, and ``ASM``.
By default ``C`` and ``CXX`` are enabled if no language options are given.
Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
to skip enabling any languages.

13
Help/envvar/ISPC.rst Normal file
View File

@@ -0,0 +1,13 @@
ISPC
-------
.. versionadded:: 3.19
.. include:: ENV_VAR.txt
Preferred executable for compiling ``ISPC`` language files. Will only be used by
CMake on the first configuration to determine ``ISPC`` compiler, after which the
value for ``ISPC`` is stored in the cache as
:variable:`CMAKE_ISPC_COMPILER <CMAKE_<LANG>_COMPILER>`. For any configuration
run (including the first), the environment variable will be ignored if the
:variable:`CMAKE_ISPC_COMPILER <CMAKE_<LANG>_COMPILER>` variable is defined.

15
Help/envvar/ISPCFLAGS.rst Normal file
View File

@@ -0,0 +1,15 @@
ISPCFLAGS
---------
.. versionadded:: 3.19
.. include:: ENV_VAR.txt
Default compilation flags to be used when compiling ``ISPC`` files. Will only be
used by CMake on the first configuration to determine ``ISPC`` default
compilation flags, after which the value for ``ISPCFLAGS`` is stored in the
cache as :variable:`CMAKE_ISPC_FLAGS <CMAKE_<LANG>_FLAGS>`. For any configuration
run (including the first), the environment variable will be ignored if
the :variable:`CMAKE_ISPC_FLAGS <CMAKE_<LANG>_FLAGS>` variable is defined.
See also :variable:`CMAKE_ISPC_FLAGS_INIT <CMAKE_<LANG>_FLAGS_INIT>`.

View File

@@ -63,6 +63,8 @@ Environment Variables for Languages
/envvar/CXXFLAGS
/envvar/FC
/envvar/FFLAGS
/envvar/ISPC
/envvar/ISPCFLAGS
/envvar/OBJC
/envvar/OBJCXX
/envvar/RC

View File

@@ -146,6 +146,11 @@ Variable Queries
``1`` if the CMake's compiler id of the Fortran compiler matches any one
of the entries in ``compiler_ids``, otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<ISPC_COMPILER_ID:compiler_ids>``
where ``compiler_ids`` is a comma-separated list.
``1`` if the CMake's compiler id of the ISPC compiler matches any one
of the entries in ``compiler_ids``, otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<C_COMPILER_VERSION:version>``
``1`` if the version of the C compiler matches ``version``, otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
@@ -164,6 +169,9 @@ Variable Queries
``$<Fortran_COMPILER_VERSION:version>``
``1`` if the version of the Fortran compiler matches ``version``, otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<ISPC_COMPILER_VERSION:version>``
``1`` if the version of the ISPC compiler matches ``version``, otherwise ``0``.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<TARGET_POLICY:policy>``
``1`` if the ``policy`` was NEW when the 'head' target was created,
else ``0``. If the ``policy`` was not set, the warning message for the policy
@@ -543,6 +551,9 @@ Variable Queries
``$<Fortran_COMPILER_ID>``
The CMake's compiler id of the Fortran compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<ISPC_COMPILER_ID>``
The CMake's compiler id of the ISPC compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
``$<C_COMPILER_VERSION>``
The version of the C compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
@@ -561,6 +572,9 @@ Variable Queries
``$<Fortran_COMPILER_VERSION>``
The version of the Fortran compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<ISPC_COMPILER_VERSION>``
The version of the ISPC compiler used.
See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
``$<COMPILE_LANGUAGE>``
The compile language of source files when evaluating compile options.
See :ref:`the related boolean expression

View File

@@ -258,6 +258,7 @@ Properties on Targets
/prop_tgt/INTERPROCEDURAL_OPTIMIZATION_CONFIG
/prop_tgt/INTERPROCEDURAL_OPTIMIZATION
/prop_tgt/IOS_INSTALL_COMBINED
/prop_tgt/ISPC_HEADER_DIRECTORY
/prop_tgt/JOB_POOL_COMPILE
/prop_tgt/JOB_POOL_LINK
/prop_tgt/JOB_POOL_PRECOMPILE_HEADER

View File

@@ -510,6 +510,7 @@ Variables for Languages
/variable/CMAKE_Fortran_MODDIR_DEFAULT
/variable/CMAKE_Fortran_MODDIR_FLAG
/variable/CMAKE_Fortran_MODOUT_FLAG
/variable/CMAKE_ISPC_HEADER_DIRECTORY
/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_MACHINE
/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_PREFIX
/variable/CMAKE_LANG_ANDROID_TOOLCHAIN_SUFFIX

View File

@@ -6,6 +6,6 @@ What programming language is the file.
A property that can be set to indicate what programming language the
source file is. If it is not set the language is determined based on
the file extension. Typical values are ``CXX`` (i.e. C++), ``C``,
``CSharp``, ``CUDA``, ``Fortran``, and ``ASM``. Setting this
``CSharp``, ``CUDA``, ``Fortran``, ``ISPC``, and ``ASM``. Setting this
property for a file means this file will be compiled. Do not set this
for headers or files that should not be compiled.

View File

@@ -0,0 +1,13 @@
ISPC_HEADER_DIRECTORY
---------------------
.. versionadded:: 3.19
Specify relative output directory for ISPC headers provided by the target.
If the target contains ISPC source files, this specifies the directory in which
the generated headers will be placed. Relative paths are treated with respect to
the value of :variable:`CMAKE_CURRENT_BINARY_DIR`. When this property is not set, the
headers will be placed a generator defined build directory. If the variable
:variable:`CMAKE_ISPC_HEADER_DIRECTORY` is set when a target is created
its value is used to initialize this property.

View File

@@ -0,0 +1,11 @@
cmake-ispc-support
------------------
* CMake learned to support ``ISPC`` as a first-class language that can be
enabled via the :command:`project` and :command:`enable_language` commands.
* ``ISPC`` is currently supported by the :ref:`Makefile Generators`
and the :generator:`Ninja` generator on Linux, macOS, and Windows.
* The Intel ISPC compiler (``ispc``) is supported.

View File

@@ -0,0 +1,10 @@
CMAKE_ISPC_HEADER_DIRECTORY
----------------------------
.. versionadded:: 3.19
ISPC generated header output directory.
This variable is used to initialize the :prop_tgt:`ISPC_HEADER_DIRECTORY`
property on all the targets. See the target property for additional
information.

View File

@@ -13,7 +13,8 @@ endfunction()
function(compiler_id_detection outvar lang)
if (NOT lang STREQUAL Fortran AND NOT lang STREQUAL CSharp)
if (NOT lang STREQUAL Fortran AND NOT lang STREQUAL CSharp
AND NOT lang STREQUAL ISPC)
file(GLOB lang_files
"${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake")
set(nonlang CXX)

View File

@@ -110,6 +110,28 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
endif()
endif()
# For ISPC we need to explicitly query the version.
if(lang STREQUAL "ISPC"
AND CMAKE_${lang}_COMPILER
AND NOT CMAKE_${lang}_COMPILER_VERSION)
execute_process(
COMMAND "${CMAKE_${lang}_COMPILER}"
--version
OUTPUT_VARIABLE output ERROR_VARIABLE output
RESULT_VARIABLE result
TIMEOUT 10
)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n"
"${output}\n"
)
if(output MATCHES [[ISPC\), ([0-9]+\.[0-9]+(\.[0-9]+)?)]])
set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}")
endif()
endif()
if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
execute_process(
COMMAND "${CMAKE_${lang}_COMPILER}"

View File

@@ -0,0 +1,96 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# determine the compiler to use for ISPC programs
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
if( NOT (("${CMAKE_GENERATOR}" MATCHES "Make") OR ("${CMAKE_GENERATOR}" MATCHES "Ninja")) )
message(FATAL_ERROR "ISPC language not currently supported by \"${CMAKE_GENERATOR}\" generator")
endif()
# Load system-specific compiler preferences for this language.
include(Platform/${CMAKE_SYSTEM_NAME}-Determine-ISPC OPTIONAL)
include(Platform/${CMAKE_SYSTEM_NAME}-ISPC OPTIONAL)
if(NOT CMAKE_ISPC_COMPILER_NAMES)
set(CMAKE_ISPC_COMPILER_NAMES ispc)
endif()
if(NOT CMAKE_ISPC_COMPILER)
set(CMAKE_ISPC_COMPILER_INIT NOTFOUND)
# prefer the environment variable CC
if(NOT $ENV{ISPC} STREQUAL "")
get_filename_component(CMAKE_ISPC_COMPILER_INIT $ENV{ISPC} PROGRAM PROGRAM_ARGS CMAKE_ISPC_FLAGS_ENV_INIT)
if(CMAKE_ISPC_FLAGS_ENV_INIT)
set(CMAKE_ISPC_COMPILER_ARG1 "${CMAKE_ISPC_FLAGS_ENV_INIT}" CACHE STRING "First argument to ISPC compiler")
endif()
if(NOT EXISTS ${CMAKE_ISPC_COMPILER_INIT})
message(FATAL_ERROR "Could not find compiler set in environment variable ISPC:\n$ENV{ISPC}.")
endif()
endif()
# next try prefer the compiler specified by the generator
if(CMAKE_GENERATOR_ISPC)
if(NOT CMAKE_ISPC_COMPILER_INIT)
set(CMAKE_ISPC_COMPILER_INIT ${CMAKE_GENERATOR_ISPC})
endif()
endif()
# finally list compilers to try
if(NOT CMAKE_ISPC_COMPILER_INIT)
set(CMAKE_ISPC_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}ispc ispc)
endif()
# Find the compiler.
_cmake_find_compiler(ISPC)
else()
_cmake_find_compiler_path(ISPC)
endif()
mark_as_advanced(CMAKE_ISPC_COMPILER)
if(NOT CMAKE_ISPC_COMPILER_ID_RUN)
set(CMAKE_ISPC_COMPILER_ID_RUN 1)
# Try to identify the compiler.
set(CMAKE_ISPC_COMPILER_ID)
set(CMAKE_ISPC_PLATFORM_ID)
set(CMAKE_ISPC_COMPILER_ID_TEST_FLAGS_FIRST
# setup logic to make sure ISPC outputs a file
"-o cmake_ispc_output"
)
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(ISPC ISPCFLAGS CMakeISPCCompilerId.ispc)
_cmake_find_compiler_sysroot(ISPC)
endif()
if (NOT _CMAKE_TOOLCHAIN_LOCATION)
get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_ISPC_COMPILER}" PATH)
endif ()
set(_CMAKE_PROCESSING_LANGUAGE "ISPC")
include(CMakeFindBinUtils)
include(Compiler/${CMAKE_ISPC_COMPILER_ID}-FindBinUtils OPTIONAL)
unset(_CMAKE_PROCESSING_LANGUAGE)
if(CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH)
set(_SET_CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH
"set(CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH [==[${CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH}]==])")
else()
set(_SET_CMAKE_ISPC_COMPILER_ID_VENDOR_MATCH "")
endif()
# configure variables set in this file for fast reload later on
configure_file(${CMAKE_ROOT}/Modules/CMakeISPCCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeISPCCompiler.cmake @ONLY)
set(CMAKE_ISPC_COMPILER_ENV_VAR "ISPC")

View File

@@ -66,6 +66,7 @@ if(("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND
OR "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xMSVC"
OR (CMAKE_HOST_WIN32 AND "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xPGI")
OR (CMAKE_HOST_WIN32 AND "x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xNVIDIA")
OR (CMAKE_HOST_WIN32 AND "x${_CMAKE_PROCESSING_LANGUAGE}" STREQUAL "xISPC")
OR (CMAKE_GENERATOR MATCHES "Visual Studio"
AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android"))

View File

@@ -0,0 +1,30 @@
set(CMAKE_ISPC_COMPILER "@CMAKE_ISPC_COMPILER@")
set(CMAKE_ISPC_COMPILER_ARG1 "@CMAKE_ISPC_COMPILER_ARG1@")
set(CMAKE_ISPC_COMPILER_ID "@CMAKE_ISPC_COMPILER_ID@")
set(CMAKE_ISPC_COMPILER_VERSION "@CMAKE_ISPC_COMPILER_VERSION@")
set(CMAKE_ISPC_COMPILER_VERSION_INTERNAL "@CMAKE_ISPC_COMPILER_VERSION_INTERNAL@")
set(CMAKE_ISPC_PLATFORM_ID "@CMAKE_ISPC_PLATFORM_ID@")
set(CMAKE_ISPC_SIMULATE_ID "@CMAKE_ISPC_SIMULATE_ID@")
set(CMAKE_ISPC_COMPILER_FRONTEND_VARIANT "@CMAKE_ISPC_COMPILER_FRONTEND_VARIANT@")
set(CMAKE_ISPC_SIMULATE_VERSION "@CMAKE_ISPC_SIMULATE_VERSION@")
set(CMAKE_AR "@CMAKE_AR@")
set(CMAKE_ISPC_COMPILER_AR "@CMAKE_ISPC_COMPILER_AR@")
set(CMAKE_RANLIB "@CMAKE_RANLIB@")
set(CMAKE_ISPC_COMPILER_RANLIB "@CMAKE_ISPC_COMPILER_RANLIB@")
set(CMAKE_ISPC_COMPILER_LOADED 1)
set(CMAKE_ISPC_COMPILER_WORKS @CMAKE_ISPC_COMPILER_WORKS@)
set(CMAKE_ISPC_ABI_COMPILED @CMAKE_ISPC_ABI_COMPILED@)
set(CMAKE_ISPC_COMPILER_ENV_VAR "ISPC")
set(CMAKE_ISPC_COMPILER_ID_RUN 1)
set(CMAKE_ISPC_SOURCE_FILE_EXTENSIONS ispc)
set(CMAKE_ISPC_IGNORE_EXTENSIONS o;O)
set(CMAKE_ISPC_LINKER_PREFERENCE 0)
set(CMAKE_ISPC_LINKER_PREFERENCE_PROPAGATES 0)
@CMAKE_ISPC_COMPILER_CUSTOM_CODE@

View File

@@ -0,0 +1,20 @@
export void ispcCompilerABI() {
#if defined(__GNU__) && defined(__ELF__) && defined(__ARM_EABI__)
print("INFO:abi[ELF ARMEABI]");
static char const info_abi[] =
#elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEB__)
print("INFO:abi[ELF ARM]");
#elif defined(__GNU__) && defined(__ELF__) && defined(__ARMEL__)
print("INFO:abi[ELF ARM]");
#elif defined(__linux__) && defined(__ELF__) && defined(__amd64__) && \
defined(__ILP32__)
print("INFO:abi[ELF X32]");
#elif defined(__ELF__)
print("INFO:abi[ELF]");
#endif
}

View File

@@ -0,0 +1,62 @@
export void ispcCompilerId() {
// Identify the compiler
#if defined(ISPC)
print("INFO:compiler[Intel]");
#endif
// Identify the platform
#if defined(__linux) || defined(__linux__) || defined(linux)
print("INFO:platform[Linux]");
#elif defined(__CYGWIN__)
print("INFO:platform[Cygwin]");
#elif defined(__MINGW32__)
print("INFO:platform[MinGW]");
#elif defined(__APPLE__)
print("INFO:platform[Darwin]");
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
print("INFO:platform[Windows]");
#elif defined(__FreeBSD__) || defined(__FreeBSD)
print("INFO:platform[FreeBSD]");
#elif defined(__NetBSD__) || defined(__NetBSD)
print("INFO:platform[NetBSD]");
#elif defined(__OpenBSD__) || defined(__OPENBSD)
print("INFO:platform[OpenBSD]");
#elif defined(__sun) || defined(sun)
print("INFO:platform[SunOS]");
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
print("INFO:platform[AIX]");
#elif defined(__hpux) || defined(__hpux__)
print("INFO:platform[HP-UX]");
#elif defined(__HAIKU__)
print("INFO:platform[Haiku]");
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
print("INFO:platform[BeOS]");
#elif defined(__QNX__) || defined(__QNXNTO__)
print("INFO:platform[QNX]");
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
print("INFO:platform[Tru64]");
#elif defined(__riscos) || defined(__riscos__)
print("INFO:platform[RISCos]");
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
print("INFO:platform[SINIX]");
#elif defined(__UNIX_SV__)
print("INFO:platform[UNIX_SV]");
#elif defined(__bsdos__)
print("INFO:platform[BSDOS]");
#elif defined(_MPRAS) || defined(MPRAS)
print("INFO:platform[MP-RAS]");
#elif defined(__osf) || defined(__osf__)
print("INFO:platform[OSF1]");
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
print("INFO:platform[SCO_SV]");
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
print("INFO:platform[ULTRIX]");
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
print("INFO:platform[Xenix]");
#else
print("INFO:platform[]");
#endif
}

View File

@@ -0,0 +1,56 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
set(CMAKE_ISPC_OUTPUT_EXTENSION .o)
set(CMAKE_INCLUDE_FLAG_ISPC "-I")
# Load compiler-specific information.
if(CMAKE_ISPC_COMPILER_ID)
include(Compiler/${CMAKE_ISPC_COMPILER_ID}-ISPC OPTIONAL)
endif()
# load the system- and compiler specific files
if(CMAKE_ISPC_COMPILER_ID)
# load a hardware specific file, mostly useful for embedded compilers
if(CMAKE_SYSTEM_PROCESSOR)
include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ISPC_COMPILER_ID}-ISPC-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
endif()
include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_ISPC_COMPILER_ID}-ISPC OPTIONAL)
endif()
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
# and you can set these flags in the cmake cache
set(CMAKE_ISPC_FLAGS_INIT "$ENV{ISPCFLAGS} ${CMAKE_ISPC_FLAGS_INIT}")
cmake_initialize_per_config_variable(CMAKE_ISPC_FLAGS "Flags used by the ISPC compiler")
if(CMAKE_ISPC_STANDARD_LIBRARIES_INIT)
set(CMAKE_ISPC_STANDARD_LIBRARIES "${CMAKE_ISPC_STANDARD_LIBRARIES_INIT}"
CACHE STRING "Libraries linked by default with all ISPC applications.")
mark_as_advanced(CMAKE_ISPC_STANDARD_LIBRARIES)
endif()
include(CMakeCommonLanguageInclude)
# now define the following rules:
# CMAKE_ISPC_COMPILE_OBJECT
# Create a static archive incrementally for large object file counts.
if(NOT DEFINED CMAKE_ISPC_ARCHIVE_CREATE)
set(CMAKE_ISPC_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_ISPC_ARCHIVE_APPEND)
set(CMAKE_ISPC_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_ISPC_ARCHIVE_FINISH)
set(CMAKE_ISPC_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
endif()
if(NOT CMAKE_ISPC_COMPILE_OBJECT)
set(CMAKE_ISPC_COMPILE_OBJECT
"<CMAKE_ISPC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> --emit-obj <SOURCE> -h <ISPC_HEADER>")
endif()
set(CMAKE_ISPC_INFORMATION_LOADED 1)

View File

@@ -0,0 +1,43 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
if(CMAKE_ISPC_COMPILER_FORCED)
# The compiler configuration was forced by the user.
# Assume the user has configured all compiler information.
set(CMAKE_ISPC_COMPILER_WORKS TRUE)
return()
endif()
include(CMakeTestCompilerCommon)
# Make sure we try to compile as a STATIC_LIBRARY
set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# # Try to identify the ABI and configure it into CMakeISPCCompiler.cmake
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
CMAKE_DETERMINE_COMPILER_ABI(ISPC ${CMAKE_ROOT}/Modules/CMakeISPCCompilerABI.ispc)
if(CMAKE_ISPC_ABI_COMPILED)
# # The compiler worked so skip dedicated test below.
set(CMAKE_ISPC_COMPILER_WORKS TRUE)
message(STATUS "Check for working ISPC compiler: ${CMAKE_ISPC_COMPILER} - skipped")
endif()
# Re-configure to save learned information.
configure_file(
${CMAKE_ROOT}/Modules/CMakeISPCCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeISPCCompiler.cmake
@ONLY
)
include(${CMAKE_PLATFORM_INFO_DIR}/CMakeISPCCompiler.cmake)
if(CMAKE_ISPC_SIZEOF_DATA_PTR)
foreach(f ${CMAKE_ISPC_ABI_FILES})
include(${f})
endforeach()
unset(CMAKE_ISPC_ABI_FILES)
endif()
set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE})

View File

@@ -0,0 +1,22 @@
include(Compiler/CMakeCommonCompilerMacros)
# Not aware of any verbose flag for ISPC
#set(CMAKE_ISPC_VERBOSE_FLAG )
set(CMAKE_DEPFILE_FLAGS_ISPC "-M -MT <OBJECT> -MF <DEPFILE>")
string(APPEND CMAKE_ISPC_FLAGS_INIT " ")
string(APPEND CMAKE_ISPC_FLAGS_DEBUG_INIT "-O0 -g")
string(APPEND CMAKE_ISPC_FLAGS_RELEASE_INIT " -O3 -DNDEBUG")
string(APPEND CMAKE_ISPC_FLAGS_MINSIZEREL_INIT " -O1 -DNDEBUG")
string(APPEND CMAKE_ISPC_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG")
set(CMAKE_ISPC_COMPILE_OPTIONS_PIE --pic)
set(CMAKE_ISPC_COMPILE_OPTIONS_PIC --pic)
set(CMAKE_INCLUDE_SYSTEM_FLAG_ISPC -isystem=)
set(CMAKE_ISPC_RESPONSE_FILE_FLAG "@")
set(CMAKE_ISPC_USE_RESPONSE_FILE_FOR_INCLUDES 1)
set(CMAKE_ISPC_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
set(CMAKE_ISPC_USE_RESPONSE_FILE_FOR_OBJECTS 1)

View File

@@ -0,0 +1,8 @@
if(CMAKE_VERBOSE_MAKEFILE)
set(CMAKE_CL_NOLOGO)
else()
set(CMAKE_CL_NOLOGO "/nologo")
endif()
set(CMAKE_ISPC_CREATE_STATIC_LIBRARY "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")

View File

@@ -192,6 +192,8 @@ SETUP_LANGUAGE(objc_properties, OBJC);
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
SETUP_LANGUAGE(objcxx_properties, OBJCXX);
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
SETUP_LANGUAGE(ispc_properties, ISPC);
// NOLINTNEXTLINE(bugprone-suspicious-missing-comma)
SETUP_LANGUAGE(swift_properties, Swift);
#undef SETUP_LANGUAGE
@@ -499,6 +501,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
// when the only language is ISPC we know that the output
// type must by a static library
if (testLangs.size() == 1 && testLangs.count("ISPC") == 1) {
targetType = cmStateEnums::STATIC_LIBRARY;
}
std::string const tcConfig =
this->Makefile->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION");
@@ -702,6 +710,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(
&objcxx_properties[lang_property_start],
&objcxx_properties[lang_property_start + lang_property_size]);
vars.insert(&ispc_properties[lang_property_start],
&ispc_properties[lang_property_start + lang_property_size]);
vars.insert(&swift_properties[lang_property_start],
&swift_properties[lang_property_start + lang_property_size]);
vars.insert(kCMAKE_CUDA_ARCHITECTURES);
@@ -744,6 +754,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(
&objcxx_properties[pie_property_start],
&objcxx_properties[pie_property_start + pie_property_size]);
vars.insert(&ispc_properties[pie_property_start],
&ispc_properties[pie_property_start + pie_property_size]);
vars.insert(&swift_properties[pie_property_start],
&swift_properties[pie_property_start + pie_property_size]);
}

View File

@@ -715,7 +715,8 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
static const CompilerIdNode cCompilerIdNode("C"), cxxCompilerIdNode("CXX"),
cudaCompilerIdNode("CUDA"), objcCompilerIdNode("OBJC"),
objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran");
objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran"),
ispcCompilerIdNode("ISPC");
struct CompilerVersionNode : public cmGeneratorExpressionNode
{
@@ -780,7 +781,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
static const CompilerVersionNode cCompilerVersionNode("C"),
cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"),
objcCompilerVersionNode("OBJC"), objcxxCompilerVersionNode("OBJCXX"),
fortranCompilerVersionNode("Fortran");
fortranCompilerVersionNode("Fortran"), ispcCompilerVersionNode("ISPC");
struct PlatformIdNode : public cmGeneratorExpressionNode
{

View File

@@ -1363,18 +1363,25 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
namespace {
std::string AddSwiftInterfaceIncludeDirectories(
enum class IncludeDirectoryFallBack
{
BINARY,
OBJECT
};
std::string AddLangSpecificInterfaceIncludeDirectories(
const cmGeneratorTarget* root, const cmGeneratorTarget* target,
const std::string& config, cmGeneratorExpressionDAGChecker* context)
const std::string& lang, const std::string& config,
const std::string& propertyName, IncludeDirectoryFallBack mode,
cmGeneratorExpressionDAGChecker* context)
{
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
"Swift_MODULE_DIRECTORY", nullptr,
context };
propertyName, nullptr, context };
switch (dag.Check()) {
case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
dag.ReportError(nullptr,
"$<TARGET_PROPERTY:" + target->GetName() +
",Swift_MODULE_DIRECTORY>");
dag.ReportError(
nullptr, "$<TARGET_PROPERTY:" + target->GetName() + ",propertyName");
CM_FALLTHROUGH;
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
@@ -1390,13 +1397,16 @@ std::string AddSwiftInterfaceIncludeDirectories(
target->GetLinkInterfaceLibraries(config, root, true)) {
for (const cmLinkItem& library : interface->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
if (cm::contains(dependency->GetAllConfigCompileLanguages(),
"Swift")) {
std::string value =
dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
auto* lg = dependency->GetLocalGenerator();
std::string value = dependency->GetSafeProperty(propertyName);
if (value.empty()) {
value =
dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
if (mode == IncludeDirectoryFallBack::BINARY) {
value = lg->GetCurrentBinaryDirectory();
} else if (mode == IncludeDirectoryFallBack::OBJECT) {
value = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
lg->GetTargetDirectory(dependency));
}
}
if (!directories.empty()) {
@@ -1410,35 +1420,39 @@ std::string AddSwiftInterfaceIncludeDirectories(
return directories;
}
void AddSwiftImplicitIncludeDirectories(
const cmGeneratorTarget* target, const std::string& config,
EvaluatedTargetPropertyEntries& entries)
void AddLangSpecificImplicitIncludeDirectories(
const cmGeneratorTarget* target, const std::string& lang,
const std::string& config, const std::string& propertyName,
IncludeDirectoryFallBack mode, EvaluatedTargetPropertyEntries& entries)
{
if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
"Swift_MODULE_DIRECTORY", nullptr,
nullptr };
propertyName, nullptr, nullptr };
for (const cmLinkImplItem& library : libraries->Libraries) {
if (const cmGeneratorTarget* dependency = library.Target) {
if (!dependency->IsInBuildSystem()) {
continue;
}
if (cm::contains(dependency->GetAllConfigCompileLanguages(),
"Swift")) {
if (cm::contains(dependency->GetAllConfigCompileLanguages(), lang)) {
auto* lg = dependency->GetLocalGenerator();
EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
if (cmProp val = dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
if (cmProp val = dependency->GetProperty(propertyName)) {
entry.Values.emplace_back(*val);
} else {
entry.Values.emplace_back(
dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
if (mode == IncludeDirectoryFallBack::BINARY) {
entry.Values.emplace_back(lg->GetCurrentBinaryDirectory());
} else if (mode == IncludeDirectoryFallBack::OBJECT) {
entry.Values.emplace_back(
dependency->GetObjectDirectory(config));
}
}
cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
config, &dag),
entry.Values);
cmExpandList(
AddLangSpecificInterfaceIncludeDirectories(
target, dependency, lang, config, propertyName, mode, &dag),
entry.Values);
entries.Entries.emplace_back(std::move(entry));
}
}
@@ -3482,7 +3496,28 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
if (lang == "Swift") {
AddSwiftImplicitIncludeDirectories(this, config, entries);
AddLangSpecificImplicitIncludeDirectories(
this, lang, config, "Swift_MODULE_DIRECTORY",
IncludeDirectoryFallBack::BINARY, entries);
}
if (this->CanCompileSources() && (lang != "Swift" && lang != "Fortran")) {
const std::string propertyName = "ISPC_HEADER_DIRECTORY";
// If this target has ISPC sources make sure to add the header
// directory to other compilation units
if (cm::contains(this->GetAllConfigCompileLanguages(), "ISPC")) {
if (cmProp val = this->GetProperty(propertyName)) {
includes.emplace_back(*val);
} else {
includes.emplace_back(this->GetObjectDirectory(config));
}
}
AddLangSpecificImplicitIncludeDirectories(
this, "ISPC", config, propertyName, IncludeDirectoryFallBack::OBJECT,
entries);
}
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
@@ -5976,6 +6011,37 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory(
return mod_dir;
}
void cmGeneratorTarget::AddISPCGeneratedHeader(std::string const& header,
std::string const& config)
{
std::string config_upper;
if (!config.empty()) {
config_upper = cmSystemTools::UpperCase(config);
}
auto iter = this->ISPCGeneratedHeaders.find(config_upper);
if (iter == this->ISPCGeneratedHeaders.end()) {
std::vector<std::string> headers;
headers.emplace_back(header);
this->ISPCGeneratedHeaders.insert({ config_upper, headers });
} else {
iter->second.emplace_back(header);
}
}
std::vector<std::string> cmGeneratorTarget::GetGeneratedISPCHeaders(
std::string const& config) const
{
std::string config_upper;
if (!config.empty()) {
config_upper = cmSystemTools::UpperCase(config);
}
auto iter = this->ISPCGeneratedHeaders.find(config_upper);
if (iter == this->ISPCGeneratedHeaders.end()) {
return std::vector<std::string>{};
}
return iter->second;
}
std::string cmGeneratorTarget::GetFrameworkVersion() const
{
assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);

View File

@@ -816,6 +816,11 @@ public:
const std::string& GetSourcesProperty() const;
void AddISPCGeneratedHeader(std::string const& header,
std::string const& config);
std::vector<std::string> GetGeneratedISPCHeaders(
std::string const& config) const;
private:
void AddSourceCommon(const std::string& src, bool before = false);
@@ -994,6 +999,9 @@ private:
std::unordered_set<std::string> UnityBatchedSourceFiles;
std::unordered_map<std::string, std::vector<std::string>>
ISPCGeneratedHeaders;
bool IsLinkLookupScope(std::string const& n,
cmLocalGenerator const*& lg) const;

View File

@@ -1601,6 +1601,7 @@ bool cmGlobalGenerator::AddAutomaticSources()
continue;
}
lg->AddUnityBuild(gt.get());
lg->AddISPCDependencies(gt.get());
// Targets that re-use a PCH are handled below.
if (!gt->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) {
lg->AddPchDependencies(gt.get());

View File

@@ -680,6 +680,9 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
this->NinjaSupportsRestatTool = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForRestatTool().c_str());
this->NinjaSupportsMultipleOutputs = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForMultipleOutputs().c_str());
}
bool cmGlobalNinjaGenerator::CheckLanguages(
@@ -688,6 +691,9 @@ bool cmGlobalNinjaGenerator::CheckLanguages(
if (cm::contains(languages, "Fortran")) {
return this->CheckFortran(mf);
}
if (cm::contains(languages, "ISPC")) {
return this->CheckISPC(mf);
}
if (cm::contains(languages, "Swift")) {
const std::string architectures =
mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
@@ -721,6 +727,25 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
return false;
}
bool cmGlobalNinjaGenerator::CheckISPC(cmMakefile* mf) const
{
if (this->NinjaSupportsMultipleOutputs) {
return true;
}
std::ostringstream e;
/* clang-format off */
e <<
"The Ninja generator does not support ISPC using Ninja version\n"
" " << this->NinjaVersion << "\n"
"due to lack of required features. Ninja 1.10 or higher is required."
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
void cmGlobalNinjaGenerator::EnableLanguage(
std::vector<std::string> const& langs, cmMakefile* mf, bool optional)
{
@@ -1127,6 +1152,21 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
}
} else {
cmNinjaDeps outs;
auto computeISPCOuputs = [](cmGlobalNinjaGenerator* gg,
cmGeneratorTarget const* depTarget,
cmNinjaDeps& outputDeps,
const std::string& targetConfig) {
if (depTarget->CanCompileSources()) {
auto headers = depTarget->GetGeneratedISPCHeaders(targetConfig);
if (!headers.empty()) {
std::transform(headers.begin(), headers.end(), headers.begin(),
gg->MapToNinjaPath());
outputDeps.insert(outputDeps.end(), headers.begin(), headers.end());
}
}
};
for (cmTargetDepend const& targetDep :
this->GetTargetDirectDepends(target)) {
if (!targetDep->IsInBuildSystem()) {
@@ -1134,8 +1174,10 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
}
if (targetDep.IsCross()) {
this->AppendTargetOutputs(targetDep, outs, fileConfig, depends);
computeISPCOuputs(this, targetDep, outs, fileConfig);
} else {
this->AppendTargetOutputs(targetDep, outs, config, depends);
computeISPCOuputs(this, targetDep, outs, config);
}
}
std::sort(outs.begin(), outs.end());

View File

@@ -370,6 +370,10 @@ public:
return "1.10";
}
static std::string RequiredNinjaVersionForCleanDeadTool() { return "1.10"; }
static std::string RequiredNinjaVersionForMultipleOutputs()
{
return "1.10";
}
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
@@ -447,6 +451,7 @@ private:
bool CheckLanguages(std::vector<std::string> const& languages,
cmMakefile* mf) const override;
bool CheckFortran(cmMakefile* mf) const;
bool CheckISPC(cmMakefile* mf) const;
void CloseCompileCommandsStream();
@@ -533,6 +538,7 @@ private:
bool NinjaSupportsRestatTool = false;
bool NinjaSupportsUnconditionalRecompactTool = false;
bool NinjaSupportsCleanDeadTool = false;
bool NinjaSupportsMultipleOutputs = false;
private:
void InitOutputPathPrefix();

View File

@@ -2426,6 +2426,38 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags,
this->EscapeForShell(rawFlag, false, false, false, this->IsNinjaMulti()));
}
void cmLocalGenerator::AddISPCDependencies(cmGeneratorTarget* target)
{
//
std::vector<std::string> configsList =
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
for (std::string const& config : configsList) {
std::string perConfigDir = target->GetObjectDirectory(config);
if (cmProp prop = target->GetProperty("ISPC_HEADER_DIRECTORY")) {
perConfigDir = cmSystemTools::CollapseFullPath(
cmStrCat(this->GetBinaryDirectory(), '/', *prop));
}
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, config);
// build up the list of ispc headers that this target is generating
for (cmSourceFile const* sf : sources) {
// Generate this object file's rule file.
const std::string& lang = sf->GetLanguage();
if (lang == "ISPC") {
std::string const& objectName = target->GetObjectName(sf);
std::string ispcSource =
cmSystemTools::GetFilenameWithoutLastExtension(objectName);
auto headerPath = cmStrCat(perConfigDir, '/', ispcSource, ".h");
target->AddISPCGeneratedHeader(headerPath, config);
}
}
}
}
void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
{
std::vector<std::string> configsList =

View File

@@ -133,6 +133,7 @@ public:
const std::vector<BT<std::string>>& newFlags) const;
virtual void AppendFlagEscape(std::string& flags,
const std::string& rawFlag) const;
void AddISPCDependencies(cmGeneratorTarget* target);
void AddPchDependencies(cmGeneratorTarget* target);
void AddUnityBuild(cmGeneratorTarget* target);
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,

View File

@@ -235,7 +235,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
for (LocalObjectEntry const& entry : localObjectFile.second) {
if (entry.Language == "C" || entry.Language == "CXX" ||
entry.Language == "CUDA" || entry.Language == "Fortran") {
entry.Language == "CUDA" || entry.Language == "Fortran" ||
entry.Language == "ISPC") {
// Right now, C, C++, Fortran and CUDA have both a preprocessor and the
// ability to generate assembly code
lang_has_preprocessor = true;
@@ -1444,7 +1445,8 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
// Create the scanner for this language
std::unique_ptr<cmDepends> scanner;
if (lang == "C" || lang == "CXX" || lang == "RC" || lang == "ASM" ||
lang == "OBJC" || lang == "OBJCXX" || lang == "CUDA") {
lang == "OBJC" || lang == "OBJCXX" || lang == "CUDA" ||
lang == "ISPC") {
// TODO: Handle RC (resource files) dependencies correctly.
scanner = cm::make_unique<cmDependsC>(this, targetDir, lang, &validDeps);
}

View File

@@ -268,6 +268,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->ExternalObjects.push_back(objectFileName);
}
}
std::vector<cmSourceFile const*> objectSources;
this->GeneratorTarget->GetObjectSources(objectSources,
this->GetConfigName());
@@ -525,6 +526,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
}
if (lang != "ISPC") {
auto const& headers =
this->GeneratorTarget->GetGeneratedISPCHeaders(config);
if (!headers.empty()) {
depends.insert(depends.end(), headers.begin(), headers.end());
}
}
std::string relativeObj =
cmStrCat(this->LocalGenerator->GetHomeRelativeOutputPath(), obj);
// Write the build rule.
@@ -552,6 +561,23 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->AppendFortranPreprocessFlags(flags, source);
}
std::string ispcHeaderRelative;
std::string ispcHeaderForShell;
if (lang == "ISPC") {
std::string ispcSource =
cmSystemTools::GetFilenameWithoutLastExtension(objectName);
std::string directory = this->GeneratorTarget->GetObjectDirectory(config);
if (cmProp prop =
this->GeneratorTarget->GetProperty("ISPC_HEADER_DIRECTORY")) {
directory =
cmStrCat(this->LocalGenerator->GetBinaryDirectory(), '/', *prop);
}
ispcHeaderRelative = cmStrCat(directory, '/', ispcSource, ".h");
ispcHeaderForShell = this->LocalGenerator->ConvertToOutputFormat(
ispcHeaderRelative, cmOutputConverter::SHELL);
}
// Add flags from source file properties.
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (cmProp cflags = source.GetProperty(COMPILE_FLAGS)) {
@@ -717,6 +743,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmOutputConverter::SHELL);
vars.ObjectFileDir = objectFileDir.c_str();
vars.Flags = flags.c_str();
vars.ISPCHeader = ispcHeaderForShell.c_str();
std::string definesString = cmStrCat("$(", lang, "_DEFINES)");
@@ -735,7 +762,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// ability to export compile commands
bool lang_has_preprocessor =
((lang == "C") || (lang == "CXX") || (lang == "OBJC") ||
(lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA"));
(lang == "OBJCXX") || (lang == "Fortran") || (lang == "CUDA") ||
lang == "ISPC");
bool const lang_has_assembly = lang_has_preprocessor;
bool const lang_can_export_cmds = lang_has_preprocessor;
@@ -910,9 +938,16 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
if (!evaluated_outputs.empty()) {
// Register these as extra files to clean.
cmExpandList(evaluated_outputs, outputs);
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
}
}
if (!ispcHeaderRelative
.empty()) { // can't move ispcHeader as vars is using it
outputs.emplace_back(ispcHeaderRelative);
}
if (outputs.size() > 1) {
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
}
// Write the rule.
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,

View File

@@ -631,6 +631,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
vars.TargetCompilePDB = "$TARGET_COMPILE_PDB";
vars.ObjectDir = "$OBJECT_DIR";
vars.ObjectFileDir = "$OBJECT_FILE_DIR";
vars.ISPCHeader = "$ISPC_HEADER_FILE";
cmMakefile* mf = this->GetMakefile();
@@ -1369,6 +1370,42 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
objBuild.RspFile = cmStrCat(objectFileName, ".rsp");
if (language == "ISPC") {
std::string const& objectName =
this->GeneratorTarget->GetObjectName(source);
std::string ispcSource =
cmSystemTools::GetFilenameWithoutLastExtension(objectName);
std::string ispcDirectory = objectFileDir;
if (cmProp prop =
this->GeneratorTarget->GetProperty("ISPC_HEADER_DIRECTORY")) {
ispcDirectory = *prop;
}
ispcDirectory =
cmStrCat(this->LocalGenerator->GetBinaryDirectory(), '/', ispcDirectory);
std::string ispcHeader = cmStrCat(ispcDirectory, '/', ispcSource, ".h");
ispcHeader = this->ConvertToNinjaPath(ispcHeader);
// Make sure ninja knows what command generates the header
objBuild.ImplicitOuts.push_back(ispcHeader);
// Make sure ninja knows how to clean the generated header
this->GetGlobalGenerator()->AddAdditionalCleanFile(ispcHeader, config);
vars["ISPC_HEADER_FILE"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
ispcHeader, cmOutputConverter::SHELL);
} else {
auto headers = this->GeneratorTarget->GetGeneratedISPCHeaders(config);
if (!headers.empty()) {
std::transform(headers.begin(), headers.end(), headers.begin(),
MapToNinjaPath());
objBuild.OrderOnlyDeps.insert(objBuild.OrderOnlyDeps.end(),
headers.begin(), headers.end());
}
}
if (language == "Swift") {
this->EmitSwiftDependencyInfo(source, config);
} else {

View File

@@ -90,6 +90,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.AIXExports;
}
}
if (replaceValues.ISPCHeader) {
if (variable == "ISPC_HEADER") {
return replaceValues.ISPCHeader;
}
}
if (replaceValues.Defines && variable == "DEFINES") {
return replaceValues.Defines;
}

View File

@@ -64,6 +64,7 @@ public:
const char* SwiftModuleName;
const char* SwiftOutputFileMap;
const char* SwiftSources;
const char* ISPCHeader;
};
// Expand rule variables in CMake of the type found in language rules

View File

@@ -366,6 +366,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("JOB_POOL_COMPILE");
initProp("JOB_POOL_LINK");
initProp("JOB_POOL_PRECOMPILE_HEADER");
initProp("ISPC_HEADER_DIRECTORY");
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
initProp("Swift_LANGUAGE_VERSION");

View File

@@ -205,6 +205,7 @@ cmake::cmake(Role role, cmState::Mode mode)
setupExts(this->CudaFileExtensions, { "cu" });
setupExts(this->FortranFileExtensions,
{ "f", "F", "for", "f77", "f90", "f95", "f03" });
setupExts(this->ISPCFileExtensions, { "ispc" });
}
}
@@ -1978,6 +1979,8 @@ std::vector<std::string> cmake::GetAllExtensions() const
// cuda extensions are also in SourceFileExtensions so we ignore it here
allExt.insert(allExt.end(), this->FortranFileExtensions.ordered.begin(),
this->FortranFileExtensions.ordered.end());
allExt.insert(allExt.end(), this->ISPCFileExtensions.ordered.begin(),
this->ISPCFileExtensions.ordered.end());
return allExt;
}

View File

@@ -268,7 +268,8 @@ public:
{
return this->CLikeSourceFileExtensions.Test(ext) ||
this->CudaFileExtensions.Test(ext) ||
this->FortranFileExtensions.Test(ext);
this->FortranFileExtensions.Test(ext) ||
this->ISPCFileExtensions.Test(ext);
}
bool IsACLikeSourceExtension(cm::string_view ext) const
@@ -617,6 +618,7 @@ private:
FileExtensions CLikeSourceFileExtensions;
FileExtensions HeaderFileExtensions;
FileExtensions CudaFileExtensions;
FileExtensions ISPCFileExtensions;
FileExtensions FortranFileExtensions;
bool ClearBuildSystem = false;
bool DebugTryCompile = false;

View File

@@ -1483,6 +1483,10 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
add_subdirectory(CudaOnly)
endif()
if(CMake_TEST_ISPC)
add_subdirectory(ISPC)
endif()
if(CMake_TEST_FindGTest)
add_subdirectory(FindGTest)
add_subdirectory(GoogleTest)

13
Tests/ISPC/CMakeLists.txt Normal file
View File

@@ -0,0 +1,13 @@
macro (add_ispc_test_macro name)
add_test_macro("${name}" ${ARGN})
set_property(TEST "${name}" APPEND
PROPERTY LABELS "ISPC")
endmacro ()
add_ispc_test_macro(ISPC.Defines ISPCDefines)
add_ispc_test_macro(ISPC.ObjectLibrary ISPCObjectLibrary)
add_ispc_test_macro(ISPC.ResponseAndDefine ISPCResponseAndDefine)
add_ispc_test_macro(ISPC.StaticLibrary ISPCStaticLibrary)
add_ispc_test_macro(ISPC.TryCompile ISPCTryCompile)

View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.18)
project(ISPCDefines CXX ISPC)
set(CMAKE_ISPC_FLAGS -DM_PI=3.1415926535f)
add_compile_definitions([==[STRUCT_DEFINE=struct{uniform int a]==])
add_executable(ISPCDefines
main.cxx
simple.ispc
)
set_target_properties(ISPCDefines PROPERTIES POSITION_INDEPENDENT_CODE ON)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set_source_files_properties(simple.ispc PROPERTIES COMPILE_OPTIONS "--arch=x86")
endif()

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include "simple.ispc.h"
int main()
{
float vin[16], vout[16];
for (int i = 0; i < 16; ++i)
vin[i] = i;
ispc::simple(vin, vout, 16);
for (int i = 0; i < 16; ++i)
printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]);
}

View File

@@ -0,0 +1,15 @@
//textual error if STRUCT_DEFINE not set
STRUCT_DEFINE;};
export void simple(uniform float vin[], uniform float vout[],
uniform int count) {
foreach (index = 0 ... count) {
float v = vin[index];
if (v < M_PI)
v = v * v;
else
v = sqrt(v);
vout[index] = v;
}
}

View File

@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.18)
project(ISPCObjectLibrary CXX ISPC)
set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_ISPC_FLAGS "--arch=x86")
endif()
add_library(ispc_objects OBJECT simple.ispc extra.ispc)
target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4>")
set_target_properties(ispc_objects PROPERTIES POSITION_INDEPENDENT_CODE ON)
add_executable(ISPCObjectLibrary main.cxx extra.cxx)
target_link_libraries(ISPCObjectLibrary PRIVATE ispc_objects)

View File

@@ -0,0 +1,17 @@
#include <stdio.h>
#include "extra.ispc.h"
int extra()
{
float vin[16], vout[16];
for (int i = 0; i < 16; ++i)
vin[i] = i;
ispc::extra(vin, vout, 16);
for (int i = 0; i < 16; ++i)
printf("%d: extra(%f) = %f\n", i, vin[i], vout[i]);
return 0;
}

View File

@@ -0,0 +1,12 @@
export void extra(uniform float vin[], uniform float vout[],
uniform int count) {
foreach (index = 0 ... count) {
float v = vin[index];
if (v < 3.)
v = v * v;
else
v = sqrt(v);
vout[index] = v;
}
}

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include "simple.ispc.h"
int main()
{
float vin[16], vout[16];
for (int i = 0; i < 16; ++i)
vin[i] = i;
ispc::simple(vin, vout, 16);
for (int i = 0; i < 16; ++i)
printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]);
}

View File

@@ -0,0 +1,12 @@
export void simple(uniform float vin[], uniform float vout[],
uniform int count) {
foreach (index = 0 ... count) {
float v = vin[index];
if (v < 3.)
v = v * v;
else
v = sqrt(v);
vout[index] = v;
}
}

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.18)
project(ispc_spaces_in_path ISPC CXX)
set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON)
# Make sure we can handle an arg file with tricky defines including spaces in -I include
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/path with spaces/simple_include.h"
"
typedef float FLOAT_TYPE;
"
)
add_executable(ISPCResponseAndDefine main.cxx simple.ispc)
set_target_properties(ISPCResponseAndDefine PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(ISPCResponseAndDefine PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
target_compile_options(ISPCResponseAndDefine PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4>")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
target_compile_options(ISPCResponseAndDefine PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--arch=x86>")
endif()
target_compile_definitions(ISPCResponseAndDefine PRIVATE
"$<$<COMPILE_LANGUAGE:ISPC>:STRUCT_DEFINE=struct{uniform int a>;M_PI=3.14159f")
target_include_directories(ISPCResponseAndDefine PRIVATE
"$<$<COMPILE_LANGUAGE:ISPC>:${CMAKE_CURRENT_BINARY_DIR}/fake path with spaces>"
"$<$<COMPILE_LANGUAGE:ISPC>:${CMAKE_CURRENT_BINARY_DIR}/path with spaces>")

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include "simple.ispc.h"
int main()
{
float vin[16], vout[16];
for (int i = 0; i < 16; ++i)
vin[i] = i;
ispc::simple(vin, vout, 16);
for (int i = 0; i < 16; ++i)
printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]);
}

View File

@@ -0,0 +1,16 @@
STRUCT_DEFINE;};
#include "simple_include.h"
export void simple(uniform FLOAT_TYPE vin[], uniform FLOAT_TYPE vout[],
uniform int count) {
foreach (index = 0 ... count) {
FLOAT_TYPE v = vin[index];
if (v < M_PI)
v = v * v;
else
v = sqrt(v);
vout[index] = v;
}
}

View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.18)
project(ISPCStaticLibrary CXX ISPC)
add_library(ispc_objects STATIC simple.ispc)
target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--target=sse2-i32x4>")
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
target_compile_options(ispc_objects PRIVATE "$<$<COMPILE_LANGUAGE:ISPC>:--arch=x86>")
endif()
set_target_properties(ispc_objects PROPERTIES POSITION_INDEPENDENT_CODE ON)
add_executable(ISPCStaticLibrary main.cxx)
target_link_libraries(ISPCStaticLibrary PRIVATE ispc_objects)

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include "simple.ispc.h"
int main()
{
float vin[16], vout[16];
for (int i = 0; i < 16; ++i)
vin[i] = i;
ispc::simple(vin, vout, 16);
for (int i = 0; i < 16; ++i)
printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]);
}

View File

@@ -0,0 +1,12 @@
export void simple(uniform float vin[], uniform float vout[],
uniform int count) {
foreach (index = 0 ... count) {
float v = vin[index];
if (v < 3.)
v = v * v;
else
v = sqrt(v);
vout[index] = v;
}
}

View File

@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.18)
project(ISPCTryCompile ISPC CXX)
set(CMAKE_NINJA_FORCE_RESPONSE_FILE ON)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_ISPC_FLAGS "--arch=x86")
endif()
#Verify we can use try_compile with ISPC
try_compile(result "${CMAKE_CURRENT_BINARY_DIR}"
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/simple.ispc"
COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/result.o")
add_executable(ISPCTryCompile main.cxx )
target_link_libraries(ISPCTryCompile "${CMAKE_CURRENT_BINARY_DIR}/result.o")

View File

@@ -0,0 +1,19 @@
#include <stdio.h>
namespace ispc {
extern "C" {
void simple(float*, float*, int);
}
}
int main()
{
float vin[16], vout[16];
for (int i = 0; i < 16; ++i)
vin[i] = i;
ispc::simple(vin, vout, 16);
for (int i = 0; i < 16; ++i)
printf("%d: simple(%f) = %f\n", i, vin[i], vout[i]);
}

View File

@@ -0,0 +1,12 @@
export void simple(uniform float vin[], uniform float vout[],
uniform int count) {
foreach (index = 0 ... count) {
float v = vin[index];
if (v < 3.)
v = v * v;
else
v = sqrt(v);
vout[index] = v;
}
}