linker script conditional includes - c++

I am converting a scatter file to linker file. Now the problem is armlink can accept symbols e.g --predefine=-DSOME_VARIABLE at link time and in the scatter file other header files can be included with the #include "someHeader.h directive. There are files which are included in scatter file on the bases of defined symbols e.g
#ifdef INCLUDE_RANDOM_FILE
randomFile (*)
#endif
in linker script these options are not available. is there a work around for this problem.

There are two fairly simple options.
Use a compiler pre-processor and use the output.
Invert your logic.
Use the C pre-processor in GCC or any compiler.
$(CC) $(DEFINES) -E -P -o output.lds -x c-header input.lds
This option allows the full range of pre-processor defines and conditional inclusion.
The invert option is to have separate master 'lds' files for each case you need and then include the common portion.
flash.lds
start = 0xf000000;
size = 0x100000;
include "common.lds"
ram.lds
start = 0x0;
size = 0x10000;
include "common.lds"
The same can be production and debug variants. This is fairly easy if the permutations are low. Otherwise, I would use the pre-processing.
The bin-utils ld documentation also has a good example with a linkcmds.memory file. You would have to symlink or copy the linkcmds.memory file in your Makefile or build process.
It is often surprisingly easy to get rid of the conditions by using weak symbols and stub file and routines that make conditions unneeded.

Related

How to make #if preprocessor be conditional upon a values in another different file?

For example if a "settings" file exists and has the following:
system,ubuntu
Can a preprocessor #if be used to customise the code based of the values in the settings file? For example:
#if lookup_system == "ubuntu" // loopup_system is pseudocode
Another use can could be to look up whether or not the code is running on production servers.
You cannot do that.
However, you might generate some header file from external data. The autoconf utility does that (actually generates some configure script generating such a header).
More generally, you should set up your build automation system (e.g. edit your Makefile for GNU make, or your build.ninja for ninja) to generate that header file suitably (perhaps with a tiny script, your own C++ -another- program, or whatever). You can also have a clever build system passing specific -D flags to your compiler.
Remember that C++ files (both header files e.g. .hh and implementation files e.g. .cc ...) can be generated by something else. This is common practice.
Read more about your preprocessor, e.g. about cpp. It is a compile only thing. With GCC you can get the preprocessed form foo.ii of your foo.cc file with a command such as g++ -C -E foo.cc > foo.ii.

Preprocess C-Code with gcc or cpp without resolving macros

Does there exists a flag that I can pass to one of these preprocessors that causes the preprocessor to not resolve any macros in the code? I"m trying to use it just to concatenate any included header files into one file. Thanks!
From the manual
-fdirectives-only
When preprocessing, handle directives, but do not expand macros.
Read the full entry for complete details.
Add the -P option to suppress #line directives, e.g.
g++ -E -P -fdirectives-only ... file.cpp
or:
cpp -P -fdirectives-only ... file.cpp
AFAIK there is no such flag. If you only want to concatenate header files - go ahead and write a short program for this.
You may anyway need sch program as the preprocessor does more than including headers and extending macros. It is also responsible e.g. for concatenating string literals, so e.g. "This""And""That" is turned into "ThisAndThat". So you will get some unexpected changes in your sources anyway.

C++ makefiles - Header files dependencies with external libraries

I want to add dependency target to my Makefile, I knew it could be done through makedepend or g++ -MM option, and I am open for using any of them but I prefer -MM option as it allowed me to exclude standard libraries (I do not know if makedepend can do it or not).
The problem is that I use some external libraries headers in my application and I want these headers to be excluded from the dependencies generated so how can I exclude certain directories from these generated dependencies.
[Edit-start] I already tried using grep -v but the problem is that if the excluded line is the last wrapped line in a certain target, the next target would be joined to that target due to the escape '\' character at the end of the line before it leading to a corrupted dependency rule. In addition to that the time it takes to go through the library headers parsing them [Edit-end].
Another problem is that How can I edit the suffixes of the generated object-files targets, I am using a Makefile that compiles the source files provided through a variable by using through a target like that:
%.o: %.cpp
g++ $< -o$*.o ...
The first problem (external libraries) could be solved by first using grep -v and then passing the output to sed 'N;s/\\\n\(.*\.o\)/\n\1/;P;D' which removes unneeded escape characters '\' to solve the problem of joined targets due to the exclusion introduced by grep -v. But the time overhead of going through the external libraries headers parsing them still as it is.
And the second problem (generated targets suffixes edit) could be solved by sed also using sed 's/.o:/$(MY_SUFFIX):/' where $(MY_SUFFIX) is the suffix to replace .o in the generated target rules.
#pragma GCC system_header is a gcc pragma to identify system header.
You may use proxy header with this pragma which include library header
//Proxy_header.h
#ifndef PROXY_HEADER_H
#define PROXY_HEADER_H
#pragma GCC system_header
#include "external_library.h"
#endif
but post-processing dependencies seems cleaner.
-MF file seems to be the gcc option you want to edit the suffix of dependency files.

Creating several precompiled header files using GNU make

