I am trying to setup some include paths using CMake and QT Creator and I'd like to get the rid of the path traversal on my includes. What I meant by that is below.
#include <QtTest>
#include <QCoreApplication>
#include <QDebug>
#include "../../../../UI/Controller/PageNavigator/PageNavigatorPT.h" //this works
//#include "PageNavigatorPT.h" // but this what I want
I want what is commented out, so I avoid these huge path traversals on my source. I added this to my cmake to try to fix the issue:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(pageNavigatorTest
../../../../UI/Controller/PageNavigator/PageNavigatorBase.cpp
../../../../UI/Controller/PageNavigator/PageNavigatorPT.cpp
tst_pagenavigatortest.cpp)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}../../../../UI/Controller/PageNavigator
)
add_test(NAME pageNavigatorTest COMMAND pageNavigatorTest)
but it does not work. I still have to spell out the full path traversal.
Is there a way to make CMake make my source find the correct header by just writing:
#include "PageNavigatorPT.h" // but this what I want
thanks #Tsyvarev, this solved the problem (slash in front of the first dir
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../../../../UI/Controller/PageNavigator
)
Related
Like the heading says I don't wanna use the find_package(Boost) to locate Boost and then the Asio component in it rather I want to do by creating a target library, and then link the target to my executable like this
cmake_minimum_required(VERSION 3.0)
project(final_exe_proj VERSION 1.0)
add_executable(final_exe main.cpp)
find_package(Threads REQUIRED)
add_library(boost_asio INTERFACE)
target_include_directories(boost_asio INTERFACE /usr/local/include/boost/asio.hpp)
target_link_libraries(boost_asio INTERFACE Threads::Threads)
target_link_libraries(final_exe PRIVATE boost_asio)
I have tried doing #include <asio.hpp> but still no luck. What is the right way to do it? Really would appreciate any help. Thanks!
Happy New Year!
Thanks Alan! The issue was in the line target_include_directories
On changing that too
target_include_directories(boost_asio INTERFACE /usr/local/include)
In a way this adds to the path for this project, so now the compiler will be able to find #include <boost/asio.hpp>
I work on C++ project, i use CMake to build my file. My build fail cause
undefined reference to `Software::Software()'
, but I do not see the problem. If you have an idea, do not hesitate, thank you
Files architecture:
CMake :
# cmake_minimum_required(VERSION <specify CMake version here>)
project(untitled)
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_CXX_STANDARD 11)
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_executable(untitled ${SOURCES})
Software.h :
#include <string>
class Software{
private :
std::string name;
public :
Software();
}
Software.cpp :
#include "Software.h"
Software::Software() {
this->name = "defaultName";
}
SoftwaresConfigurations.h (who call the contructor of Software) :
#include "Software.h"
class SoftwaresConfigurations {
public:
SoftwaresConfigurations();
}
SoftwaresConfiguration.cpp :
#include "SoftwaresConfigurations.h"
SoftwaresConfigurations::SoftwaresConfigurations(){
Software software = Software();
}
You have fallen into the trap that is FILE(GLOB ...).
Re-running CMake should fix this, but you should probably move away from using GLOB to collect your source files. For example, you can list them explicitly as follows:
set(SOURCES src/main.cpp src/Softwares.cpp src/SoftwaresConfigurations.cpp)
I will explain what happened below.
The official documentation says the following:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
So what probably happened is that you created the project with just one source file. CMake ran the GLOB at configuration-time and found only the one .cpp file.
Then, you added two files (which CMake did not know about) and added the #include to your SoftwaresConfiguration.cpp. This triggers a rebuild. However, since CMake does not know about Softwares.cpp, it does not build that file and the linker produces an unreferenced symbol.
I am a novice in the field of CMake and I want to compile an example from OpenMVG official samples. However, I do not how to link the third library by CMake. The following is the part of the C++ file that I want to compile.
#include "openMVG/features/feature.hpp"
#include "openMVG/features/sift/SIFT_Anatomy_Image_Describer.hpp"
#include "openMVG/features/svg_features.hpp"
#include "openMVG/image/image_io.hpp"
#include "openMVG/image/image_concat.hpp"
#include "openMVG/matching/regions_matcher.hpp"
#include "openMVG/matching/svg_matches.hpp"
//
#include "third_party/stlplus3/filesystemSimplified/file_system.hpp"
#include <cstdlib>
#include <string>
#include <iostream>
My CMake file is as the following.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -std=c++11")
add_executable(openMVG_sample_features_siftPutative siftmatch.cpp)
find_package(Eigen3 3.3 REQUIRED)
target_link_libraries(openMVG_sample_features_siftPutative
openMVG_image
openMVG_features
openMVG_matching
Eigen3::Eigen
${STLPLUS_LIBRARY})
target_compile_definitions(openMVG_sample_features_siftPutative
PRIVATE -DTHIS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
set_property(TARGET openMVG_sample_features_siftPutative PROPERTY FOLDER OpenMVG/Samples)
However, I cannot let the cmake find the file of "third_party/stlplus3/filesystemSimplified/file_system.hpp". I have tried several times and I always got the error that file_system.hpp is not found
Like YaleCheung said, you do not have the path to your include.
Now your second problem is that you do not provide to your project the compiled-object of the method used (from the 3rdlib includes).
To fix this, as you did for the eigen3 library where you have a find_package which (certainly) defines where to find the include and the lib, you should have the equivalent for your third_party library.
So I would add:
include_directories (${thirdLib_INCLUDE_DIRS}) # I let you define this variable (could be define while the configure process)
and then: I think your linking problem is coming from the fact that ${STLPLUS_LIBRARY} might not contain path and lib. Try to "message()" in your cmakelists to see the content of your variable ${STLPLUS_LIBRARY}
I want to compile this example in vtk, which includes the following include files:
#include <vtkSmartPointer.h>
#include <vtkObjectFactory.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkActor.h>
// headers needed for this example
#include <vtkImageViewer2.h>
#include <vtkDICOMImageReader.h>
#include <vtkInteractorStyleImage.h>
#include <vtkActor2D.h>
#include <vtkTextProperty.h>
#include <vtkTextMapper.h>
// needed to easily convert int to std::string
#include <sstream>
Originally it should be compiled with a CMakeLists.txt-file which looks like:
cmake_minimum_required(VERSION 2.8)
PROJECT(ReadDICOMSeries)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
add_executable(ReadDICOMSeries MACOSX_BUNDLE ReadDICOMSeries)
if(VTK_LIBRARIES)
target_link_libraries(ReadDICOMSeries ${VTK_LIBRARIES})
else()
target_link_libraries(ReadDICOMSeries vtkHybrid vtkWidgets)
endif()
The problem is: When I simply copy this code and compile it, I get a lot of reference errors (for example: Undefined reference to 'vtkDICOMImageReader::SetDirectoryName(char const*)'). This leads me to the assumption that I should link some libraries to it. Unfortunately the CMakeLists-file does not tell me which libraries. How do I find that out?
Cmake is really strongly suggested for compiling VTK and related projects, especially as a beginner. I only use CMake, but I got an idea of what happens under the hood by checking the properties of the projects already built. In the example you provided, the CMake file only use "target_link_libraries(ReadDICOMSeries ${VTK_LIBRARIES}" , as far as I understood that it is providing to the linker ALL the libraries built with vtk.
To see what CMake will load with that instruction, check the file "VTKConfig.cmake" in the vtk build directory.
If you do it manually, you will also have to include a lot of directories
I managed to figure this out without using CMake directly or having to dig into each individual lib.
find a header file or C/CPP file that defines the object that's giving you linker pain.
Do a find-in-files of the *.cmake files that came with VTK, searching for that filename. So in your case, look for vtkDICOMImageReader.
I found vtkDICOMImageReader in vtkIOKit.cmake, so a decent guess might be libvtkio.
In my case, I was hunting for vtkDataSetAttributes, and this method successfully determined it was in vtkFiltering.lib.
If you've already got Cmake set up then doing it correctly might be easier, but I didn't want "set up vtk" to turn into "set up cmake so I can set up vtk" and then into "set up some other thing so I can set up cmake so I can set up vtk".
This seems like something that should be easy to do, but I cant for the life of me figure out how to do it.
Basically, I want to take a source lists (for now, just a variable ${HDR_LIST}), and write them ALL as includes in a file. so if HDR_LIST="foo.h;bar.h;baz.h;quz.h" it would make the file
#include "foo.h"
#include "bar.h"
#include "baz.h"
#include "quz.h"
I'd like this file to only update if HDR_LIST changes.
The only way I can think to do it is to make a configure_file command...but this macro may be in a ton of places. Each each project sets the variable, I'm not sure how safe that is. I feel like there should be a better way...
cmake_minimum_required(VERSION 2.8)
project(MyTest)
set(CMAKE_CONFIGURABLE_FILE_CONTENT
"#include \"inc1.h\"")
set(CMAKE_CONFIGURABLE_FILE_CONTENT
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n#include \"inc2.h\"")
set(CMAKE_CONFIGURABLE_FILE_CONTENT
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n#include \"inc3.h\"")
set(CMAKE_CONFIGURABLE_FILE_CONTENT
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n#include \"inc4.h\"")
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
"${CMAKE_CURRENT_BINARY_DIR}/myfile.h"
#ONLY
)
unset(CMAKE_CONFIGURABLE_FILE_CONTENT)
configure_file has a built-in write-only-if-different.
I think you are looking for some combination of foreach() and file(APPEND ...):
file(REMOVE "includes.h")
foreach(filename ${HDR_LIST})
file(APPEND "includes.h" "#include \"${filename}\"")
endforeach(filename)
Whenever HDR_LIST is changed, CMake will be run again and the file will be regenerated.
If you want to write the file only if different, it is a bit hard, because AFAIK, there are not dependencies on variables in CMake. But you could do e.g. this workaround with some hashing:
set(new_includes "")
foreach(filename ${HDR_LIST})
set(new_includes "${new_includes}#include \"${filename}\"")
if(WIN32)
set(new_includes "${new_includes}\r\n")
else()
set(new_includes "${new_includes}\n")
endif()
endforeach()
string(SHA256 new_includes_hash "${new_includes}")
file(SHA256 "includes.h" current_includes_hash)
if(NOT current_includes_hash STREQUAL new_includes_hash)
file(WRITE "includes.h" "${new_includes}")
endif()