Jeder der das erste mal versucht in einem OpenCL-Kernel eine Headerdatei mit #include "header.h" einzubinden scheitert für gewöhnlich mit einer Fehlermeldung im Stiele von catastrophic error: cannot open source file "header.h". Grund ist, dass der Compiler normalerweise nicht im Quellverzeichnis nach der Headerdatei sucht. Man muss dem Befehl clBuildProgram explizit den Pfad per Compileroption -I /pfad/zu/den/headern/ übergeben.

Beim Implementieren der Parameterübergabe an clBuildProgram fällt schnell auf, wieso er den Pfad nicht von alleine kennt. Ein "-I ." funktioniert nämlich spätestens dann nicht mehr, wenn man das Programm nicht im Quellverzeichnis ausführt. Man benötigt also eine Konstante mit welcher man sich den korrekten Parameter zusammenbauen kann. Dies sieht dann zum Beispiel so aus:

char compiler_options[256];
sprintf( compiler_options, "-I \"%s\"", SOURCE_DIRECTORY );
err = clBuildProgram( program, 0, NULL, compiler_options, NULL, NULL);
Hier ist es wichtig, dass compiler_options groß genug ist um mit jedem möglicherweise übergebenen Pfad zu funktionieren!

Um den Code in unterschiedlichen Verzeichnissen übersetzen zu können definiert man diese Konstante am besten außerhalb und übergibt sie zur Compilezeit:

gcc -DSOURCE_DIRECTORY="$(pwd)" -o headerTest headerTest.c
Nutzt man CMake so reicht es in der CMakeList.txt die folgende Zeile hinzuzufügen:
add_definitions( -DSOURCE_DIRECTORY="${CMAKE_SOURCE_DIR}" )

So weit, so schön die Theorie. Leider scheitern die Implementierungen von Apple und NVIDIA an Leerzeichen im Pfad. Da sie die Gänsefüßchen als normale Zeichen interpretieren scheitern sie mit dem angegebenen Aufruf also auch an Pfaden ohne Leerzeichen. Ein korrekter Aufruf verzichtet also auf sie, kann dann aber nicht mehr mit Leerzeichen umgehen.

char compiler_options[256];
sprintf( compiler_options, "-I %s", SOURCE_DIRECTORY );
err = clBuildProgram( program, 0, NULL, compiler_options, NULL, NULL);