Can I use QBS for creating user defined run configuration files? - c++

I am building a program in QT that is going to need a user definable run configuration file, similar to .vimrc. In short, it will need to define what keypresses are responsible for basic commands in a curses like interface.
I have not quite decided what format to use, but thought that QBS might suit the bill as I am already using it for project management, and it would seem that on the surface that it would be well suited for this sort of thing.
The idea is to have the configuration file sitting in /home/me/.programrc, which is easy enough. I do not know however what interpreters exist for its syntax in Qt or C++, if any, or whether it is practically suited to serve as a run configuration in the first place.
Is this whole idea conceptualized properly, and do adequate tools exist for achieving this goal?
Thanks.

QBS is now deprecated in favor of CMake (along with QMake).
You can add a ".qmake.conf" file in the same dir where you .pro file resides.
In this file you can store parameters which you can use in .pro/.pri files.
.qmake.conf
BUILD_DIR=$$shadowed($$PWD)/build
BUILD_TESTS_DIR=$$shadowed($$PWD)/unit_tests
SCRIPTS_DIR=$$PWD/scripts
TOP_SRC_DIR=$$PWD
project.pro
DESTDIR = $$BUILD_DIR/
INCLUDEPATH += $$TOP_SRC_DIR/
You could add your keypress confiog in the DEFINES parameter, e.g. for TOP_SRC_DIR:
DEFINES += "TOP_SRC_DIR=\\\"$$TOP_SRC_DIR\\\""
TOP_SRC_DIR is now known in your source code as a define.
Of course you will need to rebuild the file(s) which use the define so you may bind the define(s) to centralized "extern" variable(s) which you link to and force re-linking when the parameters change (e.g. PRE_TARGETDEPS += $BUILD_DIR/myParams.a)

Related

Use autotools installation prefix

I am writing a C++ program using gtkmm as the window library and autotools as my build system. In my Makefile.am, I install the icon as follows:
icondir = $(datadir)/icons/hicolor/scalable/apps
icon_DATA = $(top_srcdir)/appname.svg
EDIT: changed from prefix to datadir
This results in appname.svg being copied to $(datadir)/icons/hicolor/scalable/apps when the program is installed. In my C++ code, I would like to access the icon at runtime for a window decoration:
string iconPath = DATADIR + "/icons/hicolor/scalable/apps/appname.svg";
// do stuff with the icon
I am unsure how to go about obtaining DATADIR for this purpose. I could use relative paths, but then moving the binary would break the icon, which seems evident of hackery. I figure that there should be a special way to handle icons separate from general data, since people can install 3rd party icon packs. So, I have two questions:
What is the standard way of installing and using icons with autotools/C++/gtkmm?
Edit: gtkmm has an IconTheme class that is the standard way to use icons in gtkmm. It appears that I add_resource_path() (for which I still need the installation prefix), and then I can use the library to obtain the icon by name.
What is the general method with autotools/C++ to access the autotools installation prefix?
To convey data determined by configure to your source files, the primary methods available are to write them in a header that your sources #include or to define them as macros on the compiler command line. These are handled most conveniently via the AC_DEFINE Autoconf macro. Under some circumstances, you might also consider converting source files to templates for configure to process, but except inasmuch as Autoconf itself uses an internal version of that technique to build config.h (when that is requested), I wouldn't normally recommend it.
HOWEVER, the installation prefix and other installation directories are special cases. They are not finally set until you actually run make. Even if you set them via the configure's command-line options, you can still override that by specifying different values on the make command line. Thus, it is not safe to rely on AC_DEFINE for this particular purpose, and in fact, doing so may not work at all (will not work for prefix itself).
Instead, you should specify the appropriate macro definition in a command-line option that is evaluated at make time. You can do this for all targets being built by setting the AM_CPPFLAGS variable in your Makefile.am files, as demonstrated in another answer. That particular example sets the specified symbol to be a macro that expands to a C string literal containing the prefix. Alternatively, you could consider defining the whole icon directory as a symbol. If you need it only for one target out of several then you might prefer setting the appropriate onetarget_CPPFLAGS variable.
As an aside, do note that $(prefix)/icons/hicolor/scalable/apps is a nonstandard choice for the installation directory for your icon. That will typically resolve to something like /usr/local/icons/hicolor/scalable/apps. The conventional choice would be $(datadir)/icons/hicolor/scalable/apps, which will resolve to something like /usr/local/share/icons/hicolor/scalable/apps.
In your Makefile.am, use the following
AM_CPPFLAGS = -DPREFIX='"$(prefix)"'
See Defining Directories in autoconf's manual.

