Pass directory to C++ application from compiler - c++

Some applications contain scripts that are run by the main application that reside in /usr/libexec. However, the autoconf scripts are able to change that directory by passing --libexecdir to the configure script.
For example, when running ./configure in the git source code, I can set --libexecdir to any directory I want, and the program will still work.
What do I need to add to a C++ to make this functionality work? In other words, how can I have a directory name set by a configure script compiled into the program?

You need the value of the #libexecdir# substitution variable (as used in e.g. Makefile.in) to be exposed to your C++ code. The simplest and most reliable way to do that is with a -D switch on the compiler command line for the object file that needs to know:
foo.o: CPPFLAGS += -DLIBEXECDIR='"$(libexecdir)"'
In foo.cc, LIBEXECDIR will then be a preprocessor macro expanding to a string constant that has the path you need. Two caveats, though: The above Makefile snippet uses a GNU make feature, target-specific variables. It will not work in other Make implementations. Also, I didn't bother quoting any characters in the expansion of $(libexecdir). Fully defensive quoting would look something like this:
foo.o: CPPFLAGS += \
-DLIBEXECDIR='"$(subst ",\",$(subst ','\'',$(subst \,\\,$(libexecdir))))"'
You will definitely need at least the innermost $(subst ...) construct if you want to be able to use Windows pathnames, with the slashes going the wrong way. People don't usually put ' or " in pathnames, so I probably wouldn't bother with the outer two until someone complained.
The same technique will work for any #whatever# substitution variable that isn't also an AC_DEFINE.
You might think you could use AC_DEFINE_UNQUOTED somehow to get the value of $(libexecdir) into config.h and so avoid all this mucking around with the command line. Unfortunately, Autoconf doesn't fully compute the value of its #*dir# substitutions at configure time:
# near the top of the generated 'configure':
exec_prefix=NONE
libexecdir='${exec_prefix}/libexec'
# much, much later -- as part of AC_OUTPUT:
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
Therefore, if you do the obvious thing with AC_DEFINE_UNQUOTED, you will get something like
#define LIBEXECDIR "${exec_prefix}/libexec"
in your config.h. So that's not going to work, and I don't see a good way to make it work.

Related

What's the best way to get a list of all the macros passed as compiler arguments?

I'm working on a code base that uses quite a bit of conditional compilation via macros passed as arguments to the compiler (i.e. gcc -DMACRO_HERE file.cpp). I would like to have a way to get a list of all the macros defined this way within the code so that I can write out all the used macros to the console and save files when the application is run, that way we know exactly what build was used.
I also need to do the same thing with the git hash but I think I can do that easily with a macro.
Edit 1: Note that this is not the same question as GCC dump preprocessor defines since I want the list available within the program and I only want the macros that are declared by being passed to the compiler with the -D argument
Edit 2: I also need it be cross compiler compatible since we use GCC, XL, CCE, CLANG, NVCC, HIP, and the MPI versions of those. Note that we're building with Make
Here's an outline of a possible solution.
The request is not well-specified because there is no guarantee that all object files will be built with the same conditional macros. So let's say that you want to capture the conditional macros specified for some designated source file.
On that basis, we can play a build trick, easy to do with make: the build recipe for that designated source file actually invokes a script, by inserting the path to the script at the beginning of the compile line.
The script runs through its arguments, selects the ones which start -D, and uses them to create a simple C source file which defines an array const char* build_options[], populating it with stringified versions of the command line arguments. (Unless you're a perfectionist, you don't need to do heroics to correctly escape the strings, because no sane build configuration would use -D arguments which require heroic escaping.)
Once the source file is built, the script saves it and either uses the command-line it was passed as its arguments to compile it, or leaves it to be compiled by some later build step.

sed/regex - Updating source files with scope issues

