CMake OpenCL: can't read kernel file - c++

I'm trying to load an external OpenCL kernel and the clCreateKernel returns an error code: -46 CL_INVALID_KERNEL_NAME. The file structure is the following:
.
├── CMakeLists.txt
└── src
├── cl.hpp
├── GameOfLife.cpp
└── kernels
└── programs.cl
This is my first CMake project, thus I'm not sure the following CMake is correct:
cmake_minimum_required(VERSION 3.5)
project(gpgpu_gameoflife)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lOpenCL")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR}/src/kernels)
# source: http://igorbarbosa.com/articles/how-to-use-opengl-freeglut-and-cmake/
#########################################################
# FIND GLUT
#########################################################
find_package(GLUT REQUIRED)
include_directories(${GLUT_INCLUDE_DIRS})
link_directories(${GLUT_LIBRARY_DIRS})
add_definitions(${GLUT_DEFINITIONS})
if(NOT GLUT_FOUND)
message(ERROR " GLUT not found!")
endif(NOT GLUT_FOUND)
#########################################################
# FIND OPENGL
#########################################################
find_package(OpenGL REQUIRED)
include_directories(${OpenGL_INCLUDE_DIRS})
link_directories(${OpenGL_LIBRARY_DIRS})
add_definitions(${OpenGL_DEFINITIONS})
if(NOT OPENGL_FOUND)
message(ERROR " OPENGL not found!")
endif(NOT OPENGL_FOUND)
set(SOURCE_FILES
src/GameOfLife.cpp
src/kernels/programs.cl
)
add_executable(gpgpu_gameoflife ${SOURCE_FILES})
target_link_libraries(gpgpu_gameoflife ${OPENGL_LIBRARIES} ${GLUT_LIBRARY})
For the following function call I get an empty string as a result, thus I think the kernel file is not available to be read (the kernel itself is not empty).
std::string sourceCode = fileToString("kernels/programs.cl");
...
std::string fileToString(const std::string &path) {
std::ifstream file(path, std::ios::in | std::ios::binary);
if (file) {
std::ostringstream contents;
contents << file.rdbuf();
file.close();
return (contents.str());
}
return "";
}
Could you please tell me how to create an OpenCL application using CMake that loads an external kernel? Or is this not a good practice?
Thank you!

Although the following line in CMake solves my problem, I'm still waiting for other answers maybe containing a better solution.
configure_file(src/kernels/programs.cl kernels/programs.cl COPYONLY)

you should update your path depending from where you build your program
If your project looks like this:
── CMakeLists.txt
└── src
| ├── cl.hpp
| ├── GameOfLife.cpp
| └── kernels
| └── programs.cl
└── build
and you call "make" from the build directory, the string path should look like this: "../src/kernels/programs.cl". Alternatively you can set a CMake variable with "set(PATH_TO_FILE "${CMAKE_SOURCE_DIR}/src/kernels/programs.cl") and pass it to the main args

Related

'torch/torch.h' file not found in header file

