How to use qmllint in Qt Creator? - qt

qmllint is a syntax checker for QML files written by KDAB which is shipped as a plugin with Qt 5.4. It's usage is based on command line like:
$ qmllint myFile.qml
Is it possible to use it directly in Qt Creator?

QtCreator
You can actually set custom commands in QtCreator to be run without cluttering your qmake file manually because that will effect all the other people in your project, too.
So, if you want to make sure that you only do it for yourself and not clutter it for others, using QtCreator's shiny GUI, I would suggest to follow this:
Projects (left pane)
Build & Run
Build Steps
Add Build Step
Here is the screen how exactly you can set up the command with the corresponding arguments:
With QtCreator's GUI, you can easily change the order with the same concept without touching your project file should you prefer that. There are use cases for that like:
You would not want to run any steps, not even qmake, before the qml file is properly validated
You only have C++ files, so there is no such a thing as "linkage".
etc.
qmake
There are other "generic" approaches useful outside QtCreator, although you asked about this IDE, like putting the command into variables like:
QMAKE_PRE_LINK
QMAKE_PRE_LINK = qmllint $$PWD/path/to/myFile.qml
QMAKE_POST_LINK
QMAKE_POST_LINK = qmllint $$PWD/path/to/myFile.qml
System command execution from your qmake project file
system("qmllint $$PWD/path/to/myFile.ml")
Adding custom targets with QMAKE_EXTRA_TARGETS
qmllinttarget.commands = qmllint $$PWD/path/to/myFile.qml
QMAKE_EXTRA_TARGETS += qmllinttarget

