VTK CMakeLists.txt for test classes - c++

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.

Related

Catch2 CLion error, "No tests were found"

I have a folder structure like
and I am trying to get Catch2 setup, my CMake files look like:
the topmost CMake:
cmake_minimum_required(VERSION 3.21)
project(throwaway)
set(CMAKE_CXX_STANDARD 14)
add_subdirectory(src)
add_subdirectory(tests)
add_executable(foo_main main.cpp)
target_link_libraries(foo_main PUBLIC foo_lib)
my src CMake:
add_subdirectory(foo)
my src/foo CMake:
add_library(foo_lib Foo.cpp)
my tests CMake:
add_subdirectory(foo)
add_executable(foo_test catch_runner.cpp)
target_link_libraries(foo_test PUBLIC
foo_test_lib)
my tests/foo CMake
add_library(foo_test_lib
FooTests.cpp)
target_link_libraries(foo_test_lib PUBLIC
foo_lib)
From there, I used Clion's Catch2 integration to set up my run config as
so nothing crazy here
However, I get this error:
I discovered that the error goes away if I edit the tests CMake into
add_executable(foo_test catch_runner.cpp foo/FooTests.cpp)
target_link_libraries(foo_test PUBLIC foo_lib)
and the test works as expected. But I obviously don't want to manually add each file into an executable, I want to be able to make a library that I can just slap the catch_runner into.
I have no clue why the test doesn't work when I link it as a library, but works when I add it manually. Any ideas?
Figured out it from the links at How do you add separate test files with Catch2 and CMake?
in my tests/foo CMake I changed it to
add_library(foo_test_lib OBJECT
FooTests.cpp)
target_link_libraries(foo_test_lib PUBLIC
foo_lib)

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.

Can values be set for CMake SOURCE(S) other than using set?

Suppose I have a simple C++ hello-world project with the following CMake script:
cmake_minimum_required(VERSION 3.15)
project(hello)
set(SOURCE main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE})
Now I noticed that PROJECT_NAME is built-in and its value is set from project(*value*) but also SOURCE (and SOURCES) seems to be provided by CMake too.
Are there other ways where SOURCE can be assigned with project source files? Just like the same behavior with PROJECT_NAME. Or is set(SOURCE ...) the intended method.
I'm new to CMake. The SOURCE and SOURCES variables were colored out on my text editor. I'm confused.
Using a SOURCE variable is a common patter in CMake files, but it is not required.
The code above can be written without any variables, it would look something like this:
add_executable(hello main.cpp)
When there are a lot of source files, passing them all to add_executable can be inconvenient. Another alternative is target_sources:
add_executable(hello)
target_sources(hello PRIVATE main.cpp)

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})

CMake: Build Multiple Executables in one Project with Static Library

I'm working on a project that consists of 3 server executables and one library for shared code. I want it to be cross-platform, so I'm using CMake (since Xcode is being a pain anyway) to handle the build process. I'm having trouble with setting up the CMakeLists so that I can include the library from a directory at the same level when I'm building the executable.
Here's the directory structure (and the CMake files):
tethealla2.0/
CMakeLists.txt
libtethealla/
CMakeLists.txt
encryption/
utils/
patch_server/
CMakeLists.txt
login_server/
CMakeLists.txt
ship_server/
CMakeLists.txt
My top-level CMake (tethealla2.0/CMakeLists.txt, only includes the sub-project that should compile):
project(tethealla CXX)
cmake_minimum_required(VERSION 2.6)
add_subdirectory(libtethealla)
add_subdirectory(patch_server)
tethealla2.0/libtethealla/CMakeLists.txt, which generates a static library:
project(Libtethealla C)
cmake_minimum_required(VERSION 2.6)
include_directories(encryption)
set(ENC_DR encryption/)
set(ENCRYPTION_SOURCES
${ENC_DR}/psobb-crypt.c
${ENC_DR}/psogc-crypt.c
${ENC_DR}/psobb-crypt.c
${ENC_DR}/encryption.c
)
add_library(tethealla STATIC ${ENCRYPTION_SOURCES})
tethealla2.0/patch_server/CMakeLists.txt thus far:
project(patch_server CXX)
cmake_minimum_required(VERSION 2.6)
add_executable(server main.cc)
target_link_libraries(server tethealla)
So it makes more sense if I build it from the top level since tethealla2.0/CMakeLists.txt will inherit the targets from each of the subdirectories and the one in patch_server will have access to the tethealla library. However what I want is to be able to build from within these subdirectories to generate Xcode projects so that I can work on/recompile them individually. To do so I need to be able to get to the libtethealla/build directory (where CMake outputs) to access the libtethealla.a library from patch_server. Is this possible?
On kind of another note, even in building from the top-level directory my source in patch_server can't include "encryption.h", the header file for the library in encryption. Which seems to be building fine. Any thoughts on that are also greatly appreciated!
My solution is to use add_subdirectory with relative patch to shared_lib directory. I don't think that this is a perfect solution it has its caveats:
Logic very similar to a header guard must be added to library CMakeLists.txt to prevent from defining targets multiple times.
Each CMakeList.txt file must know the relative path to the library, if one want to move library all CMakeLists must be updated.
Let's assume that the directory structure looks like this:
root/
CMakeLists.txt
shared_lib/
CMakeLists.txt
inc/
foo.h
src/
foo.c
exec1/
CMakeLists.txt
main.c
exec2/
CMakeLists.txt
main.c
root/CMakeList.txt
cmake_minimum_required(VERSION 2.6)
add_subdirectory(shared_lib)
add_subdirectory(exec1)
add_subdirectory(exec2)
I have decided that shared_lib/CMakeLists.txt will export a variable named SHARED_DIR_INCLUDE_DIR. This approach helps to decouple things a little bit.
root/exec1/CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
add_subdirectory(./../shared_lib shared_lib)
include_directories(${SHARED_LIB_INCLUDE_DIR})
set(SRCS main.c)
add_executable(exec1 ${SRCS})
target_link_libraries(exec1 shared_lib)
if() in the fourth line solves the issue with target's multiple definition in case the CMakeLists file is added multiple times. The second and the third lines exports the include directory for library in SHARED_LIB_INCLUDE_DIR
root/shared_lib/CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
set(SHARED_LIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/inc)
set(SHARED_LIB_INCLUDE_DIR ${SHARED_LIB_INCLUDE_DIR} PARENT_SCOPE)
if(TARGET shared_lib)
message("shared_lib is already defined")
else()
include_directories(${SHARED_LIB_INCLUDE_DIR})
set(LIB_SRCS ./src/foo.c)
add_library(shared_lib STATIC ${LIB_SRCS})
endif()