Qt/CMake difficulty with new source files - qt

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.

Related

Qt using CMake: ui_mainwindow.h: No such file or directory

I use Qt with CMake because CMake integrates with my team's work easier than my own. I have frequently encountered an error along the lines of
ui_*.h: No such file or directory
Usually when my project already has a ui_*.h file to start with it will just modify that .h file. I do use the below commands in my CMake file, so it should be wrapping my .ui file with the appropriate ui_*.h file.
qt4_wrap_ui (mainwindow mainwindow.ui)
target_linked_library (mainwindow ${QT_LIBRARIES})
But sometimes that doesn't work and I have to completely rebuild the entire ui_*.h file. What am I doing wrong?
For anyone having this problem in the future. I pretty much followed the demo here.
http://doc.qt.io/qt-5/cmake-manual.html
Adding, the following line to the CMakeLists.txt should get rid of this problem.
set(CMAKE_AUTOUIC ON)
From the CMake documentation at
https://cmake.org/cmake/help/v3.0/prop_tgt/AUTOUIC.html
AUTOUIC is a boolean specifying whether CMake will handle the Qt uic code generator automatically, i.e. without having to use the QT4_WRAP_UI() or QT5_WRAP_UI() macro. Currently Qt4 and Qt5 are supported.
One small note, this property is available in CMake versions 3.0.2+. So below that, #rbaleksandar's solution should be more appropriate.
Hope that helps.
The quick solution is to use UIC. In bash navigate to the directory containing your *.ui file and run (for the mainwindow.ui example)
uic mainwindow.ui -o ui_mainwindow.h
and then move the newly generated ui_mainwindow.h file to your build directory.
mv ui_mainwindow.h ../build_Qt_4_8_5-Debug/
You shouldn't see the 'No such file or directory' error anymore and can confidently move on to the many other wonderful errors to find in the world of Qt with CMake.
If I remember correctly you actually have to add your UI files to the add_executable(...) like this:
qt4_wrap_ui(UI_HEADERS mainwindow.ui ...) # Add all UI files here like you've done it
...
add_executable(${PROJECT_NAME} ${SRC} ${UI_HEADERS}) # Add them to the executable
...
After all UI files are actually converted to header and source files, which naturally have to be compiled along with the rest of your code.
Building with CMake seems to have an error in
if(CMAKE_VERSION VERSION_LESS "3.7.0")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
remove if in your CMakeLists.txt like this:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
This works in my system with CMake 3.12.1 and Windows 10.
when the ui files are stored in a different location the CMAKE_AUTOUIC_SEARCH_PATHS can be set to include the custom locations so that the CMAKE_AUTOUIC option will find the ui files.
None of the previous answers have helped me.
I tried Ctrl + RMB on #include "./ui_mainwindow.h" in Qt Creator and after that the error did not appear since.
Few details to mention:
set(CMAKE_AUTOUIC ON) was enabled before add_executable()
cmake_minimum_required(VERSION 3.5)
I was using qt6

Add QML files to Qt Creator project tree with CMake

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.

How to add a 'non-built' file to a project with C-Make

I have been searching about this for a couple of hours but couldn't find a solution, so asking.
I have a solution of projects that includes about 10 projects. But I'm facing a dependency problem. One of my projects generates moc files (QT moc file that was generated by 'QT4_WRAP_CPP' macro of Cmake) and I would like to use this moc file in another project. For now, after running the cmake script and getting the solution, I build all projects and the project that need those moc files generated by previous project complain about linking errors(rightly because I didn't point any file to it in its c-make script in ADD_EXECUTABLE section).
My question is: is there any way to add a 'not built yet but will' file to a project in Cmake to point it meanwhile writing the cmake script?
Here is related section of the cmake script of the project:
//suppose that X projects (which is also in this solution and built before Y project) generates a moc file with the name 'moc_X.cxx'
SET(Y_WORK_STATION_UI_HEADER YWorkStation.h
YSignInWidget.h
YConfigurationWidget.h)
QT4_WRAP_CPP(MOCSrcs ${Y_WORK_STATION_UI_HEADER})
ADD_EXECUTABLE(${PROJECT_NAME}
main.cpp
.
.
.
${MOCSrcs}
%---------------->and here something like moc_X.cxx ?
}
Hope it is clear enough. Thanks in advance.
If the file is generated by something CMake understands (that is, by a custom command in the same CMakeList), you can just list it and CMake will pick up the dependency by itself. For other cases, there is a source file property GENERATED which you can set on the source file to indicate it will be generated during build:
add_executable(${PROJECT_NAME}
main.cpp
.
.
.
${MOCSrcs}
moc_X.cxx ?
)
set_property(SOURCE moc_X.cxx PROPERTY GENERATED TRUE)
You seem to be doing several wrong things.
To start:
What do you mean by 'another project'? Do you actually mean 'another target'?
Why is one project using the moc files of another project? Is it also using the source files of that project? Why?
Why don't you use a static (or other) library if that's your goal? If using the source files of the other project makes sense for some reason (I imagine creating a unit test), then you should probably re-moc the files instead of trying to grab them from another implementation-detail location.

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