Is there anyway to stop MVSC from creating release and debug folders when using form QtCreator? - visual-studio

Whenever I set my build options in Qt for a specific folder and I compile using MVSC it creates a release and debug folder and puts the output exe file inside that folder. If I compile in linux it usually just puts the final executable file in the folder that I specify. Is there a way to get this last behaviour (that is to stop the creation release and debug folder)?

You can set CONFIG -= debug_and_release in your .pro file and it will stop doing so.

With qmake you can actually specify a destination directory for your binary(ies), and other generated output as well. For example:
DESTDIR = $${OUT_PWD}/bin # this is where the binaries ('target' files) go
OBJECTS_DIR = $${OUT_PWD}/obj # compiled objects
MOC_DIR = $${OUT_PWD}/moc # generated MOC files
UI_DIR = $${OUT_PWD}/ui # generated C++ code from .ui files
RCC_DIR = $${OUT_PWD}/rcc # generated C++ code from .qrc files
OUT_PWD is a built-in variable specifying the current build directory. You could actually use any valid path here.
Reference: http://doc.qt.io/qt-5/qmake-variable-reference.html

Related

How do you create custom build rules in QTCreator for code generation?

I'm working on a GTK3 application, but using QTCreator as my IDE, just because I happen to like it. It works fine, I can easily turn off all the QT-specific stuff and link the GTK libraries. There's just one little issue.
GTK uses XML files to define its resources. It comes with a program, "glib-compile-resources", which takes a .gresource.xml file and produces a .c file*, which can then be included in your project. The problem is that QTCreator doesn't know about glib-compile-resources, so I have to remember to run the program manually every time I make any change to them.
I've tried using a custom build step, but if I do that, then QT rebuilds the file every time, even if it hasn't changed, which slows the process down. In addition, if the C file doesn't already exist, it will fail with a "No rule to make target 'x.c' needed by 'x.o'. Stop." error, so I have to run the program manually anyway.
Is there any way to tell QTCreator to run glib-compile-resources whenever it encounters a .gresource.xml file, and include the resulting C file into the final compilation?
*There are other options available then just a straight C source file, but C source is the simplest and easiest for me.
You can add a custom target in your qmake file (rather than in your QtCreator project config). See the qmake docs at https://doc.qt.io/qt-5/qmake-advanced-usage.html#adding-custom-targets and/or https://doc.qt.io/qt-5/qmake-advanced-usage.html#adding-compilers.
Update: this is a simple example which shows how to do this for a single file, using the custom target mechanism in your .pro file:
glib_resources.target = glib-resources.c
glib_resources.depends = glib-resources.xml
glib_resources.commands = glib-compile-resources --target $$glib_resources.target --generate-source $$glib_resources.depends
QMAKE_EXTRA_TARGETS += glib_resources
PRE_TARGETDEPS += glib-resources.c ## set this target as a dependency for the actual build
QMAKE_CLEAN += glib-resources.c ## delete the file at make clean
Here's how I wound up solving my own issue:
I found in the QT documentation how to add your own custom compiler to a QT project file. The exact lines needed are:
GLIB_RESOURCE_FILES += \
resources.gresource.xml
# Add more resource files here.
glib_resources.name = glibresources
glib_resources.input = GLIB_RESOURCE_FILES
glib_resources.output = ${QMAKE_FILE_IN_BASE}.c
glib_resources.depend_command = glib-compile-resources --generate-dependencies ${QMAKE_FILE_IN}
glib_resources.commands = glib-compile-resources --target ${QMAKE_FILE_OUT} --sourcedir ${QMAKE_FILE_IN_PATH} --generate-source ${QMAKE_FILE_IN}
glib_resources.variable_out = SOURCES
glib_resources.clean = ${QMAKE_FILE_OUT}
QMAKE_EXTRA_COMPILERS += glib_resources
(Thanks to #zgyarmati, who's post lead me to the right answer.)

CMake: GCC preprocessor IMACROS file change does not trigger rebuild

I'm using the -imacros option for GCC in order to set all preprocessor defines (Options) for a project.
Before imacros I have been using a raw file with the preprocessor defines names and with a regular expression in CMAKE I was creating the list of -D to put in the CMAKE_C_FLAGS.
This works fine but ugly to see in the text editor. So to enhance that, I have changed to -imacros.
CMAKE_C_FLAGS will contain -imacros "path to configuration header"
This works fine, but if I change some configuration item in the configuration header the CMAKE do not recompile the file (don't see changes). In the old version - as you can expect - if some -D was changed all the files will be recompiled.
Any help?
An simple Approach
You can use OBJECT_DEPENDS source file property. But that needs to be set for all source files with something like:
set_source_files_properties(
${sources}
PROPERTIES
OBJECT_DEPENDS "path to configuration header"
)
Alternatives for all Source Files in Project
Officially CMake recommends to put all your definitions in a header file that is included by all your source files. The header could e.g. be generated from a template using configure_file().
But to follow your line of thought with using -imacros compiler flag, here are two alternative approaches for triggering a rebuild of all source files if "path to configuration header" file changes:
You can extend the scope of OBJECT_DEPENDS to all targets and their source files in the current directory with define_property(... INHERITED ...):
If the INHERITED option then the get_property() command will chain up to the next higher scope when the requested property is not set in the scope given to the command. DIRECTORY scope chains to GLOBAL. TARGET, SOURCE, and TEST chain to DIRECTORY.
So in your case this translates to:
define_property(
SOURCE
PROPERTY OBJECT_DEPENDS
INHERITED
BRIEF_DOCS "brief-doc"
FULL_DOCS "full-doc"
)
set_directory_properties(
PROPERTIES
OBJECT_DEPENDS "path to configuration header"
)
If I understand correctly, you anyway have to re-run CMake if your "configuration header" should/would change. Then you can simply add one definition outside your "configuration header" that keeps track of the header with something like:
file(TIMESTAMP "path to configuration header" _timestamp)
add_definitions(-DIMACROS_TIMESTAMP=${_timestamp})
Now every time your header gets a new timestamp, the definitions for all targets are changing and your build system will rebuild all source files.

CMake resources in source code for build and install

This has been on my mind for years. It is about using resource files with CMake in code such that they can be accessed when running in the build directory and when installed.
Say you have files necessary to run your program in a top-level directory called res. It contains res/file1.txt and res/file2.txt. You build this program and the resources are copied to the build directory from which the program can be run during development. Then, the program is installed with the resources into /usr/share/my_program or something and the program runs by accessing those files. The question is what to do in the source code so that the same code works when running from the build directory and when installed. I've seen several different answers for how to handle resources but each seems to have a flaw:
The program searches in some preconfigured absolute directory such as CMAKE_INSTALL_PREFIX/share/my_program and must be installed first to run, not ideal for easy use during development.
Finding some way to use relative paths to the binary but I don't see how this would work since the build tree will not mirror the installed file paths, being installed to the bin and share directories.
Differentiating between the two with a CMake variable so that it searches for a relative path in one scenario or the installed location with another. This could possibly just be the debug/release variable. It would also require rerunning CMake before installing to rebuild with the new resource paths.
Baking the files into the executable. Seems uneccessary when dealing with most resources since they could just be opened instead and may be inconvenient with large directories of files.
Is one of these the best solution? Is there something I'm not misunderstanding? I've always been under the impression programs should be able to be run from the build directory before installing to see if they work. If possible, I would like to know what both the CMake and C/C++ code would look like, such as open("my_resource_location"); and my_cmake_command(). Most answers I've seen relating to resources don't include both.
It seems to me that what you are looking for is a relocatable build.
One way to achieve this in CMake is to use configuration files to incorporate resource paths in your code. I have prepared a minimal and reproducible example to give you an idea of how it works.
First, imagine you have the following program structure on disk:
main
CMakeLists.txt
main.cpp
data
CMakeLists.txt
Resources.h.in (Thats the configuration file)
resource.txt
The resource.txt file only contains a string. The program simply opens that file, reads its content and displays it to the terminal. So you have something like:
#include <fstream>
#include <iostream>
#include <string>
#include <Resources.h>
const std::string MY_FILE = "/resource.txt";
int main(int argc, char *argv[])
{
std::string line;
std::ifstream myfile (RESOURCE_PATH + MY_FILE);
if(myfile.is_open())
{
while(std::getline(myfile,line))
{
std::cout << line << '\n';
}
myfile.close();
}
else
{
std::cout << "Unable to open file";
}
return 0;
}
Note that this file #includes a Resources.h file, but that this file does not exist in our project. However, we have a Resources.h.in configuration file that CMake will turn into a Resources.h file on generation. This generated file will then contain the resource path we need inside the RESOURCE_PATH variable. Here is what the configuration file contains:
#define RESSOURCE_PATH "#CMAKE_INSTALL_PREFIX#/#CMAKE_INSTALL_DATADIR#"
A simple #define with this strange #something# notation. On generation, CMake will make the appropriate substitution and write the result to Resource.h, which we can then consume. The main CMakeLists.txt file is pretty straight forward:
cmake_minimum_required(VERSION 3.10)
project(example)
# Sets up classic installation directories. However,
# you can override them:
include(GNUInstallDirs)
add_subdirectory(data)
add_subdirectory(main)
I use the GNUInstallDirs, which populates variables such as CMAKE_INSTALL_DATADIR, for convinience. The main/CMakeLists.txt file:
add_executable(example main.cpp)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Ressources.h.in" "Ressources.h")
target_include_directories(example
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
install(
TARGETS example
DESTINATION ${CMAKE_INSTALL_BINDIR}
)
This is where the configuration file is set up. The target_include_directories just below is added for CMake to be able to find the generated Resource.h file, which will reside in the build directory. Finally, the data/CMakeLists.txt file:
install(
FILES resource.txt
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}
)
only has a simple installation instruction. From there, you can install as usual. Simply create a build directory and use CMake as usual. For example, if the build directory is located at the same level as the project:
mkdir ../build
cd ../build
cmake ../project
make
sudo make install
Since by default (on Linux) we have:
CMAKE_INSTALL_PREFIX=/usr/local
CMAKE_INSTALL_BINDIR=bin
CMAKE_INSTALL_DATADIR=share
The program will be installed to /usr/local/bin and the resource to /usr/local/share. Note that the Resource.h file will give you the correct path once generated by CMake. Whats is nice now, however, is that you can modify the value of CMAKE_INSTALL_PREFIX to point to somewhere else by calling CMake like so (for example, this could be a dev build directory):
cmake -DCMAKE_INSTALL_PREFIX=/home/someone/example ../project
and you will have these values instead:
CMAKE_INSTALL_PREFIX=/home/someone/example
CMAKE_INSTALL_BINDIR=bin
CMAKE_INSTALL_DATADIR=share
The Resources.h file will also be updated to point to the right location, and your resource will still be found.

Qt Installer project: how to generate package.xml and config.xml

I try to make my Qt Installer project more comfortable.
I need to centralize information about my application and components (config.xml and package.xml) in one file. I don't want to jump on different files with same name and search for changeable elements between xml tags.
My first thougt is doing it right in *.pro file of installer project. I place sections of variables in header of installer project file. But where I need to place the code for xml generating?
What is the better (native / comfortable / crossplatform) way to do this?
The answer is simple here: you cannot generate XML files for Qt Installer: you write them manually, as explained in the documentation.
This section describes the following tasks that you must accomplish to create the installer:
Create a package directory that will contain all the configuration files and installable packages.
Create a configuration file that contains information about how to build the installer binaries and online repositories.
Create a package information file that contains information about the installable components.
Create installer content and copy it to the package directory.
Use the binarycreator tool to create the installer.
However, if you look closer at the examples, you can still generate the installer in the *.pro file. Let's pick an example randomly, System Info:
TEMPLATE = aux
INSTALLER = installer
INPUT = $$PWD/config/config.xml $$PWD/packages
example.input = INPUT
example.output = $$INSTALLER
example.commands = ../../bin/binarycreator -c $$PWD/config/config.xml -p $$PWD/packages ${QMAKE_FILE_OUT}
example.CONFIG += target_predeps no_link combine
QMAKE_EXTRA_COMPILERS += example
OTHER_FILES = README
If you want to apply this to your project, I think you'll have to modify the ../../bin/binarycreator line and make it system aware, by changing your PATH. It might be possible to call an external script and parse XML files, and make the substitutions you would like to do, but you'd move the complexity to another place.
Instead of maintaining plain good old XML files, you would be creating something between XSLT and XML. Maybe you could just write XSLT (or XSL or XQUERY) and generate XML but I don't know anyone who is using it anymore. Last time I used it was when I was learning Computer Science a long time ago :)
This is possible using the QMAKE_SUBSTITUTES feature which will substitute qmake variables into the given input files and put the output in the build folder.
This runs at qmake time rather than at build time. If this is suitable then you just need to add a target to copy the generated files from the build dir to your source dir.
If you need it to run at build time then you can create a .pri file containing QMAKE_SUBSTITUTES and a target in the main .pro file that will run qmake on this file during the build process.
Main .pro file:
create_xml.commands += $(QMAKE) $$shell_quote($$PWD/config/generate_xml.pri) $$escape_expand(\n\t)
create_xml.commands += $(COPY) $$shell_quote($${OUT_PWD}/config.xml) $$shell_quote($$PWD/config) $$escape_expand(\n\t)
create_xml.commands += $(COPY) $$shell_quote($${OUT_PWD}/package.xml) $$shell_quote($$PWD/packages/my.app.id/meta) $$escape_expand(\n\t)
create_xml.depends = $$PWD/version.pri
QMAKE_EXTRA_TARGETS += create_xml
generate_xml.pri:
TEMPLATE = aux
message("Generating $$OUT_PWD/config.xml and $$OUT_PWD/package.xml")
# Get the version number
include(version.pri)
APP_VERSION = $$VERSION
QMAKE_SUBSTITUTES += package.xml.in config.xml.in
config.xml.in: Note that you need to escape the quotes.
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Installer>
<Name>MyApp</Name>
<Version>$$APP_VERSION</Version>
...

Windows Compact Embedded - Include external native files

I have created a Sub project which just prints "Hello World". My goal is to create a C file inside the same subproject but within a folder named "src", also I want to create a H file within a folder named "include".
The H file contains only one function declaration "void printContent();" and the C file contains its definition which prints "Hello Buddy".
I added the C file inside the Source Files section of Sub project and added the H file inside the Header File Section, but when I compile the subproject and try to deploy it on to an emulator, I got an error.
BUILD: [01:0000000047:ERRORE] NMAKE : U1073: don't know how to make 'obj\ARMV4I\debug\content.obj'
I tried to configure the subproject by providing the below lines in the sources file of every Sub project.
INCLUDES= include/
But nothing changed and the problem still persists.
In wince subproject, sub folders are treated differently in the source file layout.
Rule No.1 You can't have both source and dirs files in the same folder.
So you either use one folder, or use several sub folders, then the root folder is clean and have one dirs file and several folders, no source file.
Rule No. 2 Each sub folder should have both source and makefile
You can copy and then edit the source file, the makefile will always be the same.
Ok, if you are going to use subfolder just to make the folder structure cleaner, my suggestion is that you create 2 subprojects, one is the main subproject; the other includes all your src files and its type is set to be static library. Then you can link to the static .lib file just as you are including them as in a subfolder. Of cource you need to set the additional include folder and input library.

Resources