I wanted to make the example which combines ITK with VTK called IO/ImageFileReader from wiki examples.
I downloaded itkvtkglue, extracted to a folder, configured with cmake and built with visual studio 2010.
but i can't use it when i try to configure the example given. Even though cmake finds the ItkVtkGlue_DIR by itself, it gives the error that he couldn't include the necessary files. Fails to include(${ItkVtkGlue_USE_FILE})
Should I somehow change the folders CMake looks for my ItkVtkGlue header files? Is there other way to use ITK & VTK together?
the error and file content are given below.
CMake Error at CMakeLists.txt:6 (include):
include could not find load file:
C:/Users/Emre
CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 2.6)
project(ImageFileReader)
find_package(ItkVtkGlue REQUIRED)
include(${ItkVtkGlue_USE_FILE})
add_executable(ImageFileReader ImageFileReader.cxx)
target_link_libraries(ImageFileReader
ItkVtkGlue ${VTK_LIBRARIES} ${ITK_LIBRARIES})
Thank you all for your help.
This is almost certainly one of the very common problems:
If the path to your tools contains a [space] character in it, then you must protect the file path from being split apart by encapsulating it in quotations "".
To be safe, you should always place file paths in quotations just incase one of your future collaborators tries to build on a path that has spaces in it.
You may also want to review:
http://www.vtk.org/Wiki/ITK/Examples#ItkVtkGlue
Related
I tries to use FOREACH to generated several pb files. And make two list names PROTO_SRCS & PROTO_HDRS like below.
I can use it in the main CMakeLists. Like add_executable(a SHARED ${PROTO_SRCS} main.cpp).
But I can not use this param in subdirectories to make a library. when I type "cmake .." in main CMakelists build dir. It shown that "Cannot find source file: a.pb.cc".
main CMakeLists.txt
add_library(xxx SHARED ${PROTO_SRCS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/back back)
in src/back CMakeLists.txt
add_executable(yyy ${PROTO_SRCS})
and I can use message to show ${PROTO_SRCS} in subdir so it pass into successfully.
Please help me to point out the problem. Thx a lot
The issue is that in CMake versions older than 3.20 the GENERATED property of source files is only visible in the directory where it is set. Thus, when you add the protobuf-generated source files to a target defined in a different directory, CMake will no longer know that these are files generated during the build. Consequently, CMake will try to locate these files at configuration time, when they obviously do not exist yet.
Unfortunately, at the time of writing there is only a release candidate for CMake 3.20 and no official release yet. So depending on whether you need to coordinate with other coworkers or whether you're working on this project on your own it might not be feasible to use the release candidate.
If you can't use it, the alternative is to create an object library via add_library(protobuf_objs OBJECT ${PROTO_SRCS}) in the directory where you generate the files and to use target_sources(xxx PRIVATE $<TARGET_OBJECTS:protobuf_objs>) and target_sources(yyy PRIVATE $<TARGET_OBJECTS:protobuf_objs>) instead of adding the ${PROTO_SRCS} as source files to these targets directly.
I am trying to integrate spdlog, a header only logging library into a C++ project but I am having trouble getting CMake to recognise the include paths properly. I am using the latest CLion with CMake 3.10.2 on Ubuntu 18.04.
My project structure looks like this:
Project Dir
|- libs
| |- spdlog #this is the include directory taken straight from GitHub
|
|- src
| |-...
|- CMakeLists.txt
In the CMakeLists.txt file I define the include directory:
include_directories("libs/")
Now when I attempt to write #include <spdlog/spdlog.h> in a header file located in src/ CLion complains that it cannot find spdlog.h even though I have checked and the file is definitely in the spdlog folder. Using quotation marks instead of angled brackets in the include statement does not fix the problem however using the path relative to the file (e.g. ../libs/spdlog/spdlog.h) works as it should. What is more confusing to me is that in the source file corresponding to the header I can include the file no problem.
I haven't been able to find anything like this issue anywhere and I'm struggling to understand what is causing CMake or CLion to behave like this.
EDIT: As per Matthieu Brucher's suggestion I have tried using fully qualified paths to the include folder but it still does not work. The problem seems to be that folders seem to not be recognised in headers, as they work in source files.
EDIT2: Here is the entire CMakeLists.txt I am using. It is nested into a different directory than the top level CMakeLists.txt for the entire project as this was the only solution I have found online to get something akin to VS's multiple projects in a solution in CLion. However since all paths are relative I don't think this would be a problem. I also know that spdlog is a C++11 library but I will need some C++14 features elsewhere in the near future.
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(TokenEngine VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES src/Application.cpp src/Application.hpp src/EntryPoint.hpp src/Logger.cpp src/Logger.hpp)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/libs/")
add_library(TokenEngine SHARED ${SOURCE_FILES})
#Expose the public API of the engine to any project that might use it
target_include_directories(TokenEngine PUBLIC include)
EDIT3: When I attempted to recreate the error to show the full message given somehow the it was gone, being replaced by a different one totally unrelated to CMake...
You may want to use fully qualified paths:
include_directories(${CMAKE_SOURCE_DIR}/libs/)
You also have to add the include folder to the include paths to be able to include via #include <spdlog/spdlog.h>. This should look like
include_directories(${CMAKE_SOURCE_DIR}/libs)
But I prefer using
target_include_directories(yourTarget PUBLIC ${CMAKE_SOURCE_DIR}/libs)
where yourTarget is the target where you want to use spdlog. Like that you will have the include directories also available if you are going to link your yourTarget to something else. If you need spdlog just in yourTargets cpp files you can change the PUBLIC to PRIVATE. See cmake doc.
I added the xgboost library as a git submodule of my project and I'm trying to add it to cmake as a subdirectory. Unfortunately it's not working. A simple hello world project with the following CMakeLists.txt replicates the error that I'm getting.
cmake_minimum_required(VERSION 3.2)
project(foo)
add_subdirectory(xgboost)
add_executable(${PROJECT_NAME} foo.cpp)
target_link_libraries(${PROJECT_NAME} xgboost)
After building the library there is nothing in the xgboost/lib directory so I get the following error.
clang: error: no such file or directory:
'/Users/.../myproject/xgboost/lib/libxgboost.dylib'
I think that the problem is generated in their CMakeLists file since they have two different targets. Maybe cmake is choosing the wrong target but I'm not familiar enough with cmake to figure it out. The following code is from xgboost's CMakeLists.
# Executable
add_executable(runxgboost $<TARGET_OBJECTS:objxgboost> src/cli_main.cc)
set_target_properties(runxgboost PROPERTIES
OUTPUT_NAME xgboost
)
set_output_directory(runxgboost ${PROJECT_SOURCE_DIR})
target_link_libraries(runxgboost ${LINK_LIBRARIES})
# Shared library
add_library(xgboost SHARED $<TARGET_OBJECTS:objxgboost>)
target_link_libraries(xgboost ${LINK_LIBRARIES})
set_output_directory(xgboost ${PROJECT_SOURCE_DIR}/lib)
#Ensure these two targets do not build simultaneously, as they produce outputs with conflicting names
add_dependencies(xgboost runxgboost)
My questions in order of importance are:
Is there any way to fix it without modifying xgboost's CMakeLists.txt file?
Is it reasonable to try to add xgboost to my project as a git submodule?
Is there any reason cmake is not instructing to build the library?
Note: There were several edits to this question since I tried to narrow down the problem and to provide more information.
(I would love to ask for few things beforehand in the comment section, but I have too low reputation to do so, so I will just give it a shot ;))
I have few suspects, and one of them is ${CMAKE_SOURCE_DIR} of the submodule's root CMakeLists.txt. Although the paths are set properly when you run that CMakeLists.txt alone, cmake gets confused the moment you add it as your subdirectory. Have you looked into another directories for your output binaries?
First I would suggest testing this hypothesis, and then I would suggest writing similar, but separate CMakeLists.txt file for xgboost library, and then substitute it in the project temporarily. Unfortunately the CMakeLists.txt filename is hardcoded and there is no possibility to have two files of that kind in one directory; so it seems that the answer to 1) is, that you rather have to change the file.
For the 2): as long as it does not require huge additional logic in your CMakeLists.txt, it makes sense. Other viable option is to create an install target, which you can use to install your xgboost library locally (using CMAKE_INSTALL_PREFIX(doc) variable), and then add the installation path to your CMAKE_LIBRARY_PATH(doc).
I am new to CMake and DBus. I am following along the guide here and make a basic program compile and execute.
The first problem that I ran into was my program will not find
<dbus/dbus.h>
I got around that issue by adding some include directories to my CMakeList.txt.
Currently, my CMakeLists.txt looks like this:
...
include_directories(/usr/lib/)
include_directories(/usr/include/dbus-1.0/)
include_directories(/usr/lib/x86_64-linux-gnu/dbus-1.0/include)
include_directories(/usr/include/glib-2.0)
include_directories(/usr/lib/x86_64-linux-gnu/glib-2.0/include/)
set (LIBS
dbus-1
dbus-glib-1
)
add_executable(mydbus mydbus.cpp)
target_link_libraries(mydbus ${LIBS} )
Now, my program is complaining about not being able to find dbus-arch-deps.h
/usr/include/dbus-1.0/dbus/dbus.h:29:33: fatal error: dbus/dbus-arch-deps.h: No such file or directory
#include <dbus/dbus-arch-deps.h>
I know that the solution for this is to use proper command line flags or pkg-config. As discussed here and numerous other posts.
However, I do not know how to configure CMakeLists.txt to have similar effect.
My guess would be to add something like find_package(dbus-1) to CMakeLists.txt. And if that is correct, I am going to have to write my own Finddbus-1.cmake. Does this sound correct? Or is there an easier way?
I will appreciate any pointers.
You may get an existing FindDBus.cmake script (e.g., this one), copy it into your project, and use as
find_package(DBus REQUIRED)
# Use results of find_package() call.
include_directories(${DBUS_INCLUDE_DIRS})
add_executable(mydbus mydbus.cpp)
target_link_libraries(mydbus ${DBUS_LIBRARIES})
Alternatively, as you know pkgconfig can find DBus, you may use CMake module PkgConfig. Actually, FindDBus.cmake script, referenced above, uses PkgConfig module in its implementation. Possible usage could be:
find_package(PkgConfig REQUIRED) # Include functions provided by PkgConfig module.
pkg_check_modules(DBUS REQUIRED dbus-1) # This calls pkgconfig with appropriate arguments
# Use results of pkg_check_modules() call.
include_directories(${DBUS_INCLUDE_DIRS})
link_directories(${DBUS_LIBRARY_DIRS})
add_executable(mydbus mydbus.cpp)
target_link_libraries(mydbus ${DBUS_LIBRARIES})
However, using link_directories is not recommended, it is better to use absolute paths to libraries in target_link_libraries() call. That is why it is better to combine pkg_check_modules with find_library, as it is done in the referenced Find script. That answer describes generic way for use result of pkgconfig in CMake.
I want to exclude some source files from building when not in Windows.
What is wrong in the following CMakeLists.txt cmake file?
aux_source_directory(. SRC_LIST)
# Remove Microsoft specific files
message(${SRC_LIST})
list(REMOVE_ITEM SRC_LIST stdafx.h stdafx.cpp)
message("------------------")
message(${SRC_LIST})
The contents of the messages before and after trying to remove the two files are exactly the same.
What is wrong?
You have to specify the exact name of the element you want to remove.
In your case, aux_source_directory prepends each entry with a ./, so the correct command has to be
list(REMOVE_ITEM SRC_LIST ./stdafx.h ./stdafx.cpp)
Also, please make sure you understand the implications of using manual calls to aux_source_directory for maintaining lists of source files:
It is tempting to use this command to avoid writing the list of source
files for a library or executable target. While this seems to work,
there is no way for CMake to generate a build system that knows when a
new source file has been added. Normally the generated build system
knows when it needs to rerun CMake because the CMakeLists.txt file is
modified to add a new source. When the source is just added to the
directory without modifying this file, one would have to manually
rerun CMake to generate a build system incorporating the new file.
Quoting the documentation for aux_source_directory.