summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-09-01 13:15:29 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-09-01 13:15:39 (GMT)
commitf10682b7961c2ad56384641ab141a66f34923753 (patch)
tree4bf3b7b721dd33b6934faf6c119770bf04209891
parentcd2f894052ea8191e21ec4997b2181c75f637ae9 (diff)
parent5ece12b7e452acb091300022a392ff71dfce9504 (diff)
downloadCMake-f10682b7961c2ad56384641ab141a66f34923753.zip
CMake-f10682b7961c2ad56384641ab141a66f34923753.tar.gz
CMake-f10682b7961c2ad56384641ab141a66f34923753.tar.bz2
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
-rw-r--r--.gitlab/ci/configure_fedora31_common.cmake1
-rw-r--r--.gitlab/ci/configure_fedora31_makefiles.cmake1
-rw-r--r--.gitlab/ci/configure_fedora31_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_fedora31_ninja_multi.cmake1
-rw-r--r--.gitlab/ci/docker/fedora31/Dockerfile3
-rwxr-xr-x.gitlab/ci/docker/fedora31/install_ispc.sh14
-rw-r--r--.gitlab/os-linux.yml2
-rw-r--r--Auxiliary/vim/syntax/cmake.vim1
-rw-r--r--Help/command/enable_language.rst3
-rw-r--r--Help/command/project.rst2
-rw-r--r--Help/envvar/ISPC.rst13
-rw-r--r--Help/envvar/ISPCFLAGS.rst15
-rw-r--r--Help/manual/cmake-env-variables.7.rst2
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst14
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/prop_sf/LANGUAGE.rst2
-rw-r--r--Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst13
-rw-r--r--Help/release/dev/ispc-language-support.rst11
-rw-r--r--Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst10
-rw-r--r--Modules/CMakeCompilerIdDetection.cmake3
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake22
-rw-r--r--Modules/CMakeDetermineISPCCompiler.cmake96
-rw-r--r--Modules/CMakeFindBinUtils.cmake1
-rw-r--r--Modules/CMakeISPCCompiler.cmake.in30
-rw-r--r--Modules/CMakeISPCCompilerABI.ispc20
-rw-r--r--Modules/CMakeISPCCompilerId.ispc.in62
-rw-r--r--Modules/CMakeISPCInformation.cmake56
-rw-r--r--Modules/CMakeTestISPCCompiler.cmake43
-rw-r--r--Modules/Compiler/Intel-ISPC.cmake22
-rw-r--r--Modules/Platform/Windows-Intel-ISPC.cmake8
-rw-r--r--Source/cmCoreTryCompile.cxx12
-rw-r--r--Source/cmGeneratorExpressionNode.cxx5
-rw-r--r--Source/cmGeneratorTarget.cxx122
-rw-r--r--Source/cmGeneratorTarget.h8
-rw-r--r--Source/cmGlobalGenerator.cxx1
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx42
-rw-r--r--Source/cmGlobalNinjaGenerator.h6
-rw-r--r--Source/cmLocalGenerator.cxx32
-rw-r--r--Source/cmLocalGenerator.h1
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx6
-rw-r--r--Source/cmMakefileTargetGenerator.cxx39
-rw-r--r--Source/cmNinjaTargetGenerator.cxx37
-rw-r--r--Source/cmRulePlaceholderExpander.cxx5
-rw-r--r--Source/cmRulePlaceholderExpander.h1
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmake.cxx3
-rw-r--r--Source/cmake.h4
-rw-r--r--Tests/CMakeLists.txt4
-rw-r--r--Tests/ISPC/CMakeLists.txt13
-rw-r--r--Tests/ISPC/Defines/CMakeLists.txt15
-rw-r--r--Tests/ISPC/Defines/main.cxx15
-rw-r--r--Tests/ISPC/Defines/simple.ispc15
-rw-r--r--Tests/ISPC/ObjectLibrary/CMakeLists.txt17
-rw-r--r--Tests/ISPC/ObjectLibrary/extra.cxx17
-rw-r--r--Tests/ISPC/ObjectLibrary/extra.ispc12
-rw-r--r--Tests/ISPC/ObjectLibrary/main.cxx15
-rw-r--r--Tests/ISPC/ObjectLibrary/simple.ispc12
-rw-r--r--Tests/ISPC/ResponseAndDefine/CMakeLists.txt28
-rw-r--r--Tests/ISPC/ResponseAndDefine/main.cxx15
-rw-r--r--Tests/ISPC/ResponseAndDefine/simple.ispc16
-rw-r--r--Tests/ISPC/StaticLibrary/CMakeLists.txt15
-rw-r--r--Tests/ISPC/StaticLibrary/main.cxx15
-rw-r--r--Tests/ISPC/StaticLibrary/simple.ispc12
-rw-r--r--Tests/ISPC/TryCompile/CMakeLists.txt16
-rw-r--r--Tests/ISPC/TryCompile/main.cxx19
-rw-r--r--Tests/ISPC/TryCompile/simple.ispc12
67 files changed, 1042 insertions, 40 deletions
diff --git a/.gitlab/ci/configure_fedora31_common.cmake b/.gitlab/ci/configure_fedora31_common.cmake
index dc068d5..90b9d90 100644
--- a/.gitlab/ci/configure_fedora31_common.cmake
+++ b/.gitlab/ci/configure_fedora31_common.cmake
@@ -1,4 +1,5 @@
set(BUILD_CursesDialog ON CACHE BOOL "")
set(BUILD_QtDialog ON CACHE BOOL "")
+
include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_makefiles.cmake b/.gitlab/ci/configure_fedora31_makefiles.cmake
index 20863a2..efb4b84 100644
--- a/.gitlab/ci/configure_fedora31_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora31_makefiles.cmake
@@ -1 +1,2 @@
+set(CMake_TEST_ISPC "ON" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora31_ninja.cmake b/.gitlab/ci/configure_fedora31_ninja.cmake
index 74768b7..dad6d45 100644
--- a/.gitlab/ci/configure_fedora31_ninja.cmake
+++ b/.gitlab/ci/configure_fedora31_ninja.cmake
@@ -1 +1,2 @@
+set(CMake_TEST_ISPC "ON" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora31_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_ninja_multi.cmake b/.gitlab/ci/configure_fedora31_ninja_multi.cmake
index 20863a2..efb4b84 100644
--- a/.gitlab/ci/configure_fedora31_ninja_multi.cmake
+++ b/.gitlab/ci/configure_fedora31_ninja_multi.cmake
@@ -1 +1,2 @@
+set(CMake_TEST_ISPC "ON" CACHE STRING "")
include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/docker/fedora31/Dockerfile b/.gitlab/ci/docker/fedora31/Dockerfile
index 5588a85..4ad8d45 100644
--- a/.gitlab/ci/docker/fedora31/Dockerfile
+++ b/.gitlab/ci/docker/fedora31/Dockerfile
@@ -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
diff --git a/.gitlab/ci/docker/fedora31/install_ispc.sh b/.gitlab/ci/docker/fedora31/install_ispc.sh
new file mode 100755
index 0000000..fdc14b5
--- /dev/null
+++ b/.gitlab/ci/docker/fedora31/install_ispc.sh
@@ -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"
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 9ad8fc7..dfd94f5 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -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"
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 2d63eb0..2dd3174 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -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
diff --git a/Help/command/enable_language.rst b/Help/command/enable_language.rst
index fdc44f2..e8640ea 100644
--- a/Help/command/enable_language.rst
+++ b/Help/command/enable_language.rst
@@ -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.
diff --git a/Help/command/project.rst b/Help/command/project.rst
index b6093d3..c325050 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -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.
diff --git a/Help/envvar/ISPC.rst b/Help/envvar/ISPC.rst
new file mode 100644
index 0000000..bcd6260
--- /dev/null
+++ b/Help/envvar/ISPC.rst
@@ -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.
diff --git a/Help/envvar/ISPCFLAGS.rst b/Help/envvar/ISPCFLAGS.rst
new file mode 100644
index 0000000..21df037
--- /dev/null
+++ b/Help/envvar/ISPCFLAGS.rst
@@ -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>`.
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index ce1e360..13e0d39 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -63,6 +63,8 @@ Environment Variables for Languages
/envvar/CXXFLAGS
/envvar/FC
/envvar/FFLAGS
+ /envvar/ISPC
+ /envvar/ISPCFLAGS
/envvar/OBJC
/envvar/OBJCXX
/envvar/RC
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index c7f6b27..b9c238d 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -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
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index afdf78c..644e87b 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -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
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 53cdd0b..082e2d5 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -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
diff --git a/Help/prop_sf/LANGUAGE.rst b/Help/prop_sf/LANGUAGE.rst
index 88d438e..1dd2554 100644
--- a/Help/prop_sf/LANGUAGE.rst
+++ b/Help/prop_sf/LANGUAGE.rst
@@ -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.
diff --git a/Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst b/Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst
new file mode 100644
index 0000000..2a3a8bc
--- /dev/null
+++ b/Help/prop_tgt/ISPC_HEADER_DIRECTORY.rst
@@ -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.
diff --git a/Help/release/dev/ispc-language-support.rst b/Help/release/dev/ispc-language-support.rst
new file mode 100644
index 0000000..254442e
--- /dev/null
+++ b/Help/release/dev/ispc-language-support.rst
@@ -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.
diff --git a/Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst b/Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst
new file mode 100644
index 0000000..a7c9cf6
--- /dev/null
+++ b/Help/variable/CMAKE_ISPC_HEADER_DIRECTORY.rst
@@ -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.
diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake
index acd15df..a0f0dfa 100644
--- a/Modules/CMakeCompilerIdDetection.cmake
+++ b/Modules/CMakeCompilerIdDetection.cmake
@@ -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)
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index d7a35e1..8724ed8 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -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}"
diff --git a/Modules/CMakeDetermineISPCCompiler.cmake b/Modules/CMakeDetermineISPCCompiler.cmake
new file mode 100644
index 0000000..ff2bf20
--- /dev/null
+++ b/Modules/CMakeDetermineISPCCompiler.cmake
@@ -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")
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index b2004f1..66adafa 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -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"))
diff --git a/Modules/CMakeISPCCompiler.cmake.in b/Modules/CMakeISPCCompiler.cmake.in
new file mode 100644
index 0000000..28c31cc
--- /dev/null
+++ b/Modules/CMakeISPCCompiler.cmake.in
@@ -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@
diff --git a/Modules/CMakeISPCCompilerABI.ispc b/Modules/CMakeISPCCompilerABI.ispc
new file mode 100644
index 0000000..e23abce
--- /dev/null
+++ b/Modules/CMakeISPCCompilerABI.ispc
@@ -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
+
+}
diff --git a/Modules/CMakeISPCCompilerId.ispc.in b/Modules/CMakeISPCCompilerId.ispc.in
new file mode 100644
index 0000000..03380f3
--- /dev/null
+++ b/Modules/CMakeISPCCompilerId.ispc.in
@@ -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
+
+}
diff --git a/Modules/CMakeISPCInformation.cmake b/Modules/CMakeISPCInformation.cmake
new file mode 100644
index 0000000..514036e
--- /dev/null
+++ b/Modules/CMakeISPCInformation.cmake
@@ -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)
diff --git a/Modules/CMakeTestISPCCompiler.cmake b/Modules/CMakeTestISPCCompiler.cmake
new file mode 100644
index 0000000..6b16393
--- /dev/null
+++ b/Modules/CMakeTestISPCCompiler.cmake
@@ -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})
diff --git a/Modules/Compiler/Intel-ISPC.cmake b/Modules/Compiler/Intel-ISPC.cmake
new file mode 100644
index 0000000..2e9792a
--- /dev/null
+++ b/Modules/Compiler/Intel-ISPC.cmake
@@ -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)
diff --git a/Modules/Platform/Windows-Intel-ISPC.cmake b/Modules/Platform/Windows-Intel-ISPC.cmake
new file mode 100644
index 0000000..cd26302
--- /dev/null
+++ b/Modules/Platform/Windows-Intel-ISPC.cmake
@@ -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> ")
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 63c1484..b9b91f6 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -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]);
}
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index fdc8f29..83e9aac 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -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
{
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7c526a0..dc5265f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -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);
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 544b27a..246eede 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -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;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index a192ffd..a550b50 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -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());
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index f0fa1f4..ed61021 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -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());
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 10f5cf6..0881ce0 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -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();
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 40010fc..300bb26 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -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 =
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 0c51a65..cf2bce1 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -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,
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 8acd1e3..26b0989 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -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);
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index fae1d76..afbbbd4 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -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,
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 57f526e..96e0c69 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -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 {
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 4ff81c1..6f40ec6 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -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;
}
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 09e8a3b..96e731f 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -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
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index bea9001..a30c9e9 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -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");
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index f630a7e..1bee728 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -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;
}
diff --git a/Source/cmake.h b/Source/cmake.h
index 0c4f429..06ab8ac 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -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;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 5d4ffae..95162ec 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -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)
diff --git a/Tests/ISPC/CMakeLists.txt b/Tests/ISPC/CMakeLists.txt
new file mode 100644
index 0000000..ca5a79b
--- /dev/null
+++ b/Tests/ISPC/CMakeLists.txt
@@ -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)
diff --git a/Tests/ISPC/Defines/CMakeLists.txt b/Tests/ISPC/Defines/CMakeLists.txt
new file mode 100644
index 0000000..5155106
--- /dev/null
+++ b/Tests/ISPC/Defines/CMakeLists.txt
@@ -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()
diff --git a/Tests/ISPC/Defines/main.cxx b/Tests/ISPC/Defines/main.cxx
new file mode 100644
index 0000000..4f1c9be
--- /dev/null
+++ b/Tests/ISPC/Defines/main.cxx
@@ -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]);
+}
diff --git a/Tests/ISPC/Defines/simple.ispc b/Tests/ISPC/Defines/simple.ispc
new file mode 100644
index 0000000..d8d6465
--- /dev/null
+++ b/Tests/ISPC/Defines/simple.ispc
@@ -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;
+ }
+}
diff --git a/Tests/ISPC/ObjectLibrary/CMakeLists.txt b/Tests/ISPC/ObjectLibrary/CMakeLists.txt
new file mode 100644
index 0000000..333ad66
--- /dev/null
+++ b/Tests/ISPC/ObjectLibrary/CMakeLists.txt
@@ -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)
diff --git a/Tests/ISPC/ObjectLibrary/extra.cxx b/Tests/ISPC/ObjectLibrary/extra.cxx
new file mode 100644
index 0000000..88ef3a7
--- /dev/null
+++ b/Tests/ISPC/ObjectLibrary/extra.cxx
@@ -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;
+}
diff --git a/Tests/ISPC/ObjectLibrary/extra.ispc b/Tests/ISPC/ObjectLibrary/extra.ispc
new file mode 100644
index 0000000..5a4a442
--- /dev/null
+++ b/Tests/ISPC/ObjectLibrary/extra.ispc
@@ -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;
+ }
+}
diff --git a/Tests/ISPC/ObjectLibrary/main.cxx b/Tests/ISPC/ObjectLibrary/main.cxx
new file mode 100644
index 0000000..4f1c9be
--- /dev/null
+++ b/Tests/ISPC/ObjectLibrary/main.cxx
@@ -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]);
+}
diff --git a/Tests/ISPC/ObjectLibrary/simple.ispc b/Tests/ISPC/ObjectLibrary/simple.ispc
new file mode 100644
index 0000000..70cb588
--- /dev/null
+++ b/Tests/ISPC/ObjectLibrary/simple.ispc
@@ -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;
+ }
+}
diff --git a/Tests/ISPC/ResponseAndDefine/CMakeLists.txt b/Tests/ISPC/ResponseAndDefine/CMakeLists.txt
new file mode 100644
index 0000000..7539209
--- /dev/null
+++ b/Tests/ISPC/ResponseAndDefine/CMakeLists.txt
@@ -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>")
diff --git a/Tests/ISPC/ResponseAndDefine/main.cxx b/Tests/ISPC/ResponseAndDefine/main.cxx
new file mode 100644
index 0000000..4f1c9be
--- /dev/null
+++ b/Tests/ISPC/ResponseAndDefine/main.cxx
@@ -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]);
+}
diff --git a/Tests/ISPC/ResponseAndDefine/simple.ispc b/Tests/ISPC/ResponseAndDefine/simple.ispc
new file mode 100644
index 0000000..81fd7ca
--- /dev/null
+++ b/Tests/ISPC/ResponseAndDefine/simple.ispc
@@ -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;
+ }
+}
diff --git a/Tests/ISPC/StaticLibrary/CMakeLists.txt b/Tests/ISPC/StaticLibrary/CMakeLists.txt
new file mode 100644
index 0000000..ebe5960
--- /dev/null
+++ b/Tests/ISPC/StaticLibrary/CMakeLists.txt
@@ -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)
diff --git a/Tests/ISPC/StaticLibrary/main.cxx b/Tests/ISPC/StaticLibrary/main.cxx
new file mode 100644
index 0000000..4f1c9be
--- /dev/null
+++ b/Tests/ISPC/StaticLibrary/main.cxx
@@ -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]);
+}
diff --git a/Tests/ISPC/StaticLibrary/simple.ispc b/Tests/ISPC/StaticLibrary/simple.ispc
new file mode 100644
index 0000000..70cb588
--- /dev/null
+++ b/Tests/ISPC/StaticLibrary/simple.ispc
@@ -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;
+ }
+}
diff --git a/Tests/ISPC/TryCompile/CMakeLists.txt b/Tests/ISPC/TryCompile/CMakeLists.txt
new file mode 100644
index 0000000..742f511
--- /dev/null
+++ b/Tests/ISPC/TryCompile/CMakeLists.txt
@@ -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")
diff --git a/Tests/ISPC/TryCompile/main.cxx b/Tests/ISPC/TryCompile/main.cxx
new file mode 100644
index 0000000..c8d1ed6
--- /dev/null
+++ b/Tests/ISPC/TryCompile/main.cxx
@@ -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]);
+}
diff --git a/Tests/ISPC/TryCompile/simple.ispc b/Tests/ISPC/TryCompile/simple.ispc
new file mode 100644
index 0000000..70cb588
--- /dev/null
+++ b/Tests/ISPC/TryCompile/simple.ispc
@@ -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;
+ }
+}