Add QML files to Qt Creator project tree with CMake - qt

I have a library called qml_components containing basic QML graphical elements. I'd like to add these files to the project tree, without building them. I've been able to regroup them in a variable, by doing the following:
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
CMAKE_POLICY(SET CMP0003 NEW)
PROJECT(myApp)
FILE(GLOB QML_SRC "*.qml")
I then tried to add them to my library target:
# Add QML files to project tree without building/compiling them
ADD_CUSTOM_TARGET(myApp ${QML_SRC})
While researching I read that ADD_CUSTOM_TARGET could add the files to the sources without building them:
The SOURCES option specifies additional source files to be included in the custom target. Specified source files will be added to IDE project files for convenience in editing even if they have not build rules.
It doesn't seem to work. I think the probable cause is that I do not generate any binaries from this library, hence the failure when trying to link the sources to the TARGET.

I had forgotten to add the SOURCES keyword in the command...
ADD_CUSTOM_TARGET(myApp SOURCES ${QML_SRC})
I'm leaving this thread open as it could be of useful information to others.

Related

QML module not found when using KDE Kirigami

So I decided to use KDE Kirigami UI framework in my app so I followed the instructions here. I cloned the repo in my app directory and then added it with a simple include(kirigami/kirigami.pri) in my project file.
Now this works, however the problem I encountered is that in QML there is always the error: QML module not found when I import the plugin (import org.kde.kirigami 2.9). The project still compiles and runs just fine and I am able to use the UI components I need, however the major issue is that code completion and syntax highlighting for the Kirigami plugin do not work.
A similar question has been asked before here, I have tried all the suggestions in the answers of that thread but none of them worked:
I imported QQmlEngine::addImportPath the kirigami/src/controls folders using absolute and relative paths. I also tried with qrc:/.
I added a QML_IMPORT_PATH += $$PWD/kirigami/src/controls $$PWD/kirigami line to my project file.
When you mouse over the "module org.kde.kirigami not found" error marker in a QML file, the popup tells you that Qt Creator is looking in QML_IMPORT_PATH for these files. It also tells you how to set this.
By adding QML_IMPORT_PATH += … to your project file, you have set it for a qmake based build process. However, Kirigami projects usually use CMake, and that might be the reason why your previous attempts did not work out.
To set QML_IMPORT_PATH for a CMake based build system, you would open the CMakeLists.txt file from the root of your project tree and add the following section on top:
# ------------------------- BEGIN: lists to maintain manually -------------------------
# Directories where Qt Creator can find QML files of Kirigami etc. on your system.
# (This setting is cached in variable QML_IMPORT_DIR, see below. Delete
# ${BUIL_DIR}/CMakeCache.txt to make make changes here effective.)
list(APPEND QML_DIRS "/usr/lib/x86_64-linux-gnu/qt5/qml")
# ------------------------- END: lists to maintain manually -------------------------
# Tell Qt Creator where to find QML files.
# (The build process will work without this, but no code completion etc..)
set(
QML_IMPORT_PATH "${QML_DIRS}"
CACHE STRING "Qt Creator 4.1 extra qml import paths"
)
Of course, adapt it to the correct directory for your system. On a Debian / Ubuntu based system, the following will determine the directory containing Kirigami QML files installed from the repositories:
dpkg -L qml-module-org-kde-kirigami2 | grep "\.qml"
Source: another answer on StackOverflow

In Qt, when should you use RESOURCES vs. DISTFILES vs. OTHER_FILES

