How can I specify an include file from the GCC Command Line? - gcc

Using GCC under Windows, I would like to be able to specify on the gcc command line (or from a manually managed makefile) the name of a specific include file to be included in the file being compiled. As I see it, ideally the source code file would contain a line something like…
#include INCLUDEFILENAME
…then a filename specified on the gcc command line would be substituted for the INCLUDEFILENAME text.
It seems I can get close to achieving this by defining a macro called INCLUDEFILENAME on the gcc command line using the -D option (eg. -D INCLUDEFILENAME="C:\TestLib\Test1.h") but when the filename text gets substituted into the #include statement it is not enclosed in double quotes, and without these it is not recognized as a file to be included. Of course…
#include "INCLUDEFILENAME"
…doesn’t work as INCLUDEFILENAME then becomes a string literal and does not get replaced by the macro value. I have tried other ways of specifying the double quotes (\x22, \", "\"", etc) but these don’t seem to work on the #include line.
I am aware of the gcc -include option which it seems can force a file to be included without it being mentioned in any way in the source file, but I would prefer that the source file indicates that an include file is to be included here but that it’s name is specified “externally” to the source file (ultimately, from the makefile).
Any suggestions on how I can achieve this would be appreciated.

You have to include the double quotes " as part of the define (or <>, as the case may be):
% cat test.c
#include <stdio.h>
#include OTHERFILE
int main() { printf("%s\n", func()); }
% cat func.c
char *func() { return "It worked."; }
% gcc test.c -DOTHERFILE='"func.c"'
% ./a.out
It worked.
%

You can use the ugly but classic stringification trick:
#define STRINGIFY2(x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#include STRINGIFY(INCLUDEFILENAME)

Related

gcc not respecting my include directory order

I'm attempting to build some code using a temporary version of an include file in my local ../include/records directory. The orignal lives in /home/apps/include/records. I have my gcc command set to search ../include before /home/apps/include, but it's still picking up the original module from /home/apps/include and reporting errors. If I rename the original in /home/apps/include, then gcc picks up my local edited copy and it compiles clean. So, what's up with the include order...? This 'local include first' logic has always worked for me in the past, but this may be the first time I've used it since migrating from AIX to Linux.
Is there something beyond the order of the -I command-line options that could be overriding the requested include order?
The source module include statment is:
#include "records/novarec.h"
and the gcc command line looks like this:
$make
gcc -DLINUX64 -c -g -I. -I../include -I/home/apps/include -I/home/apps/include/em -I/home/apps/include/odbc -Wno-implicit-function-declaration -Wno-implicit-int -Wno-format-security -Wno-format-truncation -Wno-discarded-qualifiers novaget.c
The compiler complains about an undefined value that's in my local copy of novarec.h, but not in the production /home/apps/include/records/novarec.h:
novaget.c: In function ‘calcComscoreDemoV1’:
novaget.c:2651:15: error: ‘CSCD_W21_49’ undeclared (first use in this function); did you mean ‘CSCD_W25_49’?
fval = *(dm+CSCD_W21_49);
^~~~~~~~~~~
It seems like the answer is this:
My module called in 2 include files. The first one also includes the second one - and the first one lives in /home/apps/include. That seems to make gcc search there for the second include file - even though /home/apps/include is not the first include directory in my path.
When I reverse the 2 include statements in my .c file, the correct path is followed for novarec.h. i.e. when I code:
#include "spottvdemos.h" (this modules has a #include "records/novarec.h")
#include "records/novarec.h"
novarec.h gets picked up from /home/apps/include, but when I code:
#include "records/novarec.h"
#include "spottvdemos.h"
novarec gets picked up from ../include, which is what I wanted.

My compiler doesn't parse escape sequences as expected

I am trying to run static analysis on my code using a tool. The Makefile contains:
export TASK=MY_TASK_NAME
my_static_code_tool.exe <arguments> -- gcc <arguments..> -D__TASK_NAME__=\"$(TASK)\" -o missionFile.o missionFile.c
I find that this executes without an issue on RedHat but fails to run on my Cygwin environment. I assign __TASK_NAME__ variable to an unsigned char in a C file such as:
const unsigned char TASK_NAME[] = __TASK_NAME__;
I get the error as:
gcc: no input files
I am very sure my arguments are all correct and I am referring to sources in the correct directory. To me it looks as if the -- stops the parsing of escape sequences in the command on Windows. Can anybody help me with a workaround?
The -- is used by the tool to introduce the compiler and its arguments [and thereby inform the tool that the following is compiler specific]. The GCC had all the required source/files/configuration defined in the Makefile. However it was not processed completely in the Cygwin shell (the command processing stopped with the escaping hence the corresponding gcc error).
The solution I employed to make this work was pre-processor stringification.
C file:
#define STRINGIFY_IT(str) STRING_OF(str)
#define STRING_OF(str) #str
const unsigned char TASK_NAME[] = STRINGIFY_IT(__TASK_NAME__);
Makefile:
export TASK=MY_TASK_NAME
my_static_code_tool.exe <arguments> -- gcc <arguments..> -D__TASK_NAME__=$(TASK) -o missionFile.o missionFile.c
So, if any of you face such problems in the future with 3rd party tools, try not to pass string arguments through the command line to GCC (as they will need to be escaped and might break the command)

