C++ How to run programs in Clion when you need to include OpenGL libraries? - c++

Hello I need to work with OpenGL and want to create my project in Clion. But Clion cannot compile and run my projects because of the libraries I need to include. I can create my own makefile and run the program in terminal, but I want to do it in the IDE. How can I make this happen?

First make sure you installed all libraries correctly using the compiler you configured in clion/cmake. Assuminf you have a fresh CMakeLists.txt like
cmake_minimum_required(VERSION 3.3.2)
project(MyGL CPP)
add_executable(demo-run main.cpp)
For linking your libraries you need two things. First tell the compiler where to find the include files and second which libraries to link. You could just hard code you local installation like
target_link_libraries(demo-run path/to/glfw.lib path/to/opengl.lib path/to/jpeg.lib ...)
target_include_directories(demo-run PRIVATE path/to/glfw/include path/to/opengl/include path/to/jpeg/include ...)
however this is not very portable and if you want to work with another compiler or on another machine your project file will fail. Instead you can use the package system of cmake
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
find_package(JPEG REQUIRED)
find_package(GLEW REQUIRED)
find_package (OpenGL REQUIRED)
find_package (GLM REQUIRED)
target_link_libraries(demo-run ${GLFW_LIBRARIES} ${GLEW_LIBRARIES} ${JPEG_LIBRARIES} ${OPENGL_LIBRARIES})
target_include_directories(demo-run PRIVATE ${GLFW_INCLUDE_DIRS} ${GLEW_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLM_INCLUDE_DIR})
The glfw part is a bit tricky and works only on linux i guess see http://www.glfw.org/docs/3.0/build.html.
This code is not tested at all and you may need to specify some enviroment variables so cmake can find the packages or provide additional find scripts like https://github.com/lighttransport/nanogi/blob/master/cmake/FindGLM.cmake.

I would recommend to use the CMake build tool which does the work generating Makefiles for you and is also directly supported by clion. When you open the directory containing a CMakeLists.txt (CMake Project File) with clion, it should be automatically be loaded and compiled (if not just hit build)
A very simple example CMake project would look like this
cmake_minimum_required (VERSION 2.8.9)
project (OpenGl-Stuff)
include_directories(src)
add_executable(your-binary src/your-code.c src/your-code.h)
target_link_libraries(your-binary opengl)
# target_link_libraries will search for libopengl on standard system paths,
# maybe the library is not called libopengl, then you have to adjust the name above
this cmake project will generate the binary for you and link it against opengl

Related

X11 not being linked into static library