Within the .pro file, things are straightforward if you're including header files (use HEADERS), C++ files (use SOURCES) and Objective-C / Objective-C++ files (use OBJECTIVE_SOURCES), but it is less clear to me how other file types should be included.
e.g. looking at various examples that Qt provide, there is inconsistency about whether QML files should be DISTFILES, OTHER_FILES or contained within a .qrc file (i.e. RESOURCES). I've gone with putting QML files in a qml.qrc file.
My question has arisen because I'm including data files, such as audio .wav files, within a .qrc file (also as shown in Qt examples; e.g. Qt Quick Demo - Maroon in Trouble) but this has slowed compiling down to a crawl. And in the case of MinGW on Windows, it simply crashes with an out of memory error when it reaches 1GB. There must be a better way to include these!
Could you provide a guide as to when to use:
DISTFILES
OTHER_FILES
RESOURCES
Quoting from the qmake manual:
RESOURCES
Specifies the name of the resource collection files (qrc) for the target. [...]
DISTFILES
Specifies a list of files to be included in the dist target. This feature is supported by UnixMake specs only. [...]
OTHER_FILES
This seems in fact undocumented, at least I could not find anything. As far as I can tell all files listed here are only linked in project explorer (of Qt Creator for example) and are not treated in any way by qmake.
As for your example you might consider shipping the files as they are and not include them in any resource file, because they are compiled into the binary.
You may also take a look at compiling external resources and using them for your large files to keep the simplicity of Qt's resource system.
DISTFILES: Something special for unix you won't use in most cases. From the docs:
Specifies a list of files to be included in the dist target. This
feature is supported by UnixMake specs only.
OTHER_FILES: Files, that are part of you project, but not of the "build". This can be things like a readme, build hints, or any other stuff, that does not fit into any other categories
RESOURCES: .qrc-files, that will be compiled into the application.
Regarding the usage of those three with QML:
You can basicly use DISTFILES or OTHER_FILES for other files. In QtCreator the appear in a node as other files. These two are exchangeable for most developers. The Qt examples are local project, thus either they don't require a resource or have both, i.e. you can find the QML-files in for example OTHER_FILES and RESOURCES.
For QML files, you should always use RESOURCES, to make sure they are within your binary.
Speaking of DISTFILES , you can try it yourself.
Assuming you are using Qt on Windows. Here is a very simple qmake project file project.pro:
TEMPLATE = app
DISTFILES += "C:\Windows\explorer.exe"
qmake it, and you can find the following statements in generated Makefile.Debug and Makefile.Release:
DIST = C:\Windows\explorer.exe
...
dist:
$(ZIP) project.zip $(SOURCES) $(DIST) project.pro
...
The target dist is one of the standard targets. I learned it from makefile - What is the difference between make and make dist? - Stack Overflow.

Qt/CMake difficulty with new source files