I have a project originally written for Windows, and I am currently in the process of porting it over to Linux. Most of the platform specific code has been #ifdef'ed or wrapped, so it's been easy so far.
This project has about 2000 instances of gettext() scattered throughout about 200 source files (.cpp and .c compiled as C++). The intended function call is:
std::string boost::locale::gettext(const char*);
This works in Windows, but in Linux builds, it resolves to:
char * gettext (const char * msgid);
Which I assume it's resolving from <libintl.h>, which is interesting, since I'm not including it.
What I need to do is to do the following:
Find in all my source files (ignoring the .svn directories):
1.1. Lines containing gettext(.*).c_str() and modify them to become boost::locale::gettext(.*).c_str().
1.2. Lines containing gettext(.*) and modify them to become boost::locale::gettext(.*).c_str().
What's the best way to accomplish this, preferably using BASh and sed, or some command-line-fu in general? The requirements for 1.1 I could probably do easily enough, but 1.2 is a bit more complex, and I'm not sure how to have it know which right parentheses ) to append .c_str() to correctly.
Thank you.
This problem is not solvable with a regex in the general case, since you cannot find the matching closing parenthesis of the gettext()-call with it if other calls are nested in its argument list.
But if usually no nested calls are made, it might be an option to just fix these cases automatically and do the rest by hand.
This sed expression
sed -r "s/gettext\(([^()]*)\)(\.c_str\(\))?/boost::locale::gettext(\1).c_str()/g"
should leave invocations with nested calls untouched and replace the rest.

Generating code at compile-time using scripts

I would ideally like to be able to add (very repetitive) C/C++ code to my actual code, but at compile time, code which would come from say, the stdout of a python script, the same way one does with macros.
For example, let's say I want to have functions that depend on the public attributes of a given class, being able to just write the following in my C++ code would be a blessing:
generate_boring_functions(FooBarClass,"FooBarClass.cpp")
Is that feasible using conventional means? Or must I hack with Makefiles and temporary source files?
Thanks.
You do most likely need to tweak the Makefile a bit. It would be easy to write a (Python) script that reads each of your source files as an additional preprocessing step, replacing instances of generate_boring_functions (or any other script-macro) with the correct code, potentially just by invoking generate_boring_functions.py with the right arguments, and bypassing the need for temporary files by sending the source to the compiler over standard input.
Damn, now I want to make something like this.
Edit: A rule like this, stuck in a makefile, could be used to handle the extra build step. This is untested and added only for some shot at completeness.
%.o : %.cpp
python macros.py $< | g++ -x cpp -c - -o $#
If a makefile isn't conventional enough for you, you could get by with cleverly-written macros.
class FooBarClass
{
DEFINE_BORING_METHODS( FooBarClass )
/* interesting functions begin here */
}
I very frequently see this done to implement the boilerplate parts of COM classes.
But if you want something that's neither make nor macro, then I don't know what you could possibly mean.
A makefile (or equivalent) is a "conventional" means!
I've never used this particular technology, but it sounds as though you're looking for something like Ned Batchelder's Cog tool.
Python scripts are embedded into a C++ source file such that when run through the cog tool additional C++ code is generated for the C++ compiler to consume. So your build process would consist of an extra step to have cog produce the actual C++ source file before the C++ compiler is invoked.
You could try the Boost Preprocessor Library. It's just an extension of the regular preprocessor, but if you're creative, you can achieve nearly anything in it.
Did you have a look at PythoidC ? It can be used to generate C code.
I have encountered this exact same problem multiple times.
I use it exactly in the way you describe -- (i.e. to run "boringFunction( filename.cpp, "filename.cpp") for a set of files).
It is used to generate code that "registers" the code contained in a specific set of files to a std::map, to handle adding user-written functions to the library without dynamically recompiling the whole library or relying on the (likely novice programmer) user to write syntactically correct C++ code to e.g. implement class functions.
I have solved it in two ways (which are basically equivalent)
1) A purely C++ "bootstrapping" method, in which during compilation, make compiles a simple C++ program that generates the necessary files, and then calls a second makefile that compiles the actual code generated in the temporary files.
2) A shell based method that uses bash to accomplish the same thing (I.e. use simple shell commands to iterate through the files and output new files to a temporary location, then call make on the output).
The functions can either be output to one file each, or can be output to one monolithic file for the second compilation.
Then, the functions can either be loaded dynamically (i.e. they are compiled as a shared library), or I can recompile all the rest of the code with the generated functions included.
The only hard part was (a) figuring out a way to register the function names uniquely (e.g. using preprocessor __COUNTER__ only works if it is a single monolithic file), and (b) figuring out how to reliably call the generation function in the makefile before the main makefile runs.
The advantage of the pure-C++ method (versus e.g. bash) is that it could possibly work on systems that do not have the same bash linux shell by default (e.g. windows or macOS), in which case of course a more complex cmake method is necessary..
I have included the hard parts of the makefile for posterity:
The first makefile called is:
# Dummy to compile filters first
$(MAKECMDGOALS): SCRIPTCOMPILE
make -f Makefile2 $(MAKECMDGOALS)
SCRIPTCOMPILE:
#sh scripts/filter_compiler_single.sh filter_stubs
.PHONY: SCRIPTCOMPILE
Where scripts/filter_compilr_single.sh is e.g.:
BUILD_DIR="build/COMPILED_FILTERS";
rm -r $BUILD_DIR
mkdir -p $BUILD_DIR
ARGSET="( localmapdict& inputmaps, localmapdict& outputmaps, void*& userdata, scratchmats& scratch, const std::map<std::string,std::string>& params, const uint64_t& curr_time , const std::string& nickname, const std::string& desc )"
compfname=$BUILD_DIR"/COMPILED_FILTERS.cpp"
echo "//// START OF GENERATED FILE (this file will be overwritten!) ////" > $compfname #REV: first overwrites
echo "#include <salmap_rv/include/salmap_rv_filter_includes.hpp>" >> $compfname
echo "using namespace salmap_rv;" >> $compfname
flist=$(find $1 -maxdepth 1 -type f) #REV: add constraint to only find .cpp files?
for f in $flist;
do
compfnamebase=$(basename $f) #REV: includes .cpp
alg=${compfnamebase%.cpp}
echo $f " >> " $compfname
echo "void ""$alg""$ARGSET""{" >> $compfname
echo "DEBUGPRINTF(stdout, \"Inside algo funct "$alg"\");" >> $compfname; #REV: debug...
cat $f >> $compfname
echo "}""REGISTER_SAL_FILT_FUNC(""$alg"")" >> $compfname
done
echo "//// END OF GENERATED FILE ////" >> $compfname
The second makefile Makefile2 is the normal compilation instructions.
It is not beautiful, and I would love to find a better way to do it, but as it is, extracting even just the base filename from every file during compilation is difficult even using templates or constexpr (e.g. some macro function that takes __FILE__). And that would rely on the user remembering to add the specific macro call to their function filter stub, which is just adding extra unneccessary work and asking to introduce spelling errors etc.