How do you change Qt Creator's OUT_PWD setting in the .pro file

I'm trying to set the OUT_PWD parameter when using Qt Creator. The documentation say's NOT to overwrite this parameter. So, is there another safe way to change this parameter in the .pro file?
The reason I want to modify this directory is to maintain a uniform workspace across all of my developers. At the moment when a person opens a new project, they need to ensure the "build directory" is set correctly in the "project" tab. I'd like to make this a parameter that is set in the .pro file so that all developers are working in the same directory structure.
This is important as I have both Apps and Libs combined in a SUBDIRS type of project and need to ensure the Libs end up in the right place.
Thanks for any help you can provide.
This makes zero sense, because the build folder is meant to be arbitrary, and you're meant to have possibly a multitude of build folders for any given project - depending on how you build the project.
I think that your workflow is broken, and the fix is to the workflow itself, not to project files.
This is important as I have both Apps and Libs combined in a SUBDIRS type of project and need to ensure the Libs end up in the right place.
That's done by adding targets that put the executables/libraries where you want them, not by modifying OUT_PWD.
The solution I used was the following.
Debug:DESTDIR = $$PWD/debug
Debug:OBJECTS_DIR = $$PWD/debug/.obj
Debug:MOC_DIR = $$PWD/debug/.moc
Debug:RCC_DIR = $$PWD/debug/.rcc
Debug:UI_DIR = $$PWD/debug/.ui
Release:DESTDIR = $$PWD/release
Release:OBJECTS_DIR = $$PWD/release/.obj
Release:MOC_DIR = $$PWD/release/.moc
Release:RCC_DIR = $$PWD/release/.rcc
Release:UI_DIR = $$PWD/release/.ui
The build directory is still placed in whatever location is specified by the .pro.user file (which is not something I was concerned with), but at least the lib files are placed in a known location relative to the .pro file and will therefore be uniform across my developers.
I found part of the solution at this link (How to specify different Debug/Release output directories in QMake .pro file), but the main difference is the addition of $$PWD/ to the beginning of the path

waf: nested projects and _cache.py: not supported?

I am converting a project from autotools to waf with the hope that it can be easily compiled in windows as well.
I am using a super project with two children folders that are 2 projects.
One of them is a library, the other, a program, like this:
superproject/wscript
superproject/libraryproject/wscript
superproject/programproject/wscript
It seems that waf has terrible support for subprojects. I have a wscript in each of these directories.
I recurse from superproject into the 2 other projects, but the _cache.py file is shared for both projects. This has the following side effects (issues):
When using the boost tool, I had to use it like this to avoid name collisions:
# In library project
cfg.check_boost('boost_program_options', uselib_store='BOOST_LIBRARYPROJECT')
# In program project
cfg.check_boost('boost_program_options', uselib_store='BOOST_PROGRAMPROJECT')
boost-libs and boost-includes command line options are also lost by default, so I have to set them manually, like this:
cfg.env.LIBPATH_BOOST_PROGRAMPROJECT = cfg.options.boost_libs
...
The _cache.py file is overwritten by the programproject/wscript, loosing all the configuration for the flags.
Questions:
Is there any good way to nest projects and avoid at least issue 2?
Is there any reasonable way to avoid both that doesn't require a script and building projects separately?
Configuration file is not written twice.
My mistake was to do this:
cfg.env = ConfigSet()
I wanted a new and clean ConfigSet but doing that in both projects made the first set of flags to be lost.
Since the environment seems to be shared among all project configurations, is it good style to name the variables with custom names? For example, instead of using:
cfg.check_boost('program_options')
Should I use:
cfg.check_boost('program_options', uselib_store='BOOST_MYPROGRAMPROJECT')
Is this good style or it's usually done in another way?
Can be done in a cleaner way deriving ConfigSets?

