Creating ComputeCpp (SYCL) projects with CMake
This guide aims to provide step-by-step instructions on setting up a basic SYCL project using CMake. CMake should work on the most common operating systems and generate project files for whichever IDE the user chooses to use. SYCL knowledge is only required in order to test the build system. Resources to help write a simple SYCL program will follow in the next section.
Step 1. Setting up
In order to follow along, the reader must download the following prerequisites:
-
A C++ compiler such as GCC, Microsoft Visual C++, or Clang.
-
CMake (3.4.3 or newer) (Make sure to add it to
PATH
when installing for easy use in the terminal). -
ComputeCpp (any version) is a SYCL implementation which will be used to compile SYCL source files. (A simple registration is required to download the latest Community Edition installer for free. On Windows, extract and run the installer which will install ComputeCpp).
-
OpenCL (latest version) (Get Intel® SDK for OpenCL™ Applications for the desired operating system. This will also require quickly creating an account to access the download link. Once the installer has finished, a computer restart may be required for OpenCL to be detected properly. This step may be skipped by users with CUDA installed as it includes OpenCL).
Step 2. Creating a basic CMake project
Navigate into the root directory containing the C++ project and create a file called CMakeLists.txt
. This file will be recognized by CMake as the entry point to the CMake project and will contain important information about how the project needs to be linked. Once this file is created, open it in a text editor and we will begin writing some CMake code.
First the user must declare the minimum version of CMake required for the project, in this particular case we will use 3.4.3 which is the minimum version that ComputeCpp supports.
cmake_minimum_required(VERSION 3.4.3)
Next the user must give the CMake project a name, such as
project(test_application)
Every C++ project consists of source (.cpp
) files used for generating object files that allow the compiler to create the executable / library file for an application. These source files need to be linked to the executable which is often done by creating a CMake variable which contains a list of paths to all the source files in the project relative to the CMakeLists.txt
file's root directory. For example:
set(SRC_FILES
"src/main.cpp"
"src/program.cpp")
Where SRC_FILES
will be the name of a variable which will encompass the main.cpp
and program.cpp
source files.
The same can be done for SYCL source files (.cpp
files containing SYCL code) and regular C++ header files.
set(SYCL_FILES
"src/main.cpp")
set(HEADER_FILES
"src/program.h")
While not required, creating variables to represent groups of files makes the CMake file easier to read and may avoid repetition in the future.
After this, we must inform CMake where it can find what is called a Find-module
package file for ComputeCpp. In essence, this is a CMake file which handles configuring variables and creating functions to simplify interaction with an external library. Usually, these files are placed in a folder called cmake
in the root of the project (where the CMakeLists.txt
is located). ComputeCpp provides such a file here to simplify the build process (right click anywhere on the page and save the file as a .cmake
file into a known directory). The following line will let CMake know the directory of this file:
list(APPEND CMAKE_MODULE_PATH
"${CMAKE_SOURCE_DIR}/cmake/")
Where CMAKE_SOURCE_DIR
is an intrinsic variable which points to the root directory of the CMake project (the location of the CMakeLists.txt
file). CMAKE_MODULE_PATH
is a variable which contains a list of paths that CMake will check for FindNameOfPackage.cmake
files.
In order to use ComputeCpp, the user must provide CMake with a variable called ComputeCpp_DIR
corresponding to the location of the ComputeCpp installation (usually something like C:/Program Files/Codeplay/ComputeCpp
on Windows). This variable is often provided to CMake as an argument in the terminal with the -D
flag
cmake .. -DComputeCpp_DIR="C:/Program Files/Codeplay/ComputeCpp"
However, this can get tedious to write out each time. In order to avoid having to retype this, the user can specify
set(ComputeCpp_DIR CACHE STRING "NOT-FOUND")
Within their CMake project to cache the variable between running CMake. If the path changes simply set the -DComputeCpp_DIR
flag again.
Optionally, it is useful to add a warning for the user if the variable is not defined, something such as
if (NOT ComputeCpp_DIR)
message(FATAL_ERROR "SYCL implementation root not provided, please specify "
"the path to the root of the chosen SYCL implementation using "
"ComputeCpp_DIR=<path/to/install/root>.")
endif()
Now the user will be able to add
find_package(ComputeCpp REQUIRED)
And CMake will automatically run the FindComputeCpp.cmake
file to create some functions and variables for easily linking ComputeCpp to the project.
The user can generate a C++ executable for their source files using
add_executable(${PROJECT_NAME} ${SRC_FILES} ${HEADER_FILES})
where PROJECT_NAME
is simply a CMake intrinsic variable containing the project name defined at the very beginning.
Now that the executable (also known as a target in CMake) has been created, the user must specify the include directories for the target with
target_include_directories(${PROJECT_NAME} PRIVATE
"${ComputeCpp_INCLUDE_DIRS}"
"${CMAKE_SOURCE_DIR}/src")
This informs CMake that the directories defined in the ComputeCpp_INCLUDE_DIRS
variable, which was generated by FindComputeCpp.cmake
, should be included in the project, alongside any files in the source directory.
Lastly, we must inform the executable which of the source files will contain SYCL code as the SYCL implementation will generate .sycl files for each of them. This can be done using the add_sycl_to_target
function which was defined by the FindComputeCpp.cmake
file. If, for example, main.cpp is the only file with SYCL code in it, the following CMake code can be added after creating the executable
add_sycl_to_target(TARGET ${PROJECT_NAME}
SOURCES "src/main.cpp")
Which will link SYCL to the desired target with the desired source files.
Once complete, the CMakeLists.txt
file should look something like this.
Step 3. Generating project files
It is highly advisable that before attempting to generate build files for their C++ compiler, the user first creates a build directory in the root of their project. This makes it easier to clean the project and keep the built binaries separate. First open the terminal in (or navigate into) the project’s root directory and call
mkdir build
which will create a directory called build. Afterward, the user should navigate into this directory using
cd build
and finally call CMake to generate the build files in the build directory using (replacing the path with the location of their ComputeCpp installation)
cmake .. -DComputeCpp_DIR="C:/Program Files/Codeplay/ComputeCpp"
The two dots simply tell CMake that the location of the CMakeLists.txt
file is in the outer directory and -D
is a CMake flag for defining variables in the terminal. This should produce some terminal messages and generate build / project files for the appropriate user installed compiler automatically in the build directory. Note that if using an NVIDIA GPU, PTX instructions are required, and the user should add -DCOMPUTECPP_BITCODE=ptx64
to the end of the above CMake command.
Here is a link to a repository containing a basic SYCL project template following along this guide.
The next section will cover how to write a basic "Hello World!" application using SYCL.