In Appender.hh:164 is the core
static Appender::AppenderMapStorageInitializer appenderMapStorageInitializer
which is at the top-level log4cpp namespace. This variable will be initialized by any code #include'ing it, whether directly or indirectly. Any direct inclusion is probably OK since the including project is probably linking to log4cpp directly too.
Any indirect inclusion is problematic, since the project is probably not linking to log4cpp directly & will need to do so to link cleanly. GNU Radio has this exact issue with out-of-tree (OOT) modules: A module has to #include from inside GNU Radio's headers, which in turn #include log4cpp headers. The OOT should not need to link to log4cpp, since it's not using the code directly.
A fix is found here: https://github.com/macports/macports-ports/commit/03e977add031301f57ca69729d829c607fe8d316#diff-066b9a66ca6ab453ac31b765b8caed86
It's really not clear what the intent ot this variable is beyond making sure that
_appenderMapStorageInstance
is initialized, and just once. Hence why I think moving the static variable from the header into the .cpp file is the correct fix (as per the MacPorts commit).
Hello Michael,
Thanks for letting know this. I will come with an answer a bit later.
Alex
Hello Michael,
Sorry for not answering for long time.
The code you referred to follows so called 'nifty counter idiom'. ( https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter )
Intent is shortly described there.
The purpose here is to initialize memory area once for keeping map of all allocated appenders inside. These appenders will be released during program exiting so no memory will be reported as lost.
Moving this initializer into implementation .cpp file effectively meant that only single translation unit (Appender.cpp) would prevent the static initializer (and therefore all the appenders) from being destroyed. If some other client code still counted on using logging abilities then the program would crash on exit due to attempting to write log information into appenders which are already released.
I however consider this as an open question and invite you to discuss that.
Would you give a link to the code which had the trouble you described in this ticket please?
Thanks,
Alexander.
Hi Alexander - Thanks for looking into this; no problems on delays.
The code in gnuradio-runtime is found here:
https://github.com/gnuradio/gnuradio/blob/master/gnuradio-runtime/include/gnuradio/logger.h.in
https://github.com/gnuradio/gnuradio/blob/master/gnuradio-runtime/lib/logger.cc
Please note that the header is actaully C++ even though its extension is just ".h". The ".in" is used by CMake during configuration to swap out the "#cmakedefine" lines depending on whether the variable was defined or not.
Please also note that the macros ENABLE_GR_LOG and HAVE_LOG4CPP in the above code were fixed about a month ago to allow for more robust logging options for both in-project and out-of-project #include. That said, the next gnuradio-runtime release will require log4cpp & these macros will go away & thus this issue will be relevant.
The issue here is as I wrote originally: If I try to build an out-of-tree module such as "gr-foo", which does not directly use log4cpp but does require gnuradio-runtime's API which #include's log4cpp, then I will have to link gr-foo against log4cpp's library.
My belief is that if a project does not directly use another project, then it should not be required to link against that project's library. The static initializer will be created no matter whether log4cpp is actually being used. If log4cpp isn't being used, then this static initializer should not be required.
Thanks for looking into this issue. I'm happy to discuss further and help in testing and debugging possible fixes. - MLD
Michael,
I glanced a the links you gave and devoted some thoughts to it.
I share your belief; what's not used is better not to be taken. I wonder if that's possible to arrange gnuradio-runtime's API in such a way where in-project usages include API and logging, whether out-of-project usages include API only. In other words, is it possible to separate logging from API there?
Alexander.
Hi Alexander - I haven't looked into changing the GNU Radio code, but such a change is certainly doable if desired. We've already implemented a workaround by adding "-llog4cpp" to LDFLAGS in its PKGCONFIG file -- which is what's used by CMake as the starting point for determining whether its installed. That said, these changes do not fix the broader issue; they are just workarounds. I would hope you could address the broader issue here ... but, I really don't know what the solution. Cheers! - MLD