How to get AUTOMOC to find header file in QT5 - qt

I'm using Qt 5 and I put all my headers in separate include folders, and AUTOMOC is unable to find my headers.
src
|- sim
|- include
|- sim
|- client.h (contains Q_OBJECT)
|- client.cpp
My CMake Code:
set(CMAKE_AUTOMOC ON)
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
add_library(client client.cpp)
target_include_directories(client PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
target_link_libraries(client sim Qt5::Widgets)
This results in undefined references to my signals because the QObject MOC class in client is not being generated. I tried adding this to force it to search for client.h...
#include "moc_client.cpp"
However then I get the error
AutoMoc error
-------------
"/home/peter/projects/smartmouse/smartmouse-simulator/src/sim/client.cpp"
The file includes the moc file "moc_client.cpp", but the header "client.{h,hh,h++,hm,hpp,hxx,in,txx}" could not be found.
I get why this is, because the docs only say it searches the current folder so it's not going to look int the include/sim folder. My question is how do I get AUTOMOC to find include/sim/client.h?
I also tried using qt5_wrap_cpp but it doesn't seem to actually call the moc compiler, it only sets up some information. I tried:
qt5_wrap_cpp(client include/sim/client.h)
But it did not generate any cmake targets as far as I can tell
EDIT:
I've also noticed in the AutogenInfo.cmake file that no header is found: set(AM_HEADERS "")

I just ran into this similar issue and while I'm not satisfied with this answer, it might be helpful.
CMAKE_AUTOMOC is not picking up client.cpp's #include "sim/client.h" but you can manually add it to the target sources:
add_library(client client.cpp include/sim/client.h)

Related

Creating a test project for QML QtQuick

I have a QLM project MyProject compiled with CMake, for which I wanted to add tests.
I figured I would create another project MyProject_tests, and a top level CMakeLists containing both :
MetaMyProject
|-CMakeLists.txt (1)
|-MyProject
| |-CMakeLists.txt (2)
|-MyProject_test
| |-CMakeLists.txt (3)
First CMakeLists contains
cmake_minimum_required(VERSION 3.3)
project(MetaMyProject CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
add_subdirectory(MyProject)
add_subdirectory(MyProject_Test)
Second CMakeLists is not changed, except I added set_property(TARGET ${PROJECT_NAME} PROPERTY ENABLE_EXPORTS 1) at the end.
Third CMakeLists contains
cmake_minimum_required(VERSION 3.1)
project(MyProject_ContraintsTest)
find_package(Qt6 COMPONENTS QuickTest REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCE_FILES
main.cpp
)
set(HEADER_FILES
)
set(QML_TESTCASE_FILES
testcases/tst_test.qml
)
add_definitions(-DQUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}/testcases")
add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES} ${QML_TESTCASE_FILES})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::QuickTest)
Now for the component defined in MyProject to be available in MyProject_test, I wanted to add on the last line a PIVATE MyProject. It does not raise warning, but import MyProject does not work then.
What is the correct way to link my test project to the base project in order for all the components to be available in the test project?
ENABLE_EXPORTS enables symbol exports from an executable, these symbols can be used in another library or executable. To be able to use a symbol in your qml, you would need to re-register the exported Qt Class in your MyProject_test/main.cpp using:
qmlRegisterType<MyExportedClass>("MyExportedClass", 1, 0, "MyExportedClass");
Then you would be able to use it with import MyExportedClass 1.0

qtserialport with CMake in qtcreator-ros-plugin?

