mewais
mewais

Reputation: 1337

error in gcc -D option with strings

I'm using a shell that calls a makefile to recompile the same project with different #define options.

the shell calls the makefile like this:

make UserDefined="-D SomeDefines -D InputFileName=\"input/In$SIZE.txt\"" -s

where $SIZE is a numeric variable that for example equals 32 this compiles fine for all files of the project but not main.cpp the command for main.cpp is :

g++ $(CFLAGS) $(Main) \
    -I$(CUDA_HOME)/include \
    -lpthread -o main.o

$(Main) is path to input file $(CUDA_HOME) is path to cuda libraries and $(CFLAGS) is : CFLAGS = -c -Wall $(UserDefined) -std=c++0x

when executing this command the following errors occur:

../src/main.cpp: In function ‘int main()’:
../src/main.cpp:11:30: error: ‘input’ was not declared in this scope
../src/main.cpp:11:30: error: ‘In32’ was not declared in this scope

line 11 from the main.cpp file:

InputSignalFile.open(InputFileName);

I tried it from the shell and from command line . It did not work. I also tried " instead of \". same error. I tried creating a new variable like this:

Var=\"input/In$SIZE.txt\"

and then :

-D InputFileName=$Var

did not work too. but when I #define InputFileName "input/In32.txt" in main.cpp it just works fine.of course I can't do this as I need to change the number every time. any help ??

Upvotes: 0

Views: 3504

Answers (1)

MadScientist
MadScientist

Reputation: 100856

The most useful thing you could have shown us, you didn't provide: make will print the compile command that it invokes, and looking at that will tell you EXACTLY what's wrong.

Don't use the -s flag to make, when you're debugging makefiles!!

Looking at your makefile I assume it looks something like this:

g++ -c -Wall -D SomeDefines -D InputFileName="input/In$SIZE.txt" -I ...

The problem is you're going to need even more quoting. You have to quote the argument given to make from the shell you're using to run make, then you have to quote the argument again from the shell make runs, because the compiler wants to see the double-quotes.

You'd have to run something like this:

make UserDefined="-D SomeDefines -D InputFileName='\"input/In$SIZE.txt\"'" -s

which will cause the compile line to look like this:

g++ -c -Wall -D SomeDefines -D InputFileName='"input/In$SIZE.txt"' -I ...

which will work. However, it would be much, much simpler if the user specified just the size value, and you constructed it inside the makefile:

make SIZE=$SIZE UserDefined="-D SomeDefines"

CFLAGS = -c -Wall $(UserDefined) -D InputFileName='"input/In$(SIZE).txt"' -std=c++0x

A few other notes about your makefile:

  • You should be using CXXFLAGS for compiling C++ code, not CFLAGS (which is for C code)
  • You should not add -c to CFLAGS; put it into the rule itself. You should add CFLAGS to the link line as well so you don't want -c there.
  • You don't want to link libraries (-lpthread) on the object compile line. Maybe you meant -pthread here?
  • You should separate out the preprocessor flags like -I and -D from the compiler flags, and put the preprocessor flags in CPPFLAGS so they can be included in various different types of compilation.

Upvotes: 6

Related Questions