So I am building a tiny "game engine" in C++, using cmake to build it, and I am making it as a static library. In windows it works perfectly, but in linux I need to link X11.
Now this wouldn't be a problem, I can just add add_link_options(-lX11) in CMakeLists.txt, and mylib.a will build fine, but when I go and use my mylib.a, and link it into a C++ program, I also need to link X11 again using the add_link_options command.
I am trying to do something similar to what raylib does, and I also want to do linking and including the library how raylib does it (in raylib you only need to link libraylib.a, and everything else is taken care of), but in my case, every time I want to link mylib.a into a C++ project, I also need to link X11.
If I make mylib to be shared (mylib.so), it works without the need to link X11 in the second project as well, but I would like to have a static version of the library working as well.
Here's my CMakeLists.txt for my library:
cmake_minimum_required(VERSION 3.0.0)
project(ntt VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED TRUE)
add_link_options(-lX11)
# GLFW config (this one I copied from raylib directly)
set(BUILD_SHARED_LIBS OFF)
set(GLFW_BUILD_EXAMPLES OFF)
set(GLFW_BUILD_DOCS OFF)
set(GLFW_BUILD_TESTS OFF)
set(GLFW_INSTALL OFF)
add_subdirectory("${CMAKE_SOURCE_DIR}/src/glfw")
add_compile_definitions(_GLFW_X11)
# Generate source list
file(GLOB SOURCES "${CMAKE_SOURCE_DIR}/src/*.cpp")
list(APPEND SOURCES "${CMAKE_SOURCE_DIR}/src/glad/src/glad.c")
list(APPEND SOURCES $<TARGET_OBJECTS:glfw>)
# Create the library
add_library(ntt ${SOURCES})
set_target_properties(ntt PROPERTIES
PUBLIC_HEADER "${CMAKE_SOURCE_DIR}/include/Engine.hpp"
)
# Add include directories
target_include_directories(
ntt
PUBLIC
"${CMAKE_SOURCE_DIR}/include"
PRIVATE
"${CMAKE_SOURCE_DIR}/src/glad/include"
"${CMAKE_SOURCE_DIR}/src/glfw/include"
)
And here's CMakeLists.txt for a project that uses my library, and doesn't work (unless I add the add_link_options(-lX11)):
cmake_minimum_required(VERSION 3.0.0)
project(TestCpp VERSION 0.1.0)
# I want to not need to have this line here
# add_link_options(-lX11)
add_executable(TestCpp main.cpp)
target_include_directories(TestCpp PUBLIC "${CMAKE_SOURCE_DIR}/include")
target_link_libraries(TestCpp PUBLIC "${CMAKE_SOURCE_DIR}/libntt.a")
When I try to build the second project I get a bunch of errors like this:
/usr/bin/ld: /media/hdd/Development/C-C++/test/libntt.a(x11_monitor.c.o): in function `_glfwPollMonitorsX11': x11_monitor.c:(.text+0x3e8): undefined reference to `XFree' (they all come from places like x11_window, or x11_monitor, and all of them are abount missing references to different X11 functions used by glfw)
I know I must be missing something really easy, but I just don't know what. I am not new to C++, but this is the first time I've made an actual proper library, and I'm also pretty new to cmake (so pls excuse bad practices you might see in my CMakeLists).
I mostly relied on Microsoft's Visual Studio build system until recently, and the only reason I switched to cmake was to be able to port my code to more than one platform(windows) without jumping through the weird hoops that VS makes you jump through when configuring the project, and now I'm starting to like it, but every once in a while I bump into something like this.
So, in short: X11 links properly with -lX11, but I would like to only have the user link my library, and not have to bother with also linking X11 manually.
With raylib you only need to do target_link_libraries(mytarget PUBLIC raylib.a) and that links X11 and opengl and everything else needed, but in my case you also need to add_link_options(-lX11), and I want to not have to do that.

How to include non Vcpkg on CMakeLists.txt?

So I have a project which depends on opencv, which is installed with vcpkg. The project is build with cmake.
CMakeLists.txt
cmake_minimum_required(VERSION 3.19.1)
project(mylib)
set (CMAKE_CXX_STANDARD 14)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
link_libraries(${OpenCV_LIBS})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
add_library(mylib SHARED mylib.cpp another_lib.cpp)
That works fine.
Now, instead of vcpkg provided opencv, I want to use opencv from
https://sourceforge.net/projects/opencvlibrary/files/4.4.0/opencv-4.4.0-vc14_vc15.exe/download
After installing it on C:\opencv I see there is opencv\build\OpenCVConfig.cmake, which find_package look for, right?
But how do I make cmake get this one instead of the one from vcpkg?
Use <PackageName>_DIR variable pointing to where the config file is located. It works for any library which comes with a config file.
For you it would look like this:
set(OpenCV_DIR "C:/opencv/build")
Since it is incorrect to add hard-coded paths into persistent scripts, you can choose among different methods of providing this variable to your script:
Console invocation: cmake OpenCV_DIR="C:/opencv/build"
CMake presets (user)
Local config by using some LocalConfig.cmake with the content above (set(...)), which you include in your main script like this: include(LocalConfig.cmake)

Very slow intellisense for CMake-configured Vulkan-project

