How to use CMake to compile *.cpp and *.cu seperately? - c++

I want to implement a Matrix class, and I want to use CUDA to speed up matrix multiplication. But when I try to compile the source files. I meet some problems. I know that I need to use NVCC to compile the *.cu. But I don't know how to write the CMakeLists.txt to compile the *.cu and *.cpp at the same time. I've tried many ways I found on Google, but they all don't work. Here is my current CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(Project_4 LANGUAGES CXX CUDA)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CUDA_STANDARD 14)
set(CMAKE_BUILD_TYPE RELEASE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build)
find_package(CUDA REQUIRED)
include(FindCUDA)
include_directories(${CUDA_INCLUDE_DIRS})
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -gencode arch=compute_30,code=sm_30)
include_directories(include)
aux_source_directory(src DIR_SRCS)
file(GLOB cu *.cu)
cuda_add_executable(cuda ${DIR_SRCS} ${cu})
add_executable(Project_4 ${DIR_SRCS})
set_target_properties(Project_4 PROPERTIES
CUDA_SEPARABLE_COMPILATION ON)
Then when compiling, it will report that CMake Error at cuda_generated_ cuda_helper.cu.o.RELEASE.cmake:282. And if I write CMakeLists.txt in this way:
cmake_minimum_required(VERSION 3.16)
project(Project_4 LANGUAGES CXX CUDA)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CUDA_STANDARD 14)
set(CMAKE_BUILD_TYPE RELEASE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build)
include_directories(include)
aux_source_directory(src DIR_SRCS)
find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -gencode arch=compute_30,code=sm_30)
add_executable(Project_4 ${DIR_SRCS})
set_target_properties(Project_4 PROPERTIES
CUDA_SEPARABLE_COMPILATION ON)
Then it will report error error: expected primary-expression before "<" token at where I call the kernel function.
I am searching for a long time on net. But no use. Please help or try to give some ideas how to achieve this. I will appreciate a lot. Thanks.

I created an example for you. It is not based on your cmake. But it works for me maybe it helps you.
clone repo: git clone -b cmake_cuda_example https://github.com/werto87/durak_computer_controlled_opponent.git
install: conan dependency manager
Install: cuda toolkit
create an empty folder called build inside the "durak_computer_controlled_opponent" folder
go inside this folder and inside the terminal run "conan install .. --build missing"
cmake ..
cmake --build .

Related

mingw-g++ can't find include directory