Any utility to test expand C/C++ #define macros?

It seems I often spend way too much time trying to get a #define macro to do exactly what i want. I'll post my current dilemma below and any help is appreciated. But really the bigger question is whether there is any utility someone could recommend, to quickly display what a macro is actually doing? It seems like even the slow trial and error process would go much faster if I could see what is wrong.
Currently, I'm dynamically loading a long list of functions from a DLL I made. The way I've set things up, the function pointers have the same nanes as the exported functions, and the typedef(s) used to prototype them have the same names, but with a prepended underscore. So I want to use a define to simplify assignments of a long long list of function pointers.
For example, In the code statement below, 'hexdump' is the name of a typedef'd function point, and is also the name of the function, while _hexdump is the name of the typedef. If GetProcAddress() fails, a failure counter in incremented.
if (!(hexdump = (_hexdump)GetProcAddress(h, "hexdump"))) --iFail;
So let's say I'd like to replace each line like the above with a macro, like this...
GETADDR_FOR(hexdump )
Well this is the best I've come up with so far. It doesn't work (my // comment is just to prevent text formatting in the message)...
// #define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/""))) --iFail;
And again, while I'd APPRECIATE an insight into what silly mistake I've made, it would make my day to have a utility that would show me the error of my ways, by simply plugging in my macro.
Go to https://godbolt.org/. Enter your code in the left pane and select compiler as gcc put the argument as -E in the right pane. Your pre-processed code will appear on the right.
You can just run your code through the preprocessor, which will show you what it will be expanded into (or spit out errors as necessary):
$ cat a.c
#define GETADDR_FOR(a) if (!(a = (#_#a)GetProcAddress(h, "/""#a"/"")))
GETADDR_FOR(hexdump)
$ gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
a.c:1:36: error: '#' is not followed by a macro parameter
GETADDR_FOR(hexdump)
In GCC, it's gcc -E foo.c to only preprocess the file.
Visual Studio uses the /P argument.
http://visualstudiogallery.msdn.microsoft.com/59a2438f-ba4a-4945-a407-a1a295598088 - visual studio plugin to expand macroses
You appear to be confused about what the exact syntax is for stringifying or token pasting in C preprocessor macros.
You might find this page about C preprocessor macros in general helpful.
In particular, I think this macro should read like this:
#define GETADDR_FOR(a) if (!(a = (_##a)GetProcAddress(h, #a))) --iFail
The trailing ; should be skipped because you will likely be typing this as GETADDR_FOR(hexdump);, and if you don't it will look very strange in your C code and confuse many syntax highlighters.
And as someone else mentioned gcc -E will run the preprocessor and skip the other compilation steps. This is useful for debugging preprocessor problems.
You might want to take a look at Boost Wave. Like most of Boost, it's really more a library than a utility, but it does have a driver to act as a complete preprocessor.

Registering each C/C++ source file to create a runtime list of used sources

For a debugging and logging library, I want to be able to find, at runtime, a list of all of the source files that the project has compiled and linked. I assume I'll be including some kind of header in each source file, and the preprocessor __FILE__ macro can give me a character constant for that file, so I just need to somehow "broadcast" that information from each file to be gathered by a runtime function.
The question is how to elegantly do this, and especially if it can be done from C as opposed to C++. In C++ I'd probably try to make a class with a static storage to hold the list of filenames. Each header file would create a file-local static instance of that class, which on creation would append the FILE pointer or whatever into the class's static data members, perhaps as a linked list.
But I don't think this will work in C, and even in C++ I'm not sure it's guaranteed that each element will be created.
I wouldn't do that sort of thing right in the code. I would write a tool which parsed the project file (vcproj, makefile or even just scan the project directory for *.c* files) and generated an additional C source file which contained the names of all the source files in some kind of pre-initialized data structure.
I would then make that tool part of the build process so that every time you do a build this would all happen automatically. At run time, all you would have to do is read that data structure that was built.
I agree with Ferruccio, the best way to do this is in the build system, not the code itself. As an expansion of his idea, add a target to your build system which dumps a list of the files (which it has to know anyway) to a C file as a string, or array of strings, and compile this file into your source. This avoids a lot of complication in the source, and is expandable, if you want to add additional information, like the version number from your source code control system, who built the executable, etc.
There is a standard way on UNIX and Linux - ident. For every source file you create ID tag - usually it is assigned by you version control system, e.g. SVN keywords.
Then to find out the name and revision of each source file you just use ident command. If you need to do it at runtime check out how ident does it - source for it should be freely available.
Theres no way to do it in C. In C++ you can create a class like this:
struct Reg {
Reg( const char * file ) {
StaticDictionary::Register( file );
};
where StaticDictionary is a singleton container for all your file names. Then in each source file:
static Reg regthisfile( __FILE__ );
You would want to make the dictionary a Meyers singleton to avoid order of creation problems.
I don't think you can do this in the way you outline in a "passive" mode. That is, you are going to somehow run code for each source file to be added to the registry, it's hard to get it to happen automatically.
Of course, it's possible that you can make that code very unobtrusive using macros. It might be problematic for C source files that don't have an "entrypoint", so if your code isn't already organised as "modules", with e.g. an init() function for each module, it might be hard. Static initializing code might be possible, I'm not 100% sure if the order in which things are initialized creates problems here.
Using static storage in the registry module sounds like an excellent idea, a plain linked list or simple hash table should be easy enough to implement, if your project doesn't already include any general-purpose utility library.
In C++ your solution will work. It's guaranteed.
Edit: Just found out a solution in my head: Change a rule in your makefile to add
'-include "cfiles_register.h"' to each 'g++ file.cpp'.
%.o : %.cpp
$(CC) -include 'cfiles_register.h' -o $# $<
put your proposed in the question implemnatation to that 'cfiles_register.h'.
Using static instances in C++ would work fine.
You could do this also in C, but you need to use runtime specific features - for MSVC CRT take a look at http://www.codeguru.com/cpp/misc/misc/threadsprocesses/article.php/c6945/
For C - you could do it with a macro - define a variable named corresponding to your file, and then you could scan the symbols of your executable, just as an idea:
#define TRACK_FILE(name) char _file_tracker_##name;
use it in your my_c_file.c like this:
TRACK_FILE(my_c_file_c)
and than grep all file/variable names from the binary like this
nm my-binary | grep _file_tracker
Not really nice, but...
Horrible idea, I'm sure, but use a singleton. And on each file do something like
Singleton.register(__FILE__);
at global scope. It'll only work on cpp files though.
I did something like this years ago as a novice, and it worked. But I'd cringe to do it now. I'd add a build step now.
I agree with those who say that it is better to avoid doing this at run time, but in C, you can initialize a static variable with a function call, that is, in every file:
static int doesntmatter = register( __FILE__);