CMake - Automatically Parsing Dependencies of Precompiled Header?

As of yet, at least to my knowledge, there is no standard way in CMake to specify the addition of a precompiled header (PCH) to a project in a cross-platform manner because the way PCHs are handled by C++ compilers is very different among vendors. For G++, this is usually this is worked around by simply adding a custom command which takes care of invoking the compiler with the appropriate input and has it generate the PCH.
My current problem is that CMake will not parse the dependencies of the dependencies you specify for the custom command. For instance, assume the following structure:
pch.h
|- dependA.h
|- dependB.h
...
Only providing pch.h as a dependency will lead to the generation of the appropriate target in the corresponding makefile, which tracks changes to pch.h. However, CMake does not parse the includes inside pch.h and will therefore not recognize changes to dependA.h and dependB.h. This extends furhter if there are dependencies for dependsA.h and so on.
Note: I'm aware that the fact that PCH dependencies can and do change regularly puts the whole process in question. However, this is just the way it is and I can't really do anything about it.
Since the task isn't too hard, there are a couple of obvious ideas that come to mind:
Solution A:
Enter all the dependencies by hand. Obviously this works, but is tedious as hell and doesn't scale at all.
Solution B:
If possible, write a CMake function that automates the process and parse the includes "manually".
Solution C:
Do something similar using a different language, for instance Python, and just provide CMake a list of dependencies to add to the custom command.
Solution D:
Use gcc/g++'s feature to parse and print out the dependency tree of the PCH and parse the output to extract the list of dependencies.
My question is: does anyone know a more convenient and faster way to get this done?
The IMPLICIT_DEPENDS option of the add_custom_command might do the trick:
add_custom_command(
OUTPUT outFile
COMMAND ...
IMPLICIT_DEPENDS CXX "pch.h")
The IMPLICIT_DEPENDS option makes the generated build system scan the implicit dependencies of the given input file at build time. It is only supported for Makefile generators, though.

Using Non-Local Data/Media Files with a C++ Application (gtkmm)

I'm beginning development on an acoustic spectrum analysis tool (inspired by spek) written in C++ with gtkmm (C++ bindings for the GTK+ GUI toolkit). I would imagine that I should know how to do this by now, however...
My directory structure is a-la-GNOME, e.g src/, data/, po/, man/. The specific situation that presented the need for my inquiry is the use of a GTK UI Manager that will be located in data/ui. For this specific situation, I want to be able to load the user-interface from this file in an install-independent manner (e.g. loading of the file does not depend on a make install; the executable may be run [and load the UI file] either from src/ after running make [thus compiling the sources into the selfsame exectuable] or from its install prefix). How would I refer to the UI file in my source code (keeping in mind that the loading of the file is not performed by creating a file object (fopen(...)) but rather by passing a file location as a string argument to (UIManager).add_ui_from_file(...))?
In addition to this particular situation of a UI file, how would I do similar references to files (i.e. databases, INI files, XML schemas) by using the autotools build process? Is there a piece of relevant Automake code to quickly set up a project to use this type of directory structure?
simply try to use both files (with the un-installed taking precedence):
if(!(UIManager).add_ui_from_file(../data/ui/mygui))
(UIManager).add_ui_from_file(/incalled/location/mygui)
In Glom, I created a helper function that tries both locations, with both locations being defined in the Makefile.am (this is simpler if you have only one Makefile.am, by using non-recursive automake, which is simpler anyway):
http://git.gnome.org/browse/glom/tree/glom/glade_utils.h#n38