I have a Vulkan project configured with the following CMakeLists.txt on Windows:
cmake_minimum_required(VERSION 3.20)
project(Custom_Vulkan)
set(MINGW_INCLUDE "C:\\msys64\\mingw64\\include")
find_package(Vulkan REQUIRED)
find_package(glfw3 REQUIRED HINTS "C:\\msys64\\mingw64\\lib\\cmake")
add_subdirectory(shaders)
add_executable(AppTest main.cpp)
target_link_libraries(AppTest PUBLIC Vulkan::Vulkan glfw)
include_directories(${MINGW_INCLUDE})
Extensions for CMake (CMake & CMake Tools), and C++ (C/C++, C/C++ Extension Pack, C/C++ Themes) are installed, and I have configured and built my executable using the CMake Tools-extension.
Intellisense can at times be unreasonably slow and freezes completely, resulting in 0 autocompletion suggestions for both constants from built-in libraries like M_PI from cmath, but also for the Vulkan/GLFW-APIs which have been located by CMake.
Where should I search in order to locate the dependency that stalls Intellisense?
Is it possible to monitor/profile the Intellisense-search in order to find the issue?
The CMake-tools project is fully able to detect the dependencies, and compiles fine.
The Intellisense-freezes were in this case caused by dependency-issues between a FetchContent repository dependency in CMake and the C# vscode extension pack which caused an OmniSharp server-handle to remain open.
This was a standard FetchContent-pull:
FetchContent_Declare(
imgui_repo
GIT_REPOSITORY "https://github.com/ocornut/imgui.git"
)
FetchContent_MakeAvailable(imgui_repo)
Right-clicking the extension followed by disable(workspace) solved the issue.

How can I add Vulkan to a cross platform CMake project?

In order to make a CMake project as simple and as portable as it can get I have consider to add the "whole" repositories of the libraries I need to the project.
The project structure is as follows:
MyProject/
└──CMakeLists.txt
└──src/
└──MyProject/
└── *.h & *.cpp
└── CMakeLists.txt
└──ThirdParty/
└──Vulkan-Hpp/
└──(Vulkan Files)
└──glfw/
└──(glfw Files)
└──SFML/
└──(SFML Files)
All the third party directories are the git submodules of the following repositories:
https://github.com/KhronosGroup/Vulkan-Hpp
https://github.com/SFML/SFML
https://github.com/glfw/glfw
Summarizing everything up, I'm having trouble integrating the vulkan and sfml libraries to the project.
MyProject/CMakeLists.txt is as follows:
cmake_minimum_required (VERSION 3.8 FATAL_ERROR)
project ("MyProject")
set (MyProject_VERSION_MAJOR 0)
set (MyProject_VERSION_MINOR 2)
set (MyProject_VERSION_PATCH 1)
set (CMAKE_CXX_STANDARD 17)
# Include sub-projects.
add_subdirectory ("src/MyProject")
add_subdirectory ("ThirdParty/glfw")
add_subdirectory ("ThirdParty/SFML")
add_subdirectory ("ThirdParty/Vulkan-Hpp")
MyProject/src/MyProject/CMakeLists.txt:
cmake_minimum_required (VERSION 3.8 FATAL_ERROR)
project ("MyProject")
find_package(Vulkan REQUIRED FATAL_ERROR) # error
find_package(SFML REQUIRED network audio) # error
find_package(glfw REQUIRED FATAL_ERROR) # error
# Add source to this project's executable.
add_executable (MyProject "MyProject.cpp")
target_include_directories (MyProject
PUBLIC ${GLFW_INCLUDE_DIRS}
PUBLIC ${SFML_INCLUDE_DIR}
PUBLIC ${VULKAN_INCLUDE_DIRS}
)
target_link_libraries (MyProject glfw)
target_link_libraries (MyProject ${VULKAN_LIB_LIST})
target_link_libraries (MyProject ${SFML_LIBRARIES})
How can I tweak CMake in order to use the third party libraries at my main project?
Is the project structure incorrect?
If your find_package(Vulkan REQUIRED FATAL_ERROR) line is failing, you need to make sure the Vulkan SDK is properly installed, i.e. that you have a VULKAN_SDK environment variable that points to the correct location.
Additionally, do not embed the KhronosGroup/Vulkan-Hpp repository. This repository is for building the Vulkan C++ bindings, but shouldn't be used directly. Instead you should be using the vulkan.hpp header that is bundled with your installation of the Vulkan SDK. Otherwise when people try to build your project and have a different version of the Vulkan SDK installed than is referred to by your embedded KhronosGroup/Vulkan-Hpp
More generally, you are using find_package and then later you're using add_subdirectory to try to incorporate these external projects. That's not how it works. find_package will look for a pre-existing binary of the package, while add_subdirectory isn't designed to just swallow entire existing external CMake projects.
If you want to have your project build these others from source you should investigate the use of CMake's external project functionality. However, you'll probably find this to be more of a burden than it's worth. Alternatively, install vcpkg for your target platform, and use vcpkg to build and install glfw and sfml, then tell CMake to use the vcpkg dependencies (see the vcpkg docs on how to pass the CMAKE_TOOLCHAIN_FILE to your cmake configure line.