I'm trying to compile qtserialport to my project in QtCreator4.9.2 with ROS plugin in.
Of course, I had follow the doc to install qtserialport to my Ubuntu16.04. And then, I had do some tests like this:
#include "QtSerialPort/qserialport.h"
#include "QtSerialPort/qserialportinfo.h"
...
Q_FOREACH(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
ROS_INFO("Name: %s", info.portName().toStdString().c_str());
ROS_INFO("Description: %s", info.description().toStdString().c_str());
ROS_INFO("Manufacturer: %s", info.manufacturer().toStdString().c_str());
...
}
But, get erros:
undefined reference to 'QSerialPortInfo::availablePorts()'
undefined reference to 'QSerialPortInfo::portName() const'
undefined reference to 'QSerialPortInfo::description() const'
...
undefined reference to 'QSerialPortInfo::~QSerialPortInfo()'
You know, I'm working with CMake, so the official docs about qmake or .pro introductions is useless to me. And I had find some suggestions like this, however, I'm confused with this: how to make the qtserialport as a module?
Anyway, all I want to say is that: how can I compile qtserialport with my ros CMake project? And certainly, it should also work with my QtCreator.
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.0)
project(xxx)
add_compile_options(-std=c++11)
find_package(catkin REQUIRED COMPONENTS qt_build roscpp)
include_directories(${catkin_INCLUDE_DIRS})
catkin_package()
rosbuild_prepare_qt4(QtCore QtGui QtOpenGL)
file(GLOB QT_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} rsources/*.qrc)
file(GLOB_RECURSE QT_MOC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} FOLLOW_SYMLINKS include/xxx/*.hpp)
QT4_ADD_RESOURCES(QT_RSOURCES_CPP ${QT_RESOURCES})
QT4_WRAP_CPP(QT_MOC_HPP ${QT_MOC})
set(QT_SOURCES ...)
if(MSVC)
set(...)
endif(MSVC)
add_definitions(...)
include_directories(...)
set(EXTERNAL_LIBRARIES OpenThreads osg osgDB osgViewer osgUtil osgText osgGA pthread lz4 bz2)
add_executable(... ${QT_SOURCES} ${QT_RESOURCES_CPP} ${QT_MOC_HPP})
target_link_libraries(xxx ${QT_LIBRARIES} ${EXTERNAL_LIBRARIES} ${catkin_LIBRARIES})
install(TARGETS xxx RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
Help!
QtCreator4.9.2 is your IDE's version, not the framework's version you probably are using Qt 5.1x.x version.
If you want to compile out of your IDE this line is essential
set(CMAKE_PREFIX_PATH your/qt/path/which/can/be/obtained)
check this path from QT Creator > Open a Qt Project > Projects option on Left bar > Project Build Option, on CMake settings check cmake_prefix_path
# Before add_executable
find_package(Qt5 COMPONENTS Core SerialPort REQUIRED)
# After add_executable
target_link_libraries(${PROJECT_NAME} PRIVATE
Qt5::Core Qt5::SerialPort)
You also can learn package names under CMake folder of your Qt path.
/your/sys/path/Qt5/lib/cmake

How to get platform dependent output filename with QMake?

Assume I have a qmake project file *.pro:
# some stuff ...
TARGET = my_binary
# other stuff...
include( $$PWD/post.pri )
And inside the post.pri file (because I would like to reuse whatever this *.pri file does), I would like to get the complete name of the output file.
For example if is an app, then on windows I would like to get my_binary.exe and on linux my_binary. Or if the project is a shared lib, I would like to get my_binary.dll or libmy_binary.so respectively. Same if is a static lib, I would expect my_binary.lib and libmy_binary.a.
I have already tried the undocumented qmake variable QMAKE_FILE_OUT but with no success.
You can do this in your .pro script:
load(resolve_target)
message($$QMAKE_RESOLVED_TARGET)
It will output the build path and target name, according to your platform and project TEMPLATE.

QT: No rule to make target 'res/resources.qrc'

I've switched versions of QT (from 5.10.1 to 5.12.2) to get a more recent version of Mingw32 (from GCC/G++ 5.3 -> 7.3). The reasoning behind this is that have multiple products using the same library and using an old version of gcc is less than ideal. We've never had any issues with build before, but now I get the following error:
":-1: error: No rule to make target 'res/resources.qrc', needed by 'release/qrc_resources.cpp'. Stop."
Oddly enough, it does not stop the build from generating a completely functioning executable.
So far I've tried:
Cleaning the directory and building again
Deleting the build directory and building again
Not selecting shadow build option
Forcing Qmake (Build -> Run Qmake)
Creating a new .pro.user file
Deleting the whole repo, cloning it again, rebuilding the dependencies (we have a library which it relies on) and rebuilding QT
Adding the .qrc file to the includes (I know this was silly, but I was at my wits end)
Checking for deleted files (None that I can see)
Checking file names for inconsistencies(They seem ok)
Here is my qrc file
<RCC>
<qresource prefix="/">
<file>images/cnctbtn_connected.png</file>
<file>images/cnctbtn_connecting.png</file>
<file>images/cnctbtn_disconnected.png</file>
<file>images/configbtn.png</file>
<file>images/flash.png</file>
<file>images/logbtn.png</file>
<file>images/streambtn_start.png</file>
<file>images/streambtn_stop.png</file>
<file>images/d_logo_outlined.ico</file>
<file>images/d_logo_small.png</file>
<file>images/d_logo_small_outlined.png</file>
</qresource>
</RCC>
The list of resources which are located in the images folder
cnctbtn_connected.png
cnctbtn_connecting.png
cnctbtn_disconnected.png
configbtn.png
d_logo_small.png
d_logo_small_outlined.png
flash.png
logbtn.png
streambtn_start.png
streambtn_stop.png
d_logo_outlined.ico
The qrc_resource_File.cpp also looks ok. I see the bytes of the images in it, their names and assorted namespace declarations and functions in that name space.
The one thing I'm unsure of is why the images folder has it's on name in the resource name list.
Note: I've removed the bytes in this array, for my eyes and yours.
static const unsigned char qt_resource_name[] = {
// images
// cnctbtn_disconnected.png
// cnctbtn_connected.png
// cnctbtn_connecting.png
// streambtn_start.png
// d_logo_outlined.ico
// d_logo_small.png
// streambtn_stop.png
// d_logo_small_outlined.png
};
Ideally there would be no build error, which I don't really understand since I can see and use the executable produced. If you need any other information, don't hesitate to ask!

Deploy QT plugin with its own DLL depences

I have a QT application app.exe and a QT plugin plugin.dll. My plugin.dll depends on many other dynamic libraries (e.g. lib1.dll, lib2.dll and so on). To distribute my project I have this folder structure (ignoring QT libraries):
app.exe
plugins\
plugin.dll
lib1.dll
lib2.dll
lib3.dll
The problem is that there are too many dependences on libX.dll and I want to hide them in a plugin folder, e.g.:
app.exe
plugin\
plugin.dll
lib1.dll
lib2.dll
lib3.dll
But this way libraries libX.dll are "unseen" to my plugin, so that it cannot be loaded. Is there any way to solve this problem?
I am using this code to import libX.dll in plugin.dll's pro-file:
LIBS += -Lpath -l lib1 -l lib2 -l lib3
One of the ways of solving this problem is:
Link all libraries dynamically (at runtime)
Add extra location to search for the libraries
These changes should be done in plugin.dll code:
/* Declare a pointer to import function */
typedef void (*FUNCTION)();
FUNCTION f;
/* Make system search the DLLs in my plugin folder */
// Variable "app" contains directory of the application, not the plugin
QDir app = QDir(qApp->applicationDirPath());
// Combine path
QString plugin_path = app.filePath("plugins/");
// Adding full path for DLL search
SetDllDirectory(plugin_path.toStdWString().c_str());
/* Linking the library */
QLibrary mylib("mylib.dll");
f = (FUNCTION ) mylib.resolve("function");
if (f != NULL)
f(); // You got the function from DLL
else
return; // DLL could not be loaded
This solution has disadvanges:
It is not platform independent (I think you can avoid using SetDllDirectory in UNIX-like systems but I am not sure)
If you import a lot of functions you will have a lot of pointers
Does any one know pure Qt solution?

Resources