CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > OpenFOAM Programming & Development

Make parts of code version dependent (check and toggle with `#ifdef`s?)

Register Blogs Members List Search Today's Posts Mark Forums Read

Reply
 
LinkBack Thread Tools Display Modes
Old   July 30, 2014, 00:48
Default Make parts of code version dependent (check and toggle with `#ifdef`s?)
  #1
Member
 
Christian Butcher
Join Date: Jul 2013
Location: Japan
Posts: 84
Rep Power: 4
chrisb2244 is on a distinguished road
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.

Last edited by chrisb2244; July 30, 2014 at 00:54. Reason: Found an environment variable that might be useful
chrisb2244 is offline   Reply With Quote

Old   July 30, 2014, 00:58
Default
  #2
Member
 
Christian Butcher
Join Date: Jul 2013
Location: Japan
Posts: 84
Rep Power: 4
chrisb2244 is on a distinguished road
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 is offline   Reply With Quote

Old   July 30, 2014, 01:55
Default
  #3
Member
 
Christian Butcher
Join Date: Jul 2013
Location: Japan
Posts: 84
Rep Power: 4
chrisb2244 is on a distinguished road
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)
chrisb2244 is offline   Reply With Quote

Old   August 4, 2014, 11:40
Default
  #4
Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 8,507
Blog Entries: 34
Rep Power: 86
wyldckat is just really nicewyldckat is just really nicewyldckat is just really nicewyldckat is just really nice
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
wyldckat is offline   Reply With Quote

Old   August 4, 2014, 20:44
Default
  #5
Member
 
Christian Butcher
Join Date: Jul 2013
Location: Japan
Posts: 84
Rep Power: 4
chrisb2244 is on a distinguished road
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?
chrisb2244 is offline   Reply With Quote

Old   August 5, 2014, 12:05
Default
  #6
ngj
Senior Member
 
Niels Gjoel Jacobsen
Join Date: Mar 2009
Location: Deltares, Delft, The Netherlands
Posts: 1,619
Rep Power: 25
ngj will become famous soon enoughngj will become famous soon enough
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
__________________
Please note that I do not use the Friend-feature, so do not be offended, if I do not accept a request.
ngj is offline   Reply With Quote

Old   August 5, 2014, 21:06
Default
  #7
Member
 
Christian Butcher
Join Date: Jul 2013
Location: Japan
Posts: 84
Rep Power: 4
chrisb2244 is on a distinguished road
Quote:
Originally Posted by ngj View Post
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
chrisb2244 is offline   Reply With Quote

Old   August 6, 2014, 04:14
Default
  #8
ngj
Senior Member
 
Niels Gjoel Jacobsen
Join Date: Mar 2009
Location: Deltares, Delft, The Netherlands
Posts: 1,619
Rep Power: 25
ngj will become famous soon enoughngj will become famous soon enough
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
__________________
Please note that I do not use the Friend-feature, so do not be offended, if I do not accept a request.
ngj is offline   Reply With Quote

Reply

Tags
openfoam, version-specific code

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -4. The time now is 13:52.