I'm trying to compile my program for Windows, on Linux, so I installed the w64-mingw32 compiler via the Debian package manager. I made a separate cmakelists file where I chose x86_64-w64-mingw32-g++ as the compiler. When I try to run my build script, I get errors where it can't find the libraries that I use in my project. This is my cmake file:
cmake_minimum_required (VERSION 3.5)
if (POLICY CMP0072)
cmake_policy(SET CMP0072 NEW)
else (NOT POLICY CMP0072)
message(STATUS "Could not use CMP0072 policy")
endif(POLICY CMP0072)
project(opengl-test LANGUAGES CXX)
set(CMAKE_CXX_COMPILER "/usr/bin/x86_64-w64-mingw32-g++")
set(CMAKE_C_COMPILER "/usr/bin/x86_64-w64-mingw32-gcc")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(GNUInstallDirs)
set(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32")
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set (source_dir "${PROJECT_SOURCE_DIR}/src/")
set (base_dir "${source_dir}/base/")
set (IMGUI_DIR "/usr/include/imgui")
set(GCC_COVERAGE_LINK_FLAGS "")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
file(GLOB source_files "${source_dir}/*.cpp")
file(GLOB_RECURSE base_files "${base_dir}/*.cpp")
file(GLOB imgui_files "${IMGUI_DIR}/*.cpp")
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
add_executable(${PROJECT_NAME} ${source_files} ${imgui_files} ${base_files})
#target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
message(STATUS ${OPENGL_LIBRARIES})
target_link_libraries(${PROJECT_NAME} PUBLIC ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES} ${GLEW_LIBRARIES})
A lot of the code in the cmakelists file doesn't do anything because I was trying to make it work but nothing was working. I left it in so you can see what I've tried and doesn't work.
I can run this and it compiles, but I get a linker error.
CMake Warning:
No source or binary directory provided. Both will be assumed to be the
same as the current working directory, but note that this warning will
become a fatal error in future CMake releases.
-- /usr/lib/x86_64-linux-gnu/libOpenGL.so/usr/lib/x86_64-linux-gnu/libGLX.so/usr/lib/x86_64-linux-gnu/libGLU.so
-- Configuring done
CMake Warning at CMakeLists.txt:38 (add_executable):
Cannot generate a safe runtime search path for target opengl-test because
files in some directories may conflict with libraries in implicit
directories:
runtime library [libGLEW.so.2.1] in /usr/lib64 may be hidden by files in:
/usr/lib/x86_64-linux-gnu
Some of these libraries may not be found correctly.
-- Generating done
-- Build files have been written to: /home/user/Documents/CPP-Stuff/Scrap-Framework
[29/29] Linking CXX executable opengl-test
FAILED: opengl-test
: && /usr/bin/x86_64-w64-mingw32-g++ -g CMakeFiles/opengl-test.dir/src/main.cpp.o CMakeFiles/opengl-test.dir/usr/include/imgui/imgui.cpp.o CMakeFiles/opengl-test.dir/usr/include/imgui/imgui_demo.cpp.o CMakeFiles/opengl-test.dir/usr/include/imgui/imgui_draw.cpp.o CMakeFiles/opengl-test.dir/usr/include/imgui/imgui_impl_glfw.cpp.o CMakeFiles/opengl-test.dir/usr/include/imgui/imgui_impl_opengl3.cpp.o CMakeFiles/opengl-test.dir/usr/include/imgui/imgui_tables.cpp.o CMakeFiles/opengl-test.dir/usr/include/imgui/imgui_widgets.cpp.o CMakeFiles/opengl-test.dir/src/base/Application/Application.cpp.o CMakeFiles/opengl-test.dir/src/base/Application/Window.cpp.o CMakeFiles/opengl-test.dir/src/base/GL/Cubemap.cpp.o CMakeFiles/opengl-test.dir/src/base/GL/Texture.cpp.o CMakeFiles/opengl-test.dir/src/base/GL/UniformBuffer.cpp.o CMakeFiles/opengl-test.dir/src/base/GL/VertexBuffer.cpp.o CMakeFiles/opengl-test.dir/src/base/Input/Input.cpp.o CMakeFiles/opengl-test.dir/src/base/Model/Material.cpp.o CMakeFiles/opengl-test.dir/src/base/Model/Mesh.cpp.o CMakeFiles/opengl-test.dir/src/base/Model/Model.cpp.o CMakeFiles/opengl-test.dir/src/base/Model/ModelLoader.cpp.o CMakeFiles/opengl-test.dir/src/base/Renderer/FPSCamera.cpp.o CMakeFiles/opengl-test.dir/src/base/Renderer/MaterialManager.cpp.o CMakeFiles/opengl-test.dir/src/base/Renderer/Renderbuffer.cpp.o CMakeFiles/opengl-test.dir/src/base/Renderer/Renderer.cpp.o CMakeFiles/opengl-test.dir/src/base/Scene/Lights.cpp.o CMakeFiles/opengl-test.dir/src/base/Scene/Scene.cpp.o CMakeFiles/opengl-test.dir/src/base/Scene/Skybox.cpp.o CMakeFiles/opengl-test.dir/src/base/Shader/Shader.cpp.o CMakeFiles/opengl-test.dir/src/base/Shader/ShaderManager.cpp.o -o opengl-test -Wl,-rpath,/usr/lib/x86_64-linux-gnu -lglfw /usr/lib/x86_64-linux-gnu/libOpenGL.so /usr/lib/x86_64-linux-gnu/libGLX.so /usr/lib/x86_64-linux-gnu/libGLU.so /usr/lib64/libGLEW.so && :
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lglfw
/usr/bin/x86_64-w64-mingw32-ld: /usr/lib/x86_64-linux-gnu/libOpenGL.so: error adding symbols: file in wrong format
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
The include files are located in /usr/include/, but I also put them in /usr/x86_64-w64-mingw32/include/.
Does anyone know how I can fix this, or a better way to compile for Windows on Linux?
You need to build the libraries you're using for Windows, or find prebuilt ones, e.g. in MSYS2 repositories. You also need to point CMake to those libraries.
I've made Quasi-MSYS2 to automate both.
Example usage:
# Install Clang, LLD, Wine. Then:
git clone https://github.com/holyblackcat/quasi-msys2
cd quasi-msys2/
make install _gcc _glfw _glew
env/shell.sh
# Build
cd your/project/location
mkdir build
cd build
cmake ..
make
# Run with Wine
./a.exe
Here is CMakeLists.txt I've used. I removed the cross-compilation stuff (which is handled automatically).
cmake_minimum_required (VERSION 3.5)
if (POLICY CMP0072)
cmake_policy(SET CMP0072 NEW)
else (NOT POLICY CMP0072)
message(STATUS "Could not use CMP0072 policy")
endif(POLICY CMP0072)
project(opengl-test LANGUAGES CXX)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
add_executable(a 1.cpp)
message(STATUS ${OPENGL_LIBRARIES})
target_link_libraries(a PUBLIC ${GLFW_LIBRARIES} ${OPENGL_LIBRARIES} GLEW::GLEW)
I also put them in /usr/x86_64-w64-mingw32/include/
You shouldn't modify system include directories manually. Leave them to your package manager.