I am using Qt in a way that the Qt-related files are in a separate subdirectory GUI, and I am using CMake file, the relevant part of it shown below. Basically this setup works, but when I add a new file (something like an own widget), the new file compiles OK, but in the linking phase the new object is not found. I used to delete the build subdirectory, and after that everything works fine. So, my question: do I wrong something with CMake? (I quess the symptoms are caused by some caching problem)
include_directories(${Qt5Widgets_INCLUDES} GUI/include main/include)
add_definitions(${Qt5Widgets_DEFINITIONS})
file(GLOB_RECURSE QOBJECT_HEADERS
"GUI/include/*.h"
)
file(GLOB_RECURSE QOBJECT_SOURCES
"GUI/*.cpp"
)
QT5_WRAP_CPP(hdr_moc ${QOBJECT_HEADERS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} -std=c++11 -Wall")
add_executable(simGUI main/sim_GUI.cpp ${QOBJECT_SOURCES}
${hdr_moc})
# Use the Widgets module from Qt 5.
target_link_libraries(simGUI Qt5::Widgets)
From CMake doc:
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.
The typical approach is to list all files manually.

Undefined references - I'm including correct header

I'm trying to subclass from ProjectExplorer::ProjectExplorerPlugin but I'm getting error telling me about undefined references. Any ideas how to fix it?
class MyPluginPlugin : public ProjectExplorer::ProjectExplorerPlugin
{
Q_OBJECT
...
};
error: undefined reference to `imp__ZN15ProjectExplorer21ProjectExplorerPluginC2Ev'
The fact that you don't get a compilation error, but an undefined reference usually means that your project knows where the header files are, but it doesn't know where the library is which contains the already compiled source code.
I've never written a plugin for Qt Creator but I've taken a quick look at its source code structure and I see the following options:
Option A)
There is a projectexplorer.pro file in Qt Creator's source under src/plugins/projectexplorer. You could manually build that project in order to get a ProjectExplorer.lib (plus a .dll or a .a) and then reference this library.Example: Assuming the library would be created in the same directory as its .pro file (I have no idea if it is like that) and you created your plugin withing Qt Creator's source under src/plugins/myplugin, you would define your LIBS variable like this:
LIBS += -L../projectexplorer \
-lProjectExplorer
The first line adds "../projectexplorer" as an additional library directory and the second line adds "ProjectExplorer" as a library to search in any of the defined directories (it automatically adds the OS-specific file extensions like .lib on windows etc).
Obviously if your project or the library is located somewhere else, you need to change the first line accordingly.
Option B)
You could include the source and header files of the projectexplorer directory to your own .pro file using the HEADERS and SOURCES variables. I'm not sure if this wouldn't interfere with any other plugins (including projectexplorer itself) though.
Option C)
There probably is a way to include the projectexplorer.pro file so that you have a master project which first builds the project explorer library and then your own plugin. This would be the safest way to go as it ensures the Project Explorer library is built and up-to-date before your own project is linked against it.
However I have limited experience on this.
If anyone reading this can give a detailed explanation on this option, feel free to edit or provide your own answer.
If you are using Qt Creator built from source coded after April 2013 which includes Commit: #66a3553 - make library and plugin dependencies declarative, then you can simply specify dependencies for your plugin in its .pro file:
# myplugin.pro
QTC_PLUGIN_DEPENDS += \
coreplugin \
projectexplorer

Qmake: Avoid file name conflicts in different folders without introducing libraries

I have a project with some folders which happen to contain source files with the same names.
My source tree looks like this:
project.pro
foo/
conflict.h
conflict.cpp
bar/
conflict.h
conflict.cpp
some.h
other.h
files.h
main.cpp
Per default, qmake generates a Makefile which will produce a build tree like this:
conflict.o
main.o
target
Where conflict.o is the object file resulting for both foo/conflict.cpp and foo/conflict.h.
I can't to change their names because they are generated using an external tool and forcing different file names would imply to change their contents, so this is not an option.
I also don't want to use qmake SUBDIRS template because this would imply that (1) every subdir is built separately as a library and thus very much complicate the overall build process (in my eyes at least) and (2) in the top level directory I can't have any source files. Or am I wrong?
Can't I just tell qmake to write the object files into separate directories within the build directory? So my build tree will look like this:
foo/
conflict.o
bar/
conflict.o
main.o
target
Or are there any other solutions neither requiring to rename the source files nor introducing something complicated like static libraries? I just can't believe that Qt didn't solve this (in my eyes simple) problem for years. (I already hat this problem 4 years ago but could rename the files in that project, while here I can't.)
If it's important: I use Qt 4.8 on both Ubuntu with G++ and Windows with mingw32.
Are you tied to qmake? If not, an alternative could be to use cmake. I just verified your usecase with a simple CMakeLists.txt like
cmake_minimum_required (VERSION 2.6)
project (conflict)
add_executable(conflict foo/conflict.cpp bar/conflict.cpp main.cpp)
which even included a source file in the top level directory (main.cpp). This properly builds the executable - the object files are created in sub directories like
./CMakeFiles/conflict.dir/main.cpp.o
./CMakeFiles/conflict.dir/bar/conflict.cpp.o
./CMakeFiles/conflict.dir/foo/conflict.cpp.o
cmake also includes support for Qt4, to automatically pull in the required include paths and libraries. It might require some effort to migrate from qmake to cmake, but given the requirements you have I would give it a try.

Resources