While using compiler such g++ on command line, there are some parameters, which need to be given in all invocation of g++, and which are different from default parameters. Is there a way (e.g. using bashrc), so that my selected parameters canbe made default. I am compiling single files, so using makefile is not convenient.
I could not find exact answer anywhere among previuos answers.
I guess you could put something like this in your .bashrc file:
alias g++='g++ -WHATEVER'
I'm personally not a big fan of this, because it could get confusing. I would rather do something like this:
alias my_g++='g++ -WHATEVER'
Related
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.
i use [objdump XXX.o -Ws] output many string lines, they are all struct names in my other c++ head files, but some of them are repeated, make my XXX.o so big.
can anyone tell me, are the repeated struct names in debug_str required for gcc ? and is there some parameters of gcc to reduce the repeated string? thanks.
can anyone tell me, are the repeated struct names in debug_str required for gcc ?
Yes, they are required if you want to debug your program in a friendly way.
and is there some parameters of gcc to reduce the repeated string? thanks.
Not directly, no.
You can remove the -g or similar arguments when you compile. Though that will not make source level debugging possible anymore.
You can also remove that information yourself, by running the strip -g command on your binary or object files.
Remember that this is debug information, used by a debugger. That information is not loaded or used when running your program normally.
I currently use some old C library for getting program options and would like to replace that with some proper C++ (mainly to become independent of that library, which is a real burden). I was looking into using boost.program_options, but am not sure it can support all I want. Some things I want is:
allow the following command-line syntax: myprogram option=value (in particular, I don't really want the --option value syntax)
use a default value if no value is provided (obviously this can be done in my program, but support in the options library would be nice)
allow default options (which are always present even if I don't give them) and an automatic help output consisting of all the options and their descriptions
allow mathematical parsing, i.e. (command line) myprogram option1=Pi option2=3/5 option3=sqrt(2) to give 3.1415..., 0.6, and 1.415... in my program
allow single values to be expanded. Let option_3Dpoint correspond to an std::array<double,3>, I want both myprogram option_3Dpoint=0,0,0 and myprogram option_3Dpoint=0 (expanding to 0,0,0) to work
Which of these can be supported by boost.program_options? Are there any alternatives?
boost.program_options is very good library. You can use to parse config files aswell. Answers:
Dont know but seems no builtin support.
Yes.
Yes.
No unless you make your own expression evaluation handler or use some other boost libs to do this.
Yes, you will need to write your own handler which creates 3DPoint object from string like 0,0,0
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.
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__);