CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Make parts of code version dependent (check and toggle with `#ifdef`s?) (https://www.cfd-online.com/Forums/openfoam-programming-development/139714-make-parts-code-version-dependent-check-toggle-ifdef-s.html)

chrisb2244 July 30, 2014 00:48

Make parts of code version dependent (check and toggle with `#ifdef`s?)
 
EDIT: tl;dr: Can I access something like $WM_PROJECT_VERSION inside C++ code to be compiled with wmake (libso)?

I am (still, sort of, part time) working on a 2D amr library and everything is moving along (slowly). When someone downloaded the source files via github, they emailed me and told me it wouldn't compile. Because of the time difference between us, they had already found the problem when I read this, and sent a second email stating that my files compiled for OF-2.3.0 (which I updated to, and made some changes to support), but not for OF-2.2.1 (I initially started writing the library in OF-2.2.2).

Now, obviously I can just write that the library will require OF-2.3.0, but since the changes are relatively small (referring to the function "topoChanging", whose implementation changed between 2.2.2 and 2.3.0), writing something along the lines of

Code:

#ifdef V2.2.X_OF
// lines of code with old function calls
#endif
#ifdef V2.3.X_OF+
// current, newer style lines of code
#endif

I guess I'd need to be careful avoiding any variable declarations during these sections, since I'm guessing that would make my compiler hate me, but since I think it's just a change to the arguments passed (the old function was called changing(const bool) or changing(), returning a bool with true if the mesh was changing, or similar)

Is it possible to write code which can detect the OF version, and selectively choose a #define pre-processor command? The version is usually held in the headers of files, like the controlDict, but relying on this seems unhelpful (since it can easily be wrong, if the OF version is updated but the files are kept, or you can as far as I'm aware, just write whatever you want there...) and if I use
Code:


if (someVar)
{
    topoChanging();
}
elseif (someOtherVar)
{
  changingTopo();
}

then I suspect it will compile in neither case, since both OF-2.3.0 and OF-2.2.2 would be missing one of the functions.

If I could define based on the existence of the function, I could possibly use
Code:

#ifdef EARLIER_OF
bool topoChanging(const bool)
{
    return changing(bool);
}
bool topoChanging()
{
    return changing();
}
#endif

but I still need to be able to get a preprocessor token which depends on the version of OF.

Any help would be much appreciated.

chrisb2244 July 30, 2014 00:58

And with much ado about nothing - getenv() in <stdlib.h> is likely to be something I can use to get the value of $WM_PROJECT_VERSION, which solves much of the problem.

Now just to work out if that can get me a conditional #define or #include statement (since they should occur even if in an if() branch that isn't chosen, right? :( )

chrisb2244 July 30, 2014 01:55

Solution:

In Make/options, before my
Code:

EXE_INC = \
    ...

section, use:
Code:

ifeq ($(WM_PROJECT_VERSION),2.3.0)
    MACRO_DEFINED=-DnameOfMyDefinedVar
else
    MACRO_DEFINED=
endif

EXE_INC = \
    $(MACRO_DEFINED) \
    -I$(LIB_SRC)/.....

.....

Then test for
Code:

#ifdef nameOfMyDefinedVar
I guess a whole collection of further Makefile comparisons could be used to make this less specific, which I'll look into but probably not redocument here.

Link to helpful page about conditional makefile variables: http://www.chemie.fu-berlin.de/chemn...ke/make_7.html

(although once you know what you want to find, google is your friend)

wyldckat August 4, 2014 11:40

Greetings Christian,

There are two implementations I'm aware of and neither are present in OpenFOAM, or at least not yet.
  1. One's here: http://www.openfoam.org/mantisbt/view.php?id=293
  2. Another is swak4Foam, which has its own implementation. For example, have a look into the file "Libraries/Allwmake" in swak4Foam's source code, e.g.: https://github.com/Unofficial-Extend...aries/Allwmake
Best regards,
Bruno

chrisb2244 August 4, 2014 20:44

Dear Bruno,

Thank you for taking the time to read this and adding the links as reference.

It seems like the mantis link contains a comment (from mwild) that is roughly the same as what I've done, although it also seems like the point of the 'bug' report/feature request is to avoid doing that - "#ifdef is BAAAAD". Certainly, it does make code very "Ugly".

I confess that I'm at a loss as to how you would go about using the 'dog-tag' style code in 3rd party libraries/solvers/applications etc though. Doesn't generating a set of
Code:

#define FOAM_VERSION 2
#define FOAM_VERSION_MiNOR 0
#define FOAM_VERSION_PATCHLEVEL 1

inherently lend itself to writing code with lots of #ifdef and #ifndef statements?

Is the suggestion that a version dependencies file of some kind, containing only #define commands, be included everywhere? For example, taking the mathmaticalConstants idea, something like

Code:

// Version Defines
// Get tagfile, which defines FOAM_VERSION style tags

#if FOAM_VERSION==2
#define MATHCONSTS constants::mathematical
#endif

#if FOAM_VERSION==1
#define MATHCONSTS mathematicalConstants
#endif

or (but I don't think this works - MATHCONSTS will always be the case 1 define, right?)
Code:

switch (FOAM_VERSION)
{
    case 2:
    #define MATHCONSTS constants::mathematical
    break;

    case 1:
    #define MATHCONSTS mathematicalConstants
    break;
}

and then use the MATHCONSTS in the rest of the code?

ngj August 5, 2014 12:05

Hallo Christian,

I might add another source of inspiration, since waves2Foam also tries to be cross-version compatible. In waves2Foam I transform the version number to a 3 digit number and applies "==", "<" etc. booleans in the pre-processor statements.

It is not too bad with the amount of #if statements, but specifically for PI, I use M_PI instead, because it is too common to bother about the change in syntax. In waves2Foam you will also find a whole class called crossVersionCompatibility or something along those lines, which is an attempt to gather all naming changes in one place.

Good luck,

Niels

chrisb2244 August 5, 2014 21:06

Quote:

Originally Posted by ngj (Post 504500)
Hallo Christian,
In waves2Foam you will also find a whole class called crossVersionCompatibility or something along those lines, which is an attempt to gather all naming changes in one place.

Niels,

Thank you for this suggestion - I took a look at the class you wrote and it indeed looks very useful. My current implementation is similar, but messy - implementing the changes as function calls returning 'word's is a much better plan!

Best,
Christian

ngj August 6, 2014 04:14

Good morning,

I might add that I simply pass the integer as

Code:

-DOFVERSION
and that the whole process of stripping for '.', '-' and 'x' is performed in waves2Foam/bin/bashrc(.org). Note that there are some additional flags due to a lot of changes in the 2.2.X line of version and that foam-extend runs with a higher version number, but applies and older (but not obsolete) interface for some classes and for the naming of variables.

Kind regards,

Niels


All times are GMT -4. The time now is 12:10.