Setup CMake with SFML in VS2017

Just like in CLion I want to use SFML with Visual Studio 2017, but I'm still learning cmake and I don't know the commands or the logic of how cmake works at all. I've just seen some posts and got this litle script.
Note: I downloaded the latest version of sfml in the link provided, I just taked the extrated directory and put alongside CMakeLists.txt in my folder
#sets up the minimum version of cmake
cmake_minimum_required(VERSION 3.9)
#how the project will be called
project (space_impact)
#set c++11 standard
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" -std=c++11)
#set source files
set (SOURCE_FILES main.cpp)
#we add the executable of the program
add_executable (space_impact ${SOURCE_FILES})
#taked from a mac-clion tutorial, doesn't work
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/SFML/cmake-modules/")
find_package (SFML REQUIRED system window graphics network audio)
if (SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(space_impact ${SFML_LIBRARIES})
endif()
that thing gave me errors:
Error CMake Error at SFML/cmake-modules/FindSFML.cmake:355 (message):
Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
SFML_GRAPHICS_LIBRARY SFML_NETWORK_LIBRARY SFML_AUDIO_LIBRARY) SFML/cmake-modules/FindSFML.cmake
I want everything to be dynamic, but I don't know how can I do that..
So my question is what should I do for setting up correctly SFML with Cmake in Visual Studio.
I don't want the old-fashioned method from the official website
UPDATE
Here's my location....
The thing is.. the FindSFML.cmake script it's not working...
What files should I move for make it working?
Your script is perfectly fine, except three things I'd change:
Move the whole module detection before defining targets. I'm pretty sure you also have to define your include directories before.
Your if(SFML_FOUND) bracket is pretty pointless right now, because you've set SFML to be required, which means it will never get past find_package() unless it's found.
-std=c++11 is a GCC only flag (MSVC will always use the latest standard, unless specified). As such you'll have to check the compiler here or use CMAKE_CXX_STANDARD.
So the "cleaned" CMakeLists.txt could look like this:
#sets up the minimum version of cmake
cmake_minimum_required(VERSION 3.9) # personally I'd set this version as low as required; you don't have to require the cutting edge version
#how the project will be called
project (space_impact)
#set the C++ standard to be used
set (CMAKE_CXX_STANDARD 11)
#set source files
set (SOURCE_FILES main.cpp)
#look for SFML and add it
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/SFML/cmake-modules/")
find_package (SFML REQUIRED system window graphics network audio)
include_directories(${SFML_INCLUDE_DIR})
#we add the executable of the program
add_executable (space_impact ${SOURCE_FILES})
target_link_libraries(space_impact ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
Note that adding SFML_DEPENDENCIES to the library list is optional, unless you're using a static version of SFML.
But what about your SFML issue? Since you don't have the SFML files installed in any directory looked into by default, you'll have to tell CMake where it's found using the CMake variable SFML_ROOT or the environment variable of the same name.
So the first time you're invoking CMake, it could look like this:
cmake -G "Visual Studio 15 2017" -DSFML_ROOT=path/to/sfml path/to/source
This is all you need to compile sfml in your cmake project.
find_package(SFML 2.5.1 COMPONENTS system graphics audio network REQUIRED)
add_executable (AwesomeProject "AwesomeProject.cpp" "AwesomeProject.h")
target_link_libraries(AwesomeProject PRIVATE sfml-audio sfml-graphics sfml-network sfml-system)
Also set SFML_DIR var to your sfml folder.