Linking external library in runtime - c++

I'm to trying compile simple program which uses FMOD with CMake. Compilation seems to be alright but my application crashes with 0xC0000135 which is STATUS_DLL_NOT_FOUND
My CMakeList.txt
cmake_minimum_required(VERSION 3.7)
project(fmod-test)
set(FMOD_DIR "D:/FMOD SoundSystem/FMOD Studio API Windows")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(fmod-test ${SOURCE_FILES})
include_directories(${FMOD_DIR}/api/lowlevel/inc ${FMOD_DIR}/api/studio/inc)
link_directories("${FMOD_DIR}/api/lowlevel/lib" "${FMOD_DIR}/api/studio/lib")
target_link_libraries(fmod-test
"${FMOD_DIR}/api/lowlevel/lib/fmod_vc.lib"
"${FMOD_DIR}/api/studio/lib/fmodstudio_vc.lib")
Is this a problem with my cmake config or environment?
Should I put DDLs in some specific place or provide path to them somethere besided CMakeLists.txt?

Solved by adding api/lowlevel/lib and api/studio/lib to the PATH variable.
Kudos to kvr for suggestion.

Related

CLion Not Finding GLUT with CMake

I have a problem that I can't seem to find the settings to modify.
When attempting to find the GLUT package using CLion's CMake utilities on Ubuntu, it does not find GLUT. Using command-line CMake and Makefile commands, however, finds the dependencies perfectly and allows the following to generate and compile:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(mre)
set(CMAKE_CXX_STANDARD 20)
find_package(OpenGL REQUIRED) # Works in CLion and terminal
find_package(GLUT REQUIRED) # Works only in terminal
include_directories(GL)
add_executable(mre mre.cpp)
target_link_libraries(mre -lglut -lGLU -lGL)
// mre.cpp
#include <GL/gl.h>
#include <GL/glut.h>
int main()
{
return 0;
}
Whereas attempting to use these files in a CLion project would cause errors (first unable to find GLUT, mitigated by manually setting library and include variables; then GL/glut.h: No such file or directory, which I am unable to fix).
Does anyone have any suggestions? I'm assuming it's something to do with a working directory or prefixes, but CMAKE_PREFIX_PATH is unset in CLion, and setting it to various values does nothing to solve the problem.
Thanks!
You know something has gone wrong when you write include_directories or -l flags by hand. You should absolutely always link to libraries via their imported targets.
See the documentation:
OpenGL package: https://cmake.org/cmake/help/latest/module/FindOpenGL.html
GLUT package: https://cmake.org/cmake/help/latest/module/FindGLUT.html
Try this revision:
cmake_minimum_required(VERSION 3.16)
project(mre)
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
add_executable(mre mre.cpp)
target_link_libraries(mre PRIVATE OpenGL::GL OpenGL::GLU GLUT::GLUT)
target_compile_features(mre PRIVATE cxx_std_20)
As for not being able to find GLUT... just set CMAKE_PREFIX_PATH in CLion's settings to whichever directory on your system contains include/GL/glut.h.
Alternative solution
CLion was installed through the Software Center via Flatpak, which uses some kind of filesystem sandboxing that may be interfering with paths. I tried explicitly allowing /usr and related paths, but had no effect.
I have reinstalled via JetBrains's official archive, which correctly detects GLUT and OpenGL. Their official snap also works properly.

CMake BUILD undefined reference (findpng)

I'm still very new to CMake so feedback is definitely welcome. So, I'm trying to build a simple application that should eventually create a pdf using the library libharu.
I think i figured it out how to link the library. But I still receive build errors for the findpng module (I suppose libharu depends on it)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR) # current latest stable version (if lower give FATAL_ERROR)
project(pdf_generator VERSION 0.1.0) # name of the project, version.
file(GLOB TARGET_SRC "./src/*.cpp") # Creates variable, using globbing.
include_directories(${PROJECT_SOURCE_DIR}/include) # list of directories to be used as header search paths.
add_executable(main ${TARGET_SRC}) # Create an executable of set of source files [exe name files to bundle].
find_library(libhpdf_location NAMES libhpdf.a) # find the location of libhpdf.a and save the value in the variable libhpdf_location.
message(STATUS ${libhpdf_location}) # print status of variable.
add_library(libhpdf STATIC IMPORTED) # Add library via a static import.
set_target_properties(
libhpdf PROPERTIES
IMPORTED_LOCATION ${libhpdf_location}
)
target_link_libraries(main libhpdf)
I've never worked with that particular library before, but skimming their CMakeLists.txt on GitHub it seems like libharu has optional dependencies on libpdf and zlib. Without knowing how you built your version of libharu I'm going to assume that both are needed.
Luckily, CMake comes with find-modules for both libpng and zlib, so adding the following should work:
find_package(PNG REQUIRED)
find_package(ZLIB REQUIRED)
set_target_properties(libhpdf
PROPERTIES
INTERFACE_LINK_LIBRARIES "ZLIB::ZLIB;PNG::PNG"
)
Looks like all you need to do is tell cmake to link libpng.

