waf: nested projects and _cache.py: not supported? - c++

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?

Related

Eclipse C++: fatal error: cheddar.h: no such file or directory

[RHEL v7.3, Eclipse Photon, C/C++ Project with Eclipse-generated Makefile]
Attempting to include a custom library named cheddar.h results in
Fatal Error: cheddar.h: no such file or directory
Research 1 and 2 suggests manually adding the include path by first alt-clicking the project in Project Explorer, and then manually adding the path :
Properties -> C/C++ General -> Paths and Symbols : Includes : Languages, GNU C++
No luck.
It works if I do things the old-fashioned way, and add the path to the makefile with a -I option, like so
-I/home/kmiklas/lib/
..but I feel like I'm working-around the issue, and I want this set up properly; the way it should be set up.
How do I correctly specify a custom include path in Eclipse? Tyvm :^)
What is wrong with CMake/Makefile?
I don’t know, but this just sounds like an XY problem. But what’s even more confusing is how you’re so reluctant to use a solution that you’ve already got (as in it’s bugging me).
Anyway
What may aid you in this is to ditch eclipse’s settings and just use the compiler’s. Eclipse uses (GCC/G++ (probably)). What you can do is set some environment variables DUN DUN DUHH!
These environment variables are aptly named: C_INCLUDE_PATH and CPLUS_INCLUDE_PATH. If, however, you want the same for both (you want to use it for both languages) you can just set CPATH.
You’re probably thinking: what else can I do with this marvel... and for that I direct you to the official GCC website.

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

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)

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.

different set of flags for subprojects in waf

I'm still struggling with waf for setting up different set of flags for subprojects.
I have a structure like this, in which superproject recursed to the subprojects:
superproject/wscript
libproject/wscript
progproject/wscript
The problem is that both subprojects progrproject and libproject use boost tool.
I want that both projects check for boost at configuration time, since I want the projects to be self-contained when they are built independently.
I have to do something like this to not overwrite flags for boost between subprojects:
#In libproject
cfg.check_boost('regex', uselib_store='BOOST_LIBPROJECT')
#In progrpoject
cfg.check_boost('program_options', uselib_store='BOOST_PROGPROJECT')
This has the side-effect of making options --boost-libsand --boost-includesdefaults not to work anymore.
Actually, I would like to use the default BOOST store for both, but one seems to overwrite the other in _cache.py file. If I build the projects alone and separate, this problem does not happen. I think setting another environment is not a solution (right?)
since this makes the command to become ./waf build_libproject or similar, which is not what I want.
I want:
./waf configure build
to run correctly without workarounding with different stores or preventive flag name changing.
What is the correct way to do it?

Can I use SCons aliasing for choosing SConscripts to run?

I'm using SCons to build a very large project, with many buildable sub-projects. I can easily use keyword commands like scons group=ai to build the AI sub-projects with if statements (choosing the right SConscripts based on the keyword command), but I want to make it as easy as possible for others to use scons. Ideally, I'd like to use it like so: scons ai to build the AI components. However, the only single-word command functionality I've found in SCons so far is aliasing, and all the examples are about changing the target. This is not what I want. Since I have a very large project with multiple sub-SConscript files to build the subprojects, I want to call the SConscripts selectively. I've tried code like so:
env.Alias("ai", SConscript("ai/SConscript", 'env'))
but this calls the AI SConscript every time, regardless of whether I use the "ai" alias or a different one. Does anyone know if it is possible to use aliasing this way to selectively call SConscripts based on the alias?
As you mentioned, the Alias() function is only used for targets. I can think of 2 ways to solve this
Alias() can be called multiple times for the same alias with different targets, so you could call it for all targets in each SConscript, then you could build everything in a SConscript. Here's an example of what I mean:
ai/SConscript:
# targets, etc
env.Alias("ai", target1)
env.Alias("ai", target2)
...
env.Alias("ai", targetn)
Another option would be to put some logic in your root SConstruct so it only calls sub-project SConscript's based on a command line argument. This option would require you to use a command line argument of this form: group=ai