I'm new in Linux C++ programming. I have to use libtorch (pytorch C++ version), but I kept struggling with C++ and cmake problems. These problems really make me mad, and I need some help.
Here is a simple C++ project:
.
├── build.sh
├── CMakeLists.txt
├── load_data
│   ├── CMakeLists.txt
│   ├── include
│   │   └── load_data
│   │   └── load_data.hpp
│   └── src
│   └── load_data.cpp
└── src
└── main.cpp
But I can't build it because load_data/include/load_data/load_data.hpp cannot #include <torch/torch.h>.
The build error message:
[build] /my/path/load_data/include/load_data/load_data.hpp:4:10: fatal error: 'torch/torch.h' file not found
[build] #include <torch/torch.h>
[build] ^~~~~~~~~~~~~~~
However, if I move the #include <torch/torch.h> from the header file to the corresponding source file, the error message goes away. It makes me confused.
Files' contents:
load_data/include/load_data/load_data.hpp
#pragma once
#include <torch/torch.h>
namespace load_data
{
void try_torch();
// torch::Tensor rand_tensor();
}
load_data/src/load_data.cpp
# include "load_data/load_data.hpp"
// If I remove it from load_data.hpp and use it here, the error goes away.
// #include <torch/torch.h>
namespace load_data {
void try_torch(){
torch::Tensor tensor = torch::rand({2, 3});
std::cout << tensor << std::endl;
}
}
src/main.cpp
#include <string>
#include "load_data/load_data.hpp"
int main(int argc, char **argv)
{
load_data::try_torch();
return 0;
}
CMakeLists.txt
cmake_minimum_required (VERSION 3.21)
set(CMAKE_CXX_COMPILER clang++-13)
project(ldt-cpp-experiments VERSION 1.0.0 LANGUAGES CXX)
find_package(Torch REQUIRED)
message(STATUS "Torch_FOUND: ${Torch_FOUND}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_subdirectory("load_data")
set(EXECUTABLE_NAME main)
add_executable(${EXECUTABLE_NAME} src/main.cpp)
target_link_libraries(${EXECUTABLE_NAME}
PRIVATE load_data
)
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
)
load_data/CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project (load_data VERSION 1.0.0 LANGUAGES CXX)
find_package(Torch REQUIRED)
message(STATUS "Torch_FOUND: ${Torch_FOUND}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
set(LIB_NAME "load_data")
add_library(${LIB_NAME}
SHARED
)
target_sources(${LIB_NAME}
PRIVATE
${PROJECT_SOURCE_DIR}/src/load_data.cpp
)
target_sources(${LIB_NAME}
PRIVATE
${PROJECT_SOURCE_DIR}/src/load_data.cpp
${PROJECT_SOURCE_DIR}/include/load_data/load_data.hpp
)
target_include_directories(${LIB_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
target_link_libraries(${LIB_NAME}
PRIVATE
${TORCH_LIBRARIES}
)
set_target_properties(${LIB_NAME} PROPERTIES
CXX_STANDARD 20
CXX_STANDARD_REQUIRED YES
)
build.sh
cmake -S . -B build

How do you add external libraries to 'self-made' libraries using CMake?

I'm not able to link external libraries with the libraries I wrote using CMake. I'm wondering if there's something that is needed to be added to my CMakeLists.txt? Or if I need to add another CMakeLists.txt in a lower level (inside src) and what would that need to contain?
I have the following project structure:
ProjectFolder
│   ├── CMakeLists.txt
│   ├── build
│   │   └──
│   ├── include
│   │   └── helper.h
│   └── src
│   ├── helper.cpp
   └── main.cpp
My CMakeList.txt is:
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(object_detection)
find_package(PCL 1.5 REQUIRED)
find_package(OpenCV REQUIRED)
file(GLOB SOURCES src/*.cpp)
file(GLOB INCLUDE include/*.h)
include_directories(${PCL_INCLUDE_DIRS} ${INCLUDE})
link_directories(${PROJECT_NAME} ${PCL_LIBRARY_DIRS} ${SOURCES} )
add_definitions(${PCL_DEFINITIONS})
add_executable (${PROJECT_NAME} src/main.cpp)
target_link_libraries (${PROJECT_NAME} ${OpenCV_LIBS} ${PCL_LIBRARIES} ${SOURCES})
In my file helper.cpp I have:
#include <pcl/io/pcd_io.h>
Which gives the error:
fatal error: 'pcl/io/pcd_io.h' file not found
#include <pcl/io/pcd_io.h>
^~~~~~~~~~~~~~~~~
However I have the same include in main.cpp with no errors.
I would be very grateful for any help, please let me know if I need to clarify my question or error.
Thank you.
There are several errors in the CMakeLists.txt with the following changes the project loads appropriate libraries and builds properly. Another note is that before, to include helper.h I needed to write:
#include "../include/helper.h".
Now it works as expected with #include "helper.h".
Here is the modified CMakeLists.txt:
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(object_detection)
find_package(PCL 1.5 REQUIRED)
find_package(OpenCV REQUIRED)
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.cpp)
include_directories(${PCL_INCLUDE_DIRS} include)
link_directories(${PROJECT_NAME} ${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
#add_executable (${PROJECT_NAME} src/helper.cpp src/main.cpp )
add_executable (${PROJECT_NAME} ${SRC_FILES} )
target_link_libraries (object_detection ${PCL_LIBRARIES} ${OpenCV_LIBS})

CMake building library and executable once and linking it

I'm trying to build two projects using cmake at same-time.
My folder structure is as follows:
project
├── CMakeLists.txt
├── build
├── out
├── lib
├── yanthra_engine
│  ├── CMakeLists.txt
│   └── ...
└───sandbox
├── CMakeLists.txt
└── ...
main CmakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
project(yanthra_console VERSION 0.1 DESCRIPTION "A 3d Game Engine.")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -fexceptions")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING "Build type selections" FORCE)
add_subdirectory(yanthra_engine)
add_subdirectory(sandbox)
yanthra_engine/CMakeLists.txt
set(THIRD_PARTY_DIR "../../../third-party")
set(MAIN_SOURCE_DIR "../../main/src")
include_directories(${THIRD_PARTY_DIR}/SDL/include)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib )
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
file(GLOB_RECURSE CPP_HEADERS ${MAIN_SOURCE_DIR}/*.hpp)
file(GLOB_RECURSE CPP_SOURCES ${MAIN_SOURCE_DIR}/*.cpp)
add_library(
yanthra
SHARED
${CPP_HEADERS}
${CPP_SOURCES}
)
set (CMAKE_SHARED_LINKER_FLAGS "-F../yanthra_engine/Frameworks -framework SDL2 -framework OpenGL")
sandbox/CMakeLists.txt
set(THIRD_PARTY_DIR "../../main")
set(MAIN_SOURCE_DIR "./src")
include_directories(${THIRD_PARTY_DIR}/include)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../out)
file(GLOB_RECURSE CPP_HEADERS ${MAIN_SOURCE_DIR}/includes/*.h)
file(GLOB_RECURSE CPP_SOURCES ${MAIN_SOURCE_DIR}/*.cpp)
file(GLOB_RECURSE LIB ${MAIN_SOURCE_DIR}/../lib/*.dylib)
add_executable(
yanthra_sandbox
${CPP_HEADERS}
${CPP_SOURCES}
)
set_target_properties(
yanthra_sandbox
PROPERTIES
LINK_FLAGS
"-F../yanthra_engine/Frameworks -framework SDL2 -framework OpenGL"
)
target_link_libraries(yanthra_sandbox PRIVATE ${LIB})
I would like to know if I'm generating library file in each build mode, how will I link it with it's corresponding executable, given the fact that each mode builds its output to to its own folder i.e for library its lib/Debug (for debug mode) and for executable its out/Debug.
You don't seem to link the link the yanthra target. You should do this though, since this will automatically choose the library compiled with the current configuration.
sandbox/CMakeLists.txt
...
target_link_libraries(yanthra_sandbox PRIVATE yanthra ${LIB})
...
As for importing the other libs: It would be preferrable to use find_library. This should automatically set the link options and make adding them for yanthra_sandbox unnecessary.
yanthra_engine/CMakeLists.txt
...
list(APPEND CMAKE_FRAMEWORK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Frameworks")
find_library(SDL2_LIB SDL2 REQUIRED)
find_library(OPEN_GL_LIB OpenGL REQUIRED)
target_link_library(yanthra PUBLIC "${SDL2_LIB}" "${OPEN_GL_LIB}")
This should allow you to remove the compiler flags from both targets. If there are no dependencies in the lib directory you could also remove the search for the libraries on the file system/

ifstream not reading anything

I'm writing code in C++ and I need to read a file, problem is my file structure is a bit complex and I just cannot figure out how to use my ifstream to read it. I think I tried all possible combinations... but it just doesn't work, I guess I'm doing something wrong but I can't figure it out.
Here is a minimal reproduction of my problem.
structure :
.
├── build
├── CMakeLists.txt
└── src
├── file
│   └── test.txt
├── load
│   └── loadfile.hpp
└── main.cpp
CMakeLists.txt :
cmake_minimum_required(VERSION 3.10)
project(BaseProject)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-O3 -g -std=c++17 -Wall -Wextra -pedantic")
file(GLOB SRC
"src/*.h"
"src/*.hpp"
"src/load/*.h"
"src/load/*.hpp"
"src/load/*.cpp"
)
add_executable(exec ${SRC} src/main.cpp)
main.cpp
#include "load/loadfile.hpp"
int main(){
load();
return 0;
}
test.txt : (not very relevent but meh)
test
loadfile.hpp
#include <fstream>
#include <string>
#include <iostream>
void loadFile(const std::string& file){
std::ifstream i(file, std::ifstream::in);
std::string str;
i >> str;
std::cerr << str;
i.close();
}
void load(){
loadFile("../file/test.txt");
}
output is empty and program finishes normally.
This might help, when you call install your files will be copied to destination specified.
cmake_minimum_required(VERSION 3.10)
project(BaseProject)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "-O3 -g -std=c++17 -Wall -Wextra -pedantic")
set(OUTPUT_DIR "Yours to fill, working dir")
file(GLOB RESOURCES "./file/test.txt")
file(GLOB SRC
"src/*.h"
"src/*.hpp"
"src/load/*.h"
"src/load/*.hpp"
"src/load/*.cpp"
)
add_executable(exec ${SRC} src/main.cpp)
install (FILES ${RESOURCES} DESTINATION ${OUTPUT_DIR})
Answer from Some programmer dude in the comments:
Now might be a good time to learn about the concept of current working
directory. When you run a program, its process will have a current
working directory. If you run from a console or terminal then it's
usually the terminals current directory. Relative paths (paths not
beginning with a /) are always relative to the current working
directory. You need to make sure that the relative path in the program
is valid for the programs current working directory when running.

CMake + Qt + GTest files linking

I have a simple CMake + Qt + GTest project:
.
├── CMakeLists.txt
├── src
│   ├── CMakeLists.txt
│   ├── main.cpp
│   └── utils
│   ├── calculator.cpp
│   └── calculator.h
└── tests
├── calculator_test.cpp
└── CMakeLists.txt
Root CMakeFiles.txt
cmake_minimum_required(VERSION 3.5)
project(random_project)
# Place binaries and libraries according to GNU standards.
include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
# Add source folder.
add_subdirectory(src)
# Add GTest.
include(cmake/googletest.cmake)
fetch_googletest(
${PROJECT_SOURCE_DIR}/cmake
${PROJECT_BINARY_DIR}/googletest
)
enable_testing()
# Add tests folder.
add_subdirectory(tests)
And I want to reach calculator.h in calculator_test.cpp which uses GTest:
#include <gtest/gtest.h>
#include "utils/calculator.h" // <- Want to reach this in that path format.
TEST(example, add)
{
EXPECT_EQ(8, Calculator::sum(3, 5));
}
I have tried to link but then test is not found and the path is releative:
tests/CMakeFiles.txt
# Find the Qt libraries.
find_package(Qt5Widgets REQUIRED)
# Qt5 libraries.
set(QT5_LIBRARIES
Qt5::Widgets)
# Source files.
set(SOURCE_FILES
calculator_test.cpp
../src/utils/calculator.cpp
../src/utils/calculator.h
../src/main.cpp) # If I link like this, test is not found.
# Tell CMake to create the executable.
add_executable(unit_tests ${SOURCE_FILES})
# Use the Widgets module from Qt5.
target_link_libraries(unit_tests ${QT5_LIBRARIES} gtest_main)
# Add tests.
add_test(
NAME unit_tests
COMMAND ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/unit_tests
)
How to link calculator.h in calculator_test.cpp test with CMakeLists.txt?
My Qt project with CMake project file cannot resolve the path to
"someHeader.h". What can I do to fix it?
You can specify the include path:
include_directories("${PROJECT_SOURCE_DIR}/relativePathToHeader")
and likely the path needed:
include_directories("${PROJECT_SOURCE_DIR}/src/utils") or maybe
include_directories("${PROJECT_SOURCE_DIR}/utils") depending on where the source directory actually is.
You need to re-run CMake, of course.