Support included directory in CLion

I have project in CLion constructed from 2 major parts(2 projects). One is dynamic library(/engine) and the second one is executable(/gui)
My project structure is:
CMakes looks like this:
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
add_subdirectory(engine)
add_subdirectory(gui)
/engine/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 17)
add_library(enginelib SHARED library.cpp library.h)
/gui/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 17)
include_directories(../engine)
add_executable(gui main.cpp)
target_link_libraries(gui PRIVATE enginelib)
Project builds correctly, gui is using engine and it works.
However Clion underscores including from engine and doesn't show things from engine.
How to fix this?
Thanks for help :)
Btw, It's my first time setting project like this, am I including the engine into gui correctly? Or there is a better way to do this?

Using SDL2 with CMake in CLion

After hours of scouring the web and SO for a solution I'm at a standstill. Nothing has worked so far for me...
I'm on Windows, using CLion IDE which uses CMake. My goal is to correctly link SDL2 to my project and use it through #include "SDL.h" which is the correct way.
The format of my CMakeLists.txt file
Specifics regarding the directory where I should have put the MingW development library of SDL2
Any requirements regarding windows ENV variables that I might have to set.
My CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.6)
project(sdl2Project)
set(CMAKE_CXX_STANDARD 11)
#This is where sdl2-config.cmake is located
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Users/MyUserName/CLibraries/SDL2-2.0.5/x86_64-w64-mingw32/lib/cmake/SDL2")
set(SOURCE_FILES main.cpp)
add_executable(sdl2Project ${SOURCE_FILES})
find_package(sdl2 REQUIRED)
target_include_directories(sdl2Project PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(sdl2Project ${SDL2_LIBRARIES})
There is no FindSDL2.cmake file used.
The SDL2 library I downloaded from libsdl.org is located in:
C:/Users/MyUserName/CLibraries/SDL2-2.0.5/x86_64-w64-mingw32
I have no experience with CMake so I'm unable to truly understand where the problem stems from. What are the steps I need to take in order for it to find the library and link it correctly??
EDIT:
My Project structure is the following:
sdl2Project
cmake-build-debug
CMakeLists.txt
main.cpp
Looking in your FindSDL2.cmake, you need to provide an hint to CMake about where the library is installed. You could do this by setting an environment variable SDLDIR, but you shouldn't. General advice: you shouldn't use a CMake package that wasn't provided with the sources you're using.
Looking in sources of SDL2, root directory contains a file sdl2-config.cmake.in that should have been configured and installed in your install directory as sdl2-config.cmake: that's the package file you should use.
Am I right guessing the file C:/Users/MyUserName/CLibraries/SDL2-2.0.5/sdl2-config.cmake exists?
If yes, to allow CMake to find it, add your install directory to CMAKE_PREFIX_PATH, before calling find_package:
set(CMAKE_PREFIX_PATH
${CMAKE_PREFIX_PATH}
"C:/Users/MyUserName/CLibraries/SDL2-2.0.5"
)
find_package(sdl2 REQUIRED)
Note the use of "/" in the path instead of "\" which could be interpreted as escaping character. Quotes around the path are only necessary if the path contains whitespaces.
EDIT:
Moreover, you misused target_link_libraries with a wrong target: SDL2 which you don't build in your project, instead of sdl2Project.
You also used a wrong variable: SDL2_LIBRARY instead of SDL2_LIBRARIES; you can see the good variable name by looking in sdl2-config.cmake.
You may consider target_include_directories instead of include_directories, but again the variable name you used is wrong: SDL2_INCLUDE_DIR instead of SDL2_INCLUDE_DIRS.
Try:
target_include_directories(sdl2Project PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(sdl2Project ${SDL2_LIBRARIES})

VTK CMakeLists.txt for test classes

A typical 'CMakeLists.txt' included with a VTK wiki example is shown below;
cmake_minimum_required(VERSION 2.8)
PROJECT(Arrow)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(Arrow MACOSX_BUNDLE Arrow)
if(VTK_LIBRARIES)
target_link_libraries(Arrow ${VTK_LIBRARIES})
else()
target_link_libraries(Arrow vtkHybrid)
endif()
I'm able to build the examples successfully in Windows 7 and Visual Studio 2012.
I would like to write a 'CMakeLists.txt' file so that I can build/run a test class (i.e. This one ReebGraph/Testing). I'm assuming I'm right in saying that they require different kinds of make files. The 'CMakeLists.txt' for 'TestReebGraph.cxx' is shown below.
vtk_add_test_cxx(TestReebGraph.cxx NO_DATA NO_VALID NO_OUTPUT)
vtk_test_cxx_executable(${vtk-module}CxxTests)
How would I write one for the testing class? Do I somehow have to merge the two?
The cmake commands vtk_* are for writing tests inside of the VTK CMake system. What you'll want is to first enable_testing() in your CMakeLists.txt. Then you'll have to change the function TestReebGraph to be called 'main' in TestReebGraph.cxx. You can then use add_test(TestReebGraph TestReebGraph.cxx) to build the test that you have presumably copied into your project directory.