C++ Linking a custom library built from source (CMakeLists.txt)

I built Open3D from source into a /home/user/custom_location/Open3D/build
I have a project with a dependency on Open3D and a CMakeLists.txt like this:
cmake_minimum_required(VERSION 3.12)
project(graph_filter)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)
# Pybind11
find_package(pybind11 REQUIRED)
# OpenMP
find_package(OpenMP REQUIRED)
# Eigen
find_package(Eigen3 3.3 REQUIRED NO_MODULE)
# Open3D
list(APPEND CMAKE_INSTALL_PREFIX "~/libraries/")
find_package(Open3D HINTS ${CMAKE_INSTALL_PREFIX}/lib/CMake)
list(APPEND Open3D_LIBRARIES dl)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Open3D_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Open3D_EXE_LINKER_FLAGS}")
include_directories(${Open3D_INCLUDE_DIRS})
link_directories(${Open3D_LIBRARY_DIRS})
pybind11_add_module(
graph_filter
wrapper.cpp
)
target_link_libraries(graph_filter PRIVATE ${Open3D_LIBRARIES} Eigen3::Eigen OpenMP::OpenMP_CXX)
How can I link it? When I run
INSTALL_DIR=/home/user/custom_location/Open3D/build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}```
I am getting:
Could NOT find Open3D (missing: Open3D_DIR)
fatal error: Open3D/Open3D.h: No such file or directory
2 | #include <Open3D/Open3D.h>
What is more confusing is the contents of Open3D/build folder after building from source.
I just want to resolve this dependency on Open3D. Thanks for any help!!!

CMake 3.22.4 does not compatible with GTest 1.10.0.20201025-1.1

I've build my unit test code on Ubuntu 21.10, CMake 3.18.4 and GTest 1.10.0.20201025-1.1.
I wrote CMakeList.txt file as this.
# The minimum version of CMake Required
cmake_minimum_required (VERSION 2.8.12)
# Any project name will suffice, this has connotaions when using advanced CMake Features
set(PROJECT_NAME tests)
project (${PROJECT_NAME})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# Just in case someone had the include files in seperate directory
include_directories(../include)
include_directories(..)
# This uses the complete student's library
aux_source_directory(.. SRC_LIST)
list(REMOVE_ITEM SRC_LIST "../main.cpp")
message ( STATUS "Compiling test_lib with following files ${SRC_LIST}" )
add_library(test_lib ${SRC_LIST})
# Now we make the gtests
set(GTEST_ROOT "/usr/src/gtest" CACHE PATH "Path to googletest")
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
if(NOT GTEST_LIBRARY)
message("GTest library not found")
endif()
add_executable(rawTests test_rawdata.cpp)
target_link_libraries(rawTests ${GTEST_LIBRARIES} pthread)
target_link_libraries(rawTests test_lib)
add_executable(timeTests test_time.cpp)
target_link_libraries(timeTests ${GTEST_LIBRARIES} pthread)
target_link_libraries(timeTests test_lib)
It works properly on my end.
But when I deliver this to my friend who uses CMake 3.22.4, it throws error look like this
Error Image
It's kind of weird issue and I didn't ever faced this sort of issue before.
I wonder anybody who has deep knowledge for CMake and GTest can help me to handle this.
Thank you in advance.

C++ Cygwin CMake Error: " fatal: cannot change to ' ' No such file or directory"

Using Cygwin in Windows I'm trying to build C++ project, that was sent to me, using cmake
after many trials to get it build successfully and at the last step I get this error
fatal: cannot change to '/cygdrive/d/project/C++/project1': No such file or directory
fatal: cannot change to '/cygdrive/d/project/C++/project1/lib/googletest':
Mainly this directory d:\project\c++\project1 is the root directry that I executed the cmake . commaind in and the gtest library is aready there in the same folder.
My CMAKELists.txt
cmake_minimum_required(VERSION 3.9)
project(Project1-Solution)
find_package(Threads)
find_package(Git QUIET)
# Set compiler flags
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wextra -pedantic -pedantic-errors -g")
# Make sure we have cloned googletest
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(COMMAND ${GIT_EXECUTABLE} -C ${PROJECT_SOURCE_DIR} submodule update --init --recursive)
execute_process(COMMAND ${GIT_EXECUTABLE} -C ${PROJECT_SOURCE_DIR}/lib/googletest checkout tags/release-1.8.1)
endif()
# Make sure GTest is built
include(gtest.cmake)
# Include project headers
include_directories(./include)
# Define the source files and dependencies for the executable
set(SOURCE_FILES
src/Handler.cpp
src/AllocationTracker.cpp
tests/main.cpp
tests/HandlerTest.cpp
tests/moreTests.cpp
)
# Make the project root directory the working directory when we run
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
add_executable(testing ${SOURCE_FILES})
add_dependencies(testing gtest)
target_link_libraries(testing gtest ${CMAKE_THREAD_LIBS_INIT})

CMake does not build the added sub-directory first

I am writing a C++ project that uses Poco Net library. I use CMake to configure the project.
I would like to add Poco as a sub-directory to my project so that it is built in my main project. Here is my shortened main CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
project(FunProj)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode...")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(HEADER_FILES IDataProvider.h DataProvider.h)
set(SOURCE_FILES main.cpp
DataProvider.cpp)
set(POCO_STATIC ON)
ADD_SUBDIRECTORY(poco)
include_directories(${CMAKE_SOURCE_DIR}/poco/Net/include)
include_directories(${CMAKE_SOURCE_DIR}/poco/Foundation/include)
link_directories(${CMAKE_CURRENT_BINARY_DIR}/poco/lib)
add_executable(FunProj ${SOURCE_FILES} ${HEADER_FILES})
target_link_libraries(${EXEC_NAME} PocoNet)
When I run cmake it configures everything including Poco but when I run make it does not compile the Poco libraries. It only compiles the main.o and DataProvider.o and then the linker fails with an error that libPocoNet.a does not exist.
What is the problem and how may one solve it?
Thank you.