I use gcc (running as g++) and GNU make.
I use gcc to precompile a header file precompiled.h, creating precompiled.h.gch; the following line in a Makefile does it:
# MYCCFLAGS is a list of command-line parameters, e.g. -g -O2 -DNDEBUG
precompiled.h.gch: precompiled.h
g++ $(MYCCFLAGS) -c $< -o $#
All was well until i had to run g++ with different command-line parameters.
In this case, even though precompiled.h.gch exists, it cannot be used, and the compilation will be much slower.
In the gcc documentation i have read that to handle this situation,
i have to make a directory called precompiled.h.gch and put
the precompiled header files there,
one file for each set of g++ command-line parameters.
So now i wonder how i should change my Makefile to tell g++ to create
the gch-files this way.
Maybe i can run g++ just to test whether it can use any existing file
in the precompiled.h.gch directory,
and if not, generate a new precompiled header with a unique file name.
Does gcc have support for doing such a test?
Maybe i can implement what i want in another way?
It seems weird to answer my own question; anyway, here goes.
To detect whether a suitable precompiled header file exists, i add a deliberate error to my header file:
// precompiled.h
#include <iostream>
#include <vector>
...
#error Precompiled header file not found
This works because if gcc finds a precompiled header, it will not read the .h file, and will not encounter the error.
To "compile" such a file, i remove the error first, placing the result in a temporary file:
grep -v '#error' precompiled.h > precompiled.h.h
g++ -c -x c++ $(MYCCFLAGS) precompiled.h.h -o MORE_HACKERY
Here MORE_HACKERY is not just a plain file name, but contains some code to make a file with unique name (mktemp). It was omitted for clarity.
There is a simpler way than introducing an #error in precompiled.h: never create this file at all. Neither G++ nor Visual C++ (at least up to 2005) expect the "real" file to be there, if a precompiled version is around (and if they get the necessary compilation flags).
Let's say the list of #includes that we want to precompile is called "to_be_precompiled.cpp". The filename extension doesn't matter much, but I don't like to call this a .h file, since it has to be used in a way different from genuine header files, and it's easier in Visual C++ if this is a .cpp. Then pick a different name to refer to it throughout the code, let's say "precompiled_stuff". Again, I I don't like to call this a .h file, because it's not a file at all, it's a name to refer to precompiled data.
Then in all other source files, the statement #include "precompiled_stuff" is not a genuine include, but simply loads precompiled data. It's up to you to prepare the precompiled data.
For g++, you need a build rule to create "precompiled_stuff.gch" from a source file whose name doesn't matter to the compiler (but would be "to_be_precompiled.cpp" here).
In Visual C++, the string "precompiled_stuff" equals the value of the /Yu flag and the precompiled data loaded comes from a .pch file with an unrelated name, that you also created from an unrelated source file (again "to_be_precompiled.cpp" here).
Only when building with a compiler without precompiled header support, a build rule needs to generate an actual file called "precompiled_stuff", preferably in the build directory away from the real source files. "precompiled_stuff" is either a copy of "to_be_precompiled.cpp", a hard or symbolic link, or a small file containing #include "to_be_precompiled.cpp".
In other words, you take the viewpoint that every compiler supports precompilation, but it's just a dumb copy for some compilers.

Filter C++ through a perl script?

I have a perl script I'd like to filter my cpp/h files through before gcc processes them normally -- basically as an extra preprocessing step. Is there an easy way to do this? I realize I can feed the cpp files to the script and have gcc read the output from stdin, but this doesn't help with the header files.
The classic way to handle such a process is to treat the source code (input to the Perl filter) as a new language, with a new file suffix. You then tell make that the way to compile a C++ source file from this new file type is with the Perl script.
For example:
New suffix: .ccp
New rule (assuming .cc suffix):
.ccp.cc:
${FILTERSCRIPT} $<
Add the new suffix to the suffix list - with priority over the normal C++ rules.
The last point is the trickiest. If you just add the .ccp suffix to the list, then make won't really pay attention to changes in the .ccp file when the .cc file exists. You either have to remove the intermediate .cc file or ensure that .ccp appears before .cc in the suffixes list. (Note: if you write a '.ccp.o' rule without a '.ccp.cc' rule and don't ensure that that the '.cc' intermediate is cleaned up, then a rebuild after a compilation failure may mean that make only compiles the '.cc' file, which can be frustrating and confusing.)
If changing the suffix is not an option, then write a compilation script that does the filtering and invokes the C++ compiler directly.
The C and C++ preprocessor does not have any support for this kind of thing. The only way to handle this is to have your makefile (or whatever) process all the files through the perl script before calling the compiler. This is obviously very difficult, and is one very good reason for not designing architectures that need such a step. What are you doing that makes you think you need such a facility? There is probably a better solution that you are not aware of.
How about a wrapper around gcc that runs your Perl script and then calls gcc? Call it something like plgcc and set CC=plgcc in your makefile. Your script will have to be smart enough to process the include directives -- unless your script calls just the pre-processor to bring in the includes, does its thing, and then calls gcc.
GCC allows you to use your own preprocessor. You could set your script as the preprocessor then run the output through cpp (the normal gcc pre-processor). Look at the gcc manual for -B and -no-integrated-cpp command line options.
Warning - I have never tried it myself so don't know how messy it might be (bear in mind though that for many years lots of languages, including C++, were implemented as preprocessors to a c compiler so support shouldn't be too bad).
I've handled cases like this in the past by doing something like the following. This approach assumes that the unprocessed source code can be distinguished through a naming scheme of some sort, in this case suffixing the basename with _pp.
# These are your source files to be preprocessed
SRC_RAW = mysrc_pp.cpp
# These are the source files after preprocessing
SRC_PP = $(patsubst %_pp.cpp, %.cpp, $(SRC_RAW))
ALL_SRC = $(SRC) main.cpp other.cpp
OBJ = $(patsubst %.cpp, %.o, $(ALL_SRC))
$(SRC): %.cpp: %_pp.cpp
$(PERL) $< > $#
$(OBJ): %.o: %.cpp
$(CXX) ...
This does not, however, handle the case where you have header files which need preprocessing. In that case you would need similar rules for creating them.