## Learning Objectives
* Learn how CMake 4.5 treats SYCL as a language
* Learn how to build a SYCL hello world with a `FILE_SET`
* Learn how to pick a SYCL compiler and pass SYCL-only flags
#### Before CMake 4.5
* Each implementation shipped its own CMake integration:
* DPC++: `find_package(IntelSYCL)` + `add_sycl_to_target(...)`
* AdaptiveCpp: `find_package(AdaptiveCpp)` + `add_sycl_to_target(...)`
* or `-fsycl` added by hand to `CMAKE_CXX_FLAGS`
* Every C++ file in the project was then compiled as SYCL, even
files with no kernels
#### SYCL is a CMake language
* Since CMake 4.5, SYCL is a language like `CXX`, `CUDA` or `HIP`
* CMake finds `icpx` / `acpp` and adds `-fsycl` for you
* Use `CMAKE_SYCL_COMPILER` and `CMAKE_SYCL_FLAGS`, the same way you
use `CMAKE_CXX_COMPILER` and `CMAKE_CXX_FLAGS`
* The feature is still experimental: you opt in with a UUID before
`project()`
#### Hello world: one SYCL file, one C++ file
`main.cpp` (SYCL)
#include <cassert>
#include <cstdio>
#include <sycl/sycl.hpp>
int answer(); // defined in answer.cpp
int main() {
sycl::queue q;
int* x = sycl::malloc_shared<int>(1, q);
q.single_task([=] { *x = 42; }).wait();
assert(*x == answer());
std::printf("x = %d\n", *x);
sycl::free(x, q);
}
`answer.cpp` (plain C++)
int answer() { return 42; }
* Only `main.cpp` has a kernel, so only `main.cpp` needs the SYCL compiler
#### Hello world: CMakeLists.txt
```cmake
cmake_minimum_required(VERSION 4.5)
set(CMAKE_EXPERIMENTAL_SYCL "c0d1fb10-2ece-420e-9d29-7d7f2b300f25")
project(hello LANGUAGES CXX SYCL)
add_executable(hello)
target_sources(hello PRIVATE FILE_SET SYCL FILES main.cpp)
target_sources(hello PRIVATE answer.cpp) # plain C++
```
* `LANGUAGES CXX SYCL`: enable SYCL next to C++
* `FILE_SET SYCL`: compile `main.cpp` as SYCL, even though it is a `.cpp` file
* `answer.cpp` is outside the set: it stays plain C++
* Files with the `.sycl` extension are compiled as SYCL automatically
#### Build and run
For example, with `icpx` the build looks something like:
```sh
$ cmake -B build
-- The CXX compiler identification is IntelLLVM 2026.1.0
-- The SYCL compiler identification is IntelLLVM 2026.1.0
$ cmake --build build -v
icpx -o answer.cpp.o -c answer.cpp # note: no -fsycl
icpx -fsycl -x c++ -fno-gpu-rdc -o main.cpp.o -c main.cpp
icpx -fsycl answer.cpp.o main.cpp.o -o hello -lsycl -lsycl-devicelib-host
$ ./build/hello
x = 42
```
* `answer.cpp` is compiled **without** `-fsycl`
* SYCL compilation does extra work compared to pure C++, so it is slower:
only the files in the SYCL set pay that cost
#### Compiler and flags
```sh
$ cmake -B build -DCMAKE_SYCL_FLAGS=-fsycl-targets=spir64
$ cmake --build build -v
icpx -o answer.cpp.o -c answer.cpp
icpx -fsycl -fsycl-targets=spir64 -x c++ -fno-gpu-rdc -o main.cpp.o -c main.cpp
```
* Pick a compiler: `-DCMAKE_SYCL_COMPILER=icpx`
* `CMAKE_SYCL_FLAGS` only reaches SYCL sources, not plain C++ files