Invoking the preprocessor from a shell or shell-like program

As mentioned in the title I want to invoke the preprocessor from a shell.
Let me clarify:
Suppose I have to invoke Preprocessor for command patch in Linux say:
patch -p1 -D `"{what and how should i write here }"` < patch.patch
Patch command has an option -D where I can define a preprocessor (to my understanding). I tried searching on Google I got only one link I couldn't understand it properly.
Please guide me with an example (or proper reference).
What all can be written in -D option of any command?
Are constructs same for all command are different for different commands?
What can be the input variables?
The -D option to patch means that the changes made to the patched file will be surrounded by #ifndef X / #else / #endif if X is what you specify as the argument to the -D option.
For example:
$ cat file-1.c
#include <stdio.h>
int main(void)
{
printf("Hello world\n");
return 0;
}
$ cat file-2.c
#include <stdio.h>
int main(void)
{
puts("Hello world");
return 0;
}
$ diff -u file-1.c file-2.c > patch
$ patch -DPRINTF_TO_PUTS -i patch --verbose
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- file-1.c 2013-02-01 00:33:01.000000000 -0800
|+++ file-2.c 2013-02-01 00:33:17.000000000 -0800
--------------------------
Patching file file-1.c using Plan A...
Hunk #1 succeeded at 2.
done
$ file-1.c
#include <stdio.h>
int main(void)
{
#ifndef PRINTF_TO_PUTS
printf("Hello world\n");
#else
puts("Hello world");
#endif
return 0;
}
$
So, to answer your questions:
You should put a valid C identifier after -D on the patch command line.
Different commands apply different meanings to any given option letter. You can find information about common interpretations for options at The Art of Unix Programming, but there are only 52 alphabetic (single-letter) options and there are many more different meanings for arguments to different commands than that.
I'm not sure what you mean by this.
None of this invokes a C preprocessor from the command line. If you need to do that, look for a program cpp on your system. If you can't find cpp anywhere, you may end up invoking gcc -E instead.

Don't understand gcc that well, but I can't find why it's not working

I'm trying to compile a simple "hello world"
file_name
#include <stdio.h>
void main () {
printf ("Hello World\n");
}
then I try: gcc file_name and I get "File not recognized. File format not recognized"
I however am 100% sure I did the exact same thing a few weeks back (just to see if it works, as now) and it worked, so I just don't get it.
gcc -ver // returns 4.6.1 if this helpes
Also how is gcc -o supposed to work ? The manual (man gcc) is just gibberish at times (for me)
Let's say you program is saved as helloworld.c. Typing gcc -o myprog helloworld.c would compile helloworld.c into myprog. That way, when you want to run the program, all you type in the command line is ./myprog
gcc tries to guess the language used (e.g. C or C++) based on the extension of the file, so you need to ensure you have the proper file extension (usually .cpp for C++ and .c for C dource files). Alternatively, read the manual if there is a command line option to explicitly state the format (regardless of the extension).
As for the "-o" command line parameter: the name specified after that option is the name of the object file created from the compiled source file. The object files are then linked together to form an executable

How to undefine a define at commandline using gcc

How do I at compile time undefine a compiler macro using gcc. I tried some compile args to gcc like -D but I can't get to see the "not defined" message.
Thanks
#include <iostream>
#define MYDEF
int main(){
#ifdef MYDEF
std::cout<<"defined\n";
#else
std::cout<<"not defined\n";
#endif
}
You can use the -U option with gcc, but it won't undefine a macro defined in your source code. As far as I know, there's no way to do that.
You should wrap the MYDEF definition in a preprocessor macro, the presence of which (defined on the command line) would then prevent MYDEF from being defined. A bit convoluted to be sure but you can then control the build in the way you want from the command line (or Makefile). Example:
#ifndef DONT_DEFINE_MYDEF
#define MYDEF
#endif
Then from the command line when you don't want MYDEF:
gcc -DDONT_DEFINE_MYDEF ...
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Preprocessor-Options.html#Preprocessor-Options
The -U options seemed like what you could have needed... but then again you can't override a definition contained in your source code without resorting to more preprocessor directives.
You can resort to filtering source code and give this back to gcc for compilation, like this pseudo code:
grep -v "define MYDEF" yourFile.c | gcc -o yourFile.o -xc -
Hope it helps.
The code use case is not right. As I see, you have hard coded #define in the file. If compiler initially assumes MYDEF undefined, it will define it once it start processing the file.
You should remove the line #define MYDEF. And I hope your test case will work, if you pass MYDEF to -D and -U.
Here is one possibility that doesn't completely cover your use case but which I found to be helpful in my case.
If your MYDEF were #defined in a separate header file #included from the .c file you could force the definition of the #include guard macro with the -D option (thus preventing the MYDEF #definition) then either actively #define (still with the -D option) MYDEF to something else or just leave it undefined.
It is clear that anything else defined in the header file would also be missing but this was for me a solution to forcedly undefine a macro without changing the third-party code.

Resources