In QMake:
CONFIG += console
How do I get the same effect in CMake?
(specs: Qt 5.0.2, CMake 2.8.10)
You don't do anything: for CMake, it's the default. If you want a Windows application, you'll need to add the WIN32 options to the call to add_executable:
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
This will set the linker to look for WinMain instead of main as you'd expect for a Windows GUI app, by setting the CMake internal WIN32_EXECUTABLE.
To ensure qDebug() works correctly, you can add:
/* In Header */
#include <QLoggingCategory>
/* After creating QApplication instance */
QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
Related
Recent articles about GTK4 detail the changes required for displaying application icons. This article in particular is very helpful in explaining how to deploy desktop files and icons.
I am seeing an issue where the application icons display correctly with GTK3 apps, but the default widget icon displays for GTK4 apps. One thing to mention up front is that I am running Ubuntu 22.04 LTS with the latest updates inside a VirtualBox VM hosted under Windows 10.
To test this behavior, I have created a file called HelloWorld.c that contains the following code, which is derived from The GTK Project's Getting Started page and compiles successfully under both GTK3 and GTK4:
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_window_present (GTK_WINDOW (window));
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
The file resides in a folder called "$HOME/Projects/HelloWorld3,4" and is compiled to produce executables named HelloWorld3 and HelloWorld4 as follows:
gcc `pkg-config --cflags gtk+-3.0` HelloWorld.c -o HelloWorld3 `pkg-config --libs gtk+-3.0`
gcc `pkg-config --cflags gtk4` HelloWorld.c -o HelloWorld4 `pkg-config --libs gtk4`
HelloWorld3.desktop is as follows. To simplify matters for this example, I am not installing any custom icons. There is already an icon called "preferences-color.png" under /usr/share/icons/hicolor/(icon size)/apps. Of course, "(my home folder)" is simply a placeholder for this example; the actual file on my system contains the correct full path to the executable.
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Name=Hello World GTK 3
Exec=/(my home folder)/Projects/HelloWorld3,4/HelloWorld3
Comment=Hello World with Application-Specific Icon
Icon=preferences-color
Terminal=false
Categories=Utility;GTK;
X-Desktop-File-Install-Version=0.26
HelloWorld4.desktop is as follows (again, "(my home folder)" is simply a placeholder for this example):
#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Encoding=UTF-8
Type=Application
Name=Hello World GTK 4
Exec=/(my home folder)/Projects/HelloWorld3,4/HelloWorld4
Comment=Hello World with Application-Specific Icon
Icon=preferences-color
Terminal=false
Categories=Utility;GTK;
X-Desktop-File-Install-Version=0.26
According to the article I referenced at the top of this post, the desktop files can either be copied to $HOME/.local/share/applications or installed under /usr/share/applications using desktop-file-install. Both methods have been attempted, with the same results. For sake of completeness, the latter method was used as follows:
sudo desktop-file-install --dir=/usr/share/applications ./HelloWorld3.desktop
sudo desktop-file-install --dir=/usr/share/applications ./HelloWorld4.desktop
After all is said and done, launching HelloWorld3 shows the preferences-color icon, but launching HelloWorld4 shows the default widget icon. Rebooting has no effect on the outcome.
Hopefully I have provided enough information, but please let me know if you have any questions. Any suggestions on where the issue may lie would be very helpful.
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
A very simple Qt project fails to build for me with Qt 5.10 in a Docker container (with an image derived from opensuse:tumbleweed). The project is as follows:
sh-4.4# cat test.pro
TEMPLATE = app
TARGET = test
INCLUDEPATH += .
INCLUDEPATH += sub
HEADERS = obj.h sub/iface.h
SOURCES = obj.cpp main.cpp
sh-4.4# cat sub/iface.h
#pragma once
#include <QtPlugin>
class Interface
{
public:
virtual ~Interface () {}
};
Q_DECLARE_INTERFACE (Interface, "org.meh.interface/1.0")
sh-4.4# cat obj.h
#pragma once
#include <QObject>
#include <sub/iface.h>
class Obj : public QObject
{
Q_OBJECT
Q_INTERFACES (Interface)
};
sh-4.4# cat obj.cpp
#include "obj.h"
sh-4.4# cat main.cpp
int main() {}
In this case moc complains as follows:
obj.h:9: Error: Undefined interface
Everything is fine in another container with Qt 5.9, and everything is also fine with Qt 5.10 when the project is built in openSUSE Build Service (which uses something else instead of Docker). Some quick googling did not reveal any relevant bugreports for recent Qt versions.
What could be wrong?
Running moc under strace shows Operation not permitted on various statx calls, which sheds some light on why exactly it fails (also, related to this question). This pull request is hopefully going to fix this.
Did you try to run the container with the --privileged (see Which capabilities are needed for statx to stop giving EPERM)?
I can see only one merit of the feauture: we are able to issue the make all commad.
Well, I do not call make in any point of my developer's life. I use Qt Creator and when I build the project I want it strictly as debug or as release. I guess this is an expeted behaviour by people.
But debug_and_release is on by default in Qt Creator. Is there a merit in this I can't see? Is there some sense in the unintuitive mess like this:
CONFIG( debug, debug|release ) {
# debug
} else {
# release
}
which people are learning by making mistakes and asking WTF questions all over the internet?
Am I missing something?
I switch it off:
CONFIG -= debug_and_release
CONFIG( debug, debug|release ) {
CONFIG -= release
}
else {
CONFIG -= debug
CONFIG += release
}
UPD.
I've got it. My question is completely wrong. debug_and_release have not much to do with debug and release.
The debug_and_release option has almost nothing to do with qmake's "debug" and "release" build-modes, learn build-modes in the other answer:
https://stackoverflow.com/a/75194443/8740349
What's debug_and_release option?
CONFIG += debug_and_release just asks qmake.exe to generate the "Makefile" file in a way that supports building both build-modes.
In details:
debug_and_release causes qmake to parse script 3 times:
Once without changing the build-mode which IDE sets.
Once with ensuring CONFIG variable sets release as build-mode.
Once with ensuring CONFIG variable sets debug as build-mode.
And that in above order (at least, if tested with qmake version 3.0).
Which normally results in qmake generating 3 files:
Makefile
Makefile.release
Makefile.debug
Where the "Makefile" file takes around 10 times less space,
and does nothing but redirecting "make.exe" to "Makefile.release" file or "Makefile.debug" file.
However, if your script logs a single warning, qmake spams 2 additional warnings, which can be work-arounded by useing like:
!build_pass: warning("My message shown in IDE")
Or:
!build_pass {
warning("My message shown in IDE")
}
Or:
if (!build_pass) {
warning("My message shown in IDE")
}
I'm trying to write a test suit for my Qt(c++) application using google test, the main problem is that my application consists of one main program and various shared libs. Everything was working just fine, until I tried to do some code coverage using gcov/lcov (which don't operate on dynamic libs), so I modified all my .pro file to have a static lib compilation using :
CONFIG += staticlib create_prl
QMAKE_LFLAGS += -static
LIBS += ../../Libs/lib*.a
The problem is that google test test application is something like this:
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
so it detects the linkage at runtime, which means that when I compile the test application here is no warning or whatever that indicate a problem, and when running the test application it execute 0 test because it doesn't found any.
my solution (quit annoying one) is to define in each class which will be used for test a phony public static member and do an operation for the main test application on it:
class SETTINGS_TESTS_SHARED_EXPORT SettingsTests: public testing::Test {
public:
SettingsTests();
virtual ~SettingsTests();
static bool dummy;
protected:
virtual void SetUp();
virtual void TearDown();
private:
Settings* _setting0;
Settings* _setting1;
Settings* _setting2;
};
using namespace MBI::SETTINGS;
using namespace MBI::TESTS;
int main(int argc, char **argv) {
SettingsTests::dummy = true;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
so I can force the linkage of that lib on my application.
I have also found the option -u to do something like that in gcc but doesn't seem to work. have anyone have a way to force static library linking if no symbol can be detected in compile time ?
I don't completely understand the question, it's not explained what ::testing::InitGoogleTest and RUN_ALL_TESTS actually do, and how they're related to dynamic linking.
But: you can make the GNU linker ignore unresolved symbols at link time by using the option --unresolved-symbols=ignore-all , or if you need to pass the option to gcc, -Wl,--unresolved-symbols=ignore-all.
In the google test doc there is a mention of linkage problem with visual c++ dll:
Important note for Visual C++ users
If you put your tests into a library and your main() function is in a different library or in your .exe file, those tests will not run. The reason is a bug in Visual C++. When you define your tests, Google Test creates certain static objects to register them. These objects are not referenced from elsewhere but their constructors are still supposed to run. When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out. You have to reference your library with tests from your main program to keep the linker from discarding it. Here is how to do it. Somewhere in your library code declare a function:
__declspec(dllimport) int PullInMyLibrary() { return 0; }
If you put your tests in a static library (not DLL) then __declspec(dllexport) is not required. Now, in your main program, write a code that invokes that function:
int PullInMyLibrary();
static int dummy = PullInMyLibrary();
This will keep your tests referenced and will make them register themselves at startup.
In addition, if you define your tests in a static library, add /OPT:NOREF to your main program linker options. If you use MSVC++ IDE, go to your .exe project properties/Configuration Properties/Linker/Optimization and set References setting to Keep Unreferenced Data (/OPT:NOREF). This will keep Visual C++ linker from discarding individual symbols generated by your tests from the final executable.
There is one more pitfall, though. If you use Google Test as a static library (that's how it is defined in gtest.vcproj) your tests must also reside in a static library. If you have to have them in a DLL, you must change Google Test to build into a DLL as well. Otherwise your tests will not run correctly or will not run at all. The general conclusion here is: make your life easier - do not write your tests in libraries!
And the solution adopted is pretty much what I did with g++. I'm suspecting the fact that qmake produce intermediary file moc_* and that my code in linked against that.