I believe the point in this question is not to have a check for a single file with known name, but to run qmllint on all qml files of a project. Ideally this should be done before building anything, because a build with erroneous qml files is likely to have no real value.
Extending lpapp's answer and playing around with qmake a bit, I came to this solution:
ALL_PWD_QML_FILES = $$files($${_PRO_FILE_PWD_}/*.qml , true)
# a command that creates an empty file with a given name.
win32 {
MY_TOUCH_CMD = copy NUL
} else {
MY_TOUCH_CMD = touch
}
qmllint.output = .qmllint/${QMAKE_FILE_BASE}.qmllint
qmllint.input = ALL_PWD_QML_FILES
qmllint.commands = qmllint ${QMAKE_FILE_NAME} && $${MY_TOUCH_CMD} ${QMAKE_FILE_OUT}
qmllint.CONFIG += no_link recursive target_predeps
QMAKE_EXTRA_COMPILERS += qmllint
This assumes that all qml files are either in the same directory as the .pro file or in subdirectories.
It will run qmllint on all qml files before the actual build, but only if any qml file has changed since a previous build.
Tested on Windows with Qt 5.11 and MSVC.

You can use QMAKE_POST_LINK variable in your .pro file like :
QMAKE_POST_LINK = qmllint $$PWD/QMLFiles/myFile.qml
This runs qmllint on your QML file when you build your project.

Related

How to get the actual qmake build destination within the project file?

I'm trying to determine the build directory in the qmake project file, but failed in all my experiments so far :-(
At first I had a very plain foo.pro as QtCreator generates it for a plain Qt5 gui app with a few source files. Then I added an EXTRA_BINFILES list with some data files. They must be copied in the same directory as the executable foo. Without the copy stuff, it looks like this:
QT += core gui xml webkitwidgets widgets
TARGET = foo
TEMPLATE = app
EXTRA_BINFILES += \
foobar.png \
baz.png
SOURCES += \
main.cpp \
# ...
HEADERS += \
# ...
FORMS += \
# ...
When I build that, I get the foo executable (or foo.exe if you want). Mostly straightforward so far. Now I want to copy the EXTRA_BINFILES alongside this executable. The open question is how to get the destination directory. My best idea so far is adding this:
for(FILE, EXTRA_BINFILES) {
QMAKE_POST_LINK += $$quote($${QMAKE_COPY} $$shell_path($${PWD}/$${FILE}) $$shell_path($${OUT_PWD})$$escape_expand(\n\t))
}
This uses the OUT_PWD variable, which automatically points to where the Makefile is generated. This is nice for some scenarios. However, I have to deal with two different scenarios:
Directly compiling from within QtCreator with mostly out-of-the-box build configs. It creates a new build-foo-desktop-release directory, creates the Makefile there and builds the executable there. In this scenario, everything works fine.
Building from command-line with qmake -makefile /my/projects/foo/foo.pro and make in a temporary fresh build directory. This way it creates the Makefile in directly in that build directory but compiles the executable into a release subdirectory`. This obviously breaks my copy code.
For some reasons, it is not an option to get rid of one of those scenarios. I have to deal with both of them within the same project file. It is also not an option to make very technical/tricky things in the project file. It has to remain mostly as 'straightforward' as it is. Overriding some of qmake's own variables in the qmake command-line call is also probably not an option. This is because of the broader context, which is too extensive to explain here.
Is there an option to get the correct path in both scenarios? Something like OUT_PWD but for the executable itself?
Unfortunately, DESTDIR is empty (and as mentioned, it is not an option to forcefully set it). DESTDIR_TARGET is empty as well (otherwise I could combine it with dirname, which would be barely non-tricky enough).
Any hints?
sub_dir = $$_PRO_FILE_PWD_
sub_dir ~= s,^$$re_escape($$PWD),,
PROJECT_BUILD_TREE = $$clean_path($$OUT_PWD)
PROJECT_BUILD_TREE ~= s,$$re_escape($$sub_dir)$,,

How do I stop Qt Creator placing my executable in a "debug" subdirectory?

I'm building a project in Qt Creator, and while I don't care where the intermediate .obj files go it's important that the final executable be put in (and run from) a particular directory where the many dependency DLLs etc. are to be found.
So, in Qt Creator, I select the 'Shadow Build' option and specify the path to this directory.
What I always find, however, is that instead of being put into this directory, the final executable is always placed into
the_Directory_I_Actually_Want/debug
... which is no use to me because, when I then try to run or debug the program from within Qt Creator, it won't start because the DLLs that it depends on are all in the_Directory_I_Actually_Want and not in the /debug subdirectory.
I've tried setting DESTDIR within my .pro file to the the_Directory_I_Actually_Want, and I've tried setting TARGET within my .pro file to the_Directory_I_Actually_Want/projectName, and I've tried faddling around with the various options that are part of the 'kit' configuration, and nothing seems to let me have any control over this.
Is there a way of doing this, or am I going to have to change the rest of my build system around just for Qt Creator's benefit?
Three years later...
Just use:
CONFIG -= \
copy_dir_files \
debug_and_release \
debug_and_release_target
On Windows you can use DLLDESTDIR variable which specifies where to copy the target dll or exe. Just add this to your .pro :
CONFIG(release, debug|release): DLLDESTDIR += $$PWD/../exec
On Linux you can use QMAKE_POST_LINK variable which contains the command to execute after linking the TARGET together. So it is like:
CONFIG(release, debug|release): QMAKE_POST_LINK += $$quote(cp project $$PWD/../exec)
Here project is the name of the target file which you provide by TARGET = project
These will copy the executable binary to a directory named exec one level upper than the program working directory. You can have your arbitrary path.

Using Qt Creator to develop an Apache2 module

I'm developing an Apache2 module as a subproject of a larger project. The source file is (for example) module_example.c. Apache2 modules are compiled with apxs2, thus:
% apxs2 -c module_example.c
I've successfully added rules (patterned on how ODB works) to my Qt Creator .pro file to find and use apxs2, like this:
APXS_FLAGS =
APXS_FILES += module_example.c
for(dir, APXS_FILES) {
APXS_PWD_FILES += $$PWD/$${dir}
}
apxs.name = apxs2 -c ${QMAKE_FILE_IN}
apxs.input = APXS_PWD_FILES
apxs.output = ${QMAKE_FILE_BASE}.so
apxs.commands = apxs2 $$APXS_FLAGS -c ${QMAKE_FILE_IN}
apxs.depends = $$APXS_PWD_FILES
apxs.clean = module_${QMAKE_FILE_BASE}.so
QMAKE_EXTRA_COMPILERS += apxs
QtCreator correctly compiles the module using apxs2 (although it leaves the binaries in the source directory instead of the build directory, which isn't ideal), but then also tries to compile it with GCC (which fails). How do I tell Qt Creator to use my "extra compiler" instead of the normal one? Changing the extension to something else (module_example.apxs, for example) doesn't appear to be an option, because apxs2 has no option to specify the extension of C source files. Any ideas?
It's not Qt Creator that does it, but qmake. You need to remove module_example.c from SOURCES. The problem is in the part of the .pro file you're not showing.
If you wish to easily access the file from Qt Creator, add it to OTHER_FILES. It will be shown in the project structure in the IDE, but won't be compiled by default.
Also, it's up to you to tell apxs to output to the build path. You need ${OUT_PWD}.

What the right variable to use here, that represents the TARGET field in the .pro file

I would like to add a custom command, that will work on the generated binary file (The target field in *.pro file),
But what should I use here, in the Command arguments
I'm afraid this is not possible. QtCreator only handles source and build directory. The QtCreator documentation says:
The following Qt Creator variables are available:
%{buildDir}
%{sourceDir}
Note that the target even doesn't have to be in the build directory. The build directory is where qmake is ran, typically resulting in the target being put there, because in the .pro file one typically specifies TARGET = projectName.
Further note that the QtCreator build steps configuration only works within QtCreator. This should not be used when your custom build steps are needed for other people working without QtCreator (they should only run qmake and make to build your application).
This being said and assuming that you want to define a post-build step, you should look for a solution to define such in the .pro file (by using the $${TARGET} variable) so that qmake will put your buildstep into the Makefile after the linking step.
If you want to execute a command after linkage, let's say call a custom script (batch script on Windows, otherwise a bourne shell script) with the TARGET as an argument, add the following to your .pro file:
win32 {
poststep.commands = #myScript.bat $${TARGET}
}
!win32 {
poststep.commands = #./myScript.sh $${TARGET}
}
QMAKE_EXTRA_TARGETS += poststep

Can I get qmake -project to add LIBS += .... to my .pro file?

I have a project that uses Qt. So I have "qmake" make my Makefile from the .pro file. But Qmake can also make that .pro file: qmake -project . This worked until I needed to add an external extra library to my project.
I get lots of hits on google that tell me to add LIBS += ... to my project file, but I want to tell qmake -project something that causes it to add it for me. In effect of course I'll be doing it myself, but I don't think that it's proper that I am editing the generated project file.
If for example I add files to the project directory, I'll have to recreate it and add in the library again, or I'll have to manually add the files to the (almost completely computer-generated) project file. I'm now using a script to auto-generate the project file, and then add in the LIBS += directive, but is there a proper way to do this?
When you are developing without the Qt Creator IDE, unless the IDE includes by itself some automatic utilities, you must edit manually the .pro configuration file.
The generated .pro file is a skeleton file which YOU must fill in with the libraries that you need, then the qmake system figures out the other dependencies and compiles your project. It is a essentially a much better version of pkg-config of gtk + Makefiles.
When you add more source and resource files to your project then manually you must add them to the .pro file.
Example:
QT += core gui
TARGET = qtcp1
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
miwidget1.cpp \
lcdrange.cpp
HEADERS += mainwindow.h \
miwidget1.h \
lcdrange.h
FORMS += mainwindow.u
Alternately, you can issue qmake -project over and over again, but this can cause some unforseen accidents, since it includes everything that is in the current directory at the time, including the pre-processed files for conversion to standard C++ from QT dialect. This intermediate files must be erased (cleaned), before the remaking the project and the next make or can lead to tricky problems.
Using the official and free QT Creator IDE takes away most of this burden by adding automatically the new data to the .pro file and cleaning loose ends. Some other IDEs like Code::BLocks and Codelite provide some facilities for QT, but not to the level of QT creator. Some prefer to edit the .pro themselves for custom reasons, other like more other styles of IDEs, like Eclipse.
You should test the waters and decide by yourself what fits best to your needs.
ReEdited, to clarify a few things.

Resources