qt4 scons including a uic file in variant_dir - c++

I'm using the qt4 tool for scons and having some troubles getting the .ui files to be handled correctly. I'm coming from a Cmake background with Qt and a beginner with scons.
In my SConstruct file I have
env.Uic4(Glob('*.ui'))
env.Program('test',Glob('*.cpp'))
The problem is that my source file can't find the resulting header files src/qt-test/sample_widget.cpp:3:23: error: ui_sample.h: No such file or directory. The header file is created, as is all moc processing done, thus I'm pretty sure everything is installed correctly and basically correct.
What I think is happening is because this is a recrusive SConstruct file, and the caller is using a variant_dir for the build. So possibly the problem is just getting the compiler to resolve headers in the build directory (and perhaps nothing to do with the qt4 tool). This was handled automatically in CMake (I think).
So how do I get this working (get the ui include file to be found)?

Use the CPPPATH construction variable to set the include paths as mentioned in the man pages:
http://scons.org/doc/production/HTML/scons-user/a4916.html
For example:
env.Append(CPPPATH = ['dir1', 'dir2'])
Brady

Related

Is there "includePath" option in clangd?

I used to work with VSCode C/C++ extension. there was a feature in this extension(in a json file), called "includePath", which I could set the paths for my headers, so without execution of CMake or make, I would have the suggestion of my headers and code completion from those.
now I have switched to neovim and clangd as the language server for code completion. I searched a lot to find the corresponding feature in clangd options but I could not find anything more than this link.
since the clangd is a powerful language server, I am in wonder if there is not such a feature in it. so I want to know is there actually such a feature in clangd? and if YES how can I use that?
Note: I use a language client, called "coc-clangd". I don't know if it matters or not.
Clangd uses compile_commands.json database file which contains flags (such as include directories) for each file in project. But this file is auto-generated, so all modifications to it will be overwritten eventually. You can ask CMake to add any custom compile flags with -DCMAKE_CXX_FLAGS command line argument.
Example for system headers (#include <file.h>):
cmake -DCMAKE_CXX_FLAGS="-isystem /path/to/includes" /path/to/source
For project headers (#include "file.h"):
cmake -DCMAKE_CXX_FLAGS=-Ipath/to/includes /path/to/source
Additionally, you can set CXXFLAGS environment variable:
export CXXFLAGS="-isystem /path/to/includes"
cmake path/to/sources
After that new flags should appear in your compile_commands.json file.
Maybe this is useful: https://clangd.llvm.org/config
Create a file called '.clangd' in the top-level of the source directory.
Add those content.
CompileFlags: # Tweak the parse settings
Add:
- "-I=[folder]"
But I think this is not recommend, all include directories should be add in CMakeLists.txt file.
You can add includePath to clangd.fallbackFlags into vscode's settings.json like this:
"clangd.fallbackFlags": [
"-I${workspaceFolder}/include",
"-I/my/include"
]
To use code completion provided by Clangd, let Clangd retrieve include paths from compiler_commands.json with compiler calls used by CMake. Set the CMAKE_EXPORT_COMPILE_COMMANDS option in CMakeLists.txt, it will output compiler_commands.json to the build directory when CMake is run:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Copy the generated compiler_commands.json to the project source directory. Clangd will now source this file.

pugixml include dir set to not found from pugixml config cmake files

I am trying to compile this project: https://github.com/computationalpathologygroup/ASAP.git from source.
Pugixml is a dependency
I have built pugixml from source and set PugiXML_DIR and PUGIXML_INCLUDE_DIR And it still gives me error: "CMake Error: The following variables are used in this project, but they are set to NOTFOUND."
Things I have tried:
I am doing this on windows, using cmake 3.14 and visual studio 2017.
I have successfully built pugixml from source and included the .lib file as well
I have tried including and excluding combinations of PUGIXML_INCLUDE_DIR, PUGIXML_LIBRARY, PugiXML_DIR.
This is the error I get:
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
cpp/ASAP/annotation/PUGIXML_INCLUDE_DIR
used as include directory in directory
/cpp/ASAP/annotation
cpp/ASAP/multiresolutionimageinterface/PUGIXML_INCLUDE_DIR
used as include directory in directory cpp/ASAP/multiresolutionimageinterface
Other information: setting PugiXML_DIR is mandatory, and the cmake looks for a file named "pugixml-config.cmake" in that directory. And the config cmake file is supposed to point to compiled lib file. But when it wasn't able to find, I simply copied the lib file I compiled to the location pugixml-config.cmake was pointing.
In ASAP versions before 4.04.2019 they play dirty games with extracting include directory from the IMPORTED target. annotation/CMakeLists.txt:30:
get_target_property(PUGIXML_INCLUDE_DIR pugixml INTERFACE_INCLUDE_DIRECTORIES)
In some cases this results in setting PUGIXML_INCLUDE_DIR variable to "-NOTFOUND", thus you got corresponded error message from CMake.
In commit 36d8bd75 they add FindPugiXML.cmake script, which handle find_package(PugiXML) call instead of configuration script shipped with PugiXML. In that find script they obtain include directory with find_path, which looks more natually:
find_path(PugiXML_INCLUDE_DIR pugixml.hpp)
Because in newer ASAP versions the configuration script (pugixml-config.cmake), shipped with PugiXML, is no longer used, one cannot hint about PugiXML location with PugiXML_DIR or PugiXML_ROOT. In case PugiXML is installed into non-system-default location, one may simply set PugiXML_INCLUDE_DIR variable to the PugiXML include directory.

CMake with Xcode: configured header file (.h.in) not found

I'm working through the CMake tutorial and I'm up to the Adding a Version Number and Configured Header File section. Unfortunately Xcode isn't recognising the generated header file:
The error:
The header file was generated by CMake ok:
TutorialConfig.h.in
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR #Tutorial_VERSION_MAJOR#
#define Tutorial_VERSION_MINOR #Tutorial_VERSION_MINOR#
CMakeLists.txt
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}/src")
# add the executable
add_executable(Tutorial src/tutorial.cpp)
This is the tutorial I'm working from.
I don't use Xcode, but another IDE that's Linux based. But maybe I can help you a bit. I'm just wondering -- does your program compile? That's perhaps more important.
My IDE often complains about header files such as your's -- that is, configuration files that are generated by CMake. Such warnings (at least for me) can be ignored. I usually do because my build/ directory is sometimes empty. So when I've opened up the source file, there wouldn't be TutorialConfig.h yet.
In fact, the IDE can never know about such header files. That's because it doesn't know which build/ directory you're going to compile your program in.
If you are worried by the warning, then there is probably a place where you can specify to Xcode which build/ directory to search for header files. That will remove the warning, after you've run CMake once. However, removing such a warning is unreliable because you can always build in another directory that would have TutorialConfig.h missing.
Hope this helps!
Oh, haha. I changed #include "src/TutorialConfig.h" to #include "TutorialConfig.h" and all is well. I figured it out by checking out the project settings:

The right way to structure my c++ project with cmake?

I have been struggling with this for quite a while, and my adventures with cmake have only resulted in hackish solutions that I am pretty sure are not correct.
I created a library that consists of several files, as follows:
-libfolder
-codepart1folder
-CMakeLists.txt
-codepart1.cpp
-codepart1.hpp
-codepart2folder
-codepart3folder
-lib.cpp
-lib.hpp
-CMakeLists.txt
I wrote a CMakeLists file to compile the library (after some experimentation), and I can generate a lib.a file. Now I would like to include this code as a library in other projects, and access it through the interface in lib.hpp. What is the best way to do this, in terms of directory structure, and what I need to put into CMakeLists.txt in my root project?
My current attempt has been to add -libfolder as a subfolder to my current project, and add the commands:
include_directories(${PROJECT_SOURCE_DIR}/libfolder)
link_directories(${PROJECT_BINARY_DIR}/libfolder)
add_subdirectory(libfolder)
target_link_libraries(project lib)
When I run make, the library compiles fine, but when project.cpp compiles, it complains that it cannot find codepart1.hpp (which is included in lib.hpp, included from project.cpp).
I suspect that this is the wrong way about doing this, but I cannot wade through the CMake documentation and find a good tutorial on setting up projects like this. Please help, CMake gurus!
The clean way to import one CMake project into another is via the find_package command. The package declaration is done by using the export command. An advantage of using find_package is that it eliminates the need to hard-code paths to the package's files.
Regarding the missing hpp file, you didn't include codepart1folder, so it's not on the include path.
Ok, so after consulting a coworker of mine who is a CMake guru, it seems CMake does not have support for what I am trying to do, leaving one with 3 options:
Add all of the dependencies to the parent projects CMakeLists.txt - not very clean, but it will get the thing to work. You'll have to do this for every project you add the code to, and go back and fix things if your library changes.
clean up your library headers. This is done through some compiler hackery. The idea is to forward-declare every class, and use only pointers or boost::shared_ptr, and then include the dependencies only in the cpp file. That way you can build the cpp file using all the findpackage stuff, and you get the bonus of being able to use the lib by only including the header and linking to the library.
Look into build systems. Having portable code and fast code compilation with complex dependencies is not a solved problem! From my investigations it turned out to be quite complicated. I ended up adopting my coworkers build system which he created himself in cmake, using things he picked up from Google.
Looking at your post you don't seem to add 'codepart1folder' to the includes anywhere. How are you including codepart1.hpp as:
#include <codepart1.hpp>
#include "codepart1folder/codepart1.hpp"
I don't think there is a standard accepted way to structure cmake projects. I've looked at a bunch of cmake repos and they tend to have differences. Personally I do the following:
-project
CMakeLists.txt
-build
-cmake
OptionalCmakeModule.cmake
-src
-Main
Main.cpp
Main.hpp
-DataStructs
SomeTree.hpp
SomeObject.hpp
-Debug
Debug.hpp
-UI
Window.hpp
Window.cpp
Basically that dumps all the source code into 1 directory, then you perform an out of source build with: 'mkdir build && cd build && cmake .. && make' in the projects root folder.
If you have separate libs as part of your project, then you might want a separate libs directory with another subfolder for your specific lib.
I have some of my repos on: https://github.com/dcbishop/ if you want to look at the CMakeLists.txt files.
The main problems with my project structure are that I use the FILE_GLOB which is apparently the 'wrong' way to do things (if you add files after running 'cmake ..' then they won't be picked up hen you do a 'make'). I haven't figured out what the 'right' way to do it is (from what I can see it involves keeping a separate list of files) I also only use 1 CMakeLists.txt file.
Some projects also choose to separate their cpp and hpp files into separate directories. So you would have an include and src folders (at least for the hpp files that are intended to be used externally). I think that would mainly be for projects that are mainly large libraries. Would also make installing header files much easier.
You are probably missing
include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder)
In such a case you might want to set( CMAKE_INCLUDE_CURRENT_DIR on) to add all folders to the include directory path variable.
Check cmake's output on the command line whether the correct include folders are set or not. Additionally you can always use message() as "print debugging" for cmake variables.
In case of include directories however you need to read the directory property to see what is actually in the include directories.
get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
message("inc_dirs = ${inc_dirs}")
I hope this helps you figuring out what is missing.
Edit
I just saw your comment about added codepart1folder in the libfolder. It is only available in the libfolder's include_directory path and not propagated to the root folder.
Since the include codepart1.hpp is present in the lib.hpp however you need to have it also available in the project path otherwise you will get missing declaration errors when you build your project.

QAction: No such file or directory

I'm getting the error
QAction: No such file or directory
when I try to compile a project for plugin (C++ Library template). Weird, because I have a project for my app which also includes this header and there is no error. What might cause this?
For me I had some stale moc_ and ui_ files left over from compiling under a different version and configuration of Qt, so removing them solved the problem for me.
rm moc_* ui_* *.o
Make sure that you have the right include paths set up.
If you use QMake the *.pro should contain these settings if you want to include files from QtGui. They should be set by default but some templates may not set them.
CONFIG += qt
QT += gui
If you use another build system then make sure that you either use
#include <QtGui/QAction>
or you add $QTDIR/include/QtGui and not just $QTDIR/include to your include path