CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Command line parameters with preprocessor defines

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
nikolai



Joined: 28 Apr 2010
Posts: 5
Location: Houston

View user's profile Send private message

Command line parameters with preprocessor defines
PostPosted: Mon Oct 21, 2013 1:19 pm     Reply with quote

I have an application that I maintain for different versions of hardware. Essentially there are preprocessor define statements throughout the code that control what code is compiled for each hardware type. In the past, I would have to manually comment out the #DEFINE statements and compile within MPLAB for each build type. I'm trying to automate this by building all of the output files sequentially using a Powershell script.

I already know that I can define a preprocessor variable in the command line like this:

CCsc +FH +DH +LN +T +A +M -Z +Y=9 +EA `#FILENAME=$somevariable main.c

This also works if I save the arguments as a string.

$arguments = "+FH +DH +LN +T +A +M -Z +Y=9 +EA `#FILENAME=$somevariable main.c"
start-process Ccsc $arguments

The problem is that I have addition variables that I want to declare in the command line which don't hold a value.

CCsc +FH +DH +LN +T +A +M -Z +Y=9 +EA `#FILENAME=$somevariable #TYPE= #DEBUG= main.c

When I look in main.esym, I can see that the DEBUG variable is not defined and that TYPE=" #DEBUG". So it's just grabbing the next value in the list in the assigment. In main.esym those variables would otherwise be defined as TYPE="" and DEBUG="". But it doesn't seem to compile if I just put double quotes in the string, even if I escape them from Powershell interpretation. I'm not sure if this is a PS quirk or the compiler (v4.109).
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Mon Oct 21, 2013 1:43 pm     Reply with quote

Needs inverted commas.

Syntax is:

#FRED="TRUE"

To set the #define 'FRED' to the value 'TRUE'

etc..

Obviously though this gets overridden if there is a #define for FRED in the code.

Unless you want to define it as having a value, there is no point in defining it. So empty inverted commas make no sense.

Best Wishes
nikolai



Joined: 28 Apr 2010
Posts: 5
Location: Houston

View user's profile Send private message

PostPosted: Mon Oct 21, 2013 2:22 pm     Reply with quote

I've tried defining them with values and they don't get detected by the #ifdef statements in the code. When I did this manually my code would look like this:

#define TYPE
#ifdef TYPE
do something
#else
do something else
#endif

But if I define them as anything at all in the command line or the code (i.e. #define TYPE 1), the #ifdef evaluations don't work.
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Mon Oct 21, 2013 2:57 pm     Reply with quote

You need to understand the limitations of the Windows command line. This is why it works from @ file (where these limitations do not exist), and why it has to assume that the data after the =, is what is meant to be put into the define, unless a inverted comma 'value' is present.

I don't know what you are doing wrong, but a simple test, with:

CCSC main.c #test="TRUE"

and a simple block of code as:
Code:

#ifdef TEST
     delay_us(10);
#else
     delay_us(20);
#endif


compiles to produce:
Code:

.................... #ifdef test
....................      delay_us(10);
000F:  MOVLW  10
0010:  MOVWF  77
0011:  DECFSZ 77,F
0012:  GOTO   011
0013:  NOP
.................... #else
0014:  GOTO   00F
....................      delay_us(20);
.................... #endif


in the lst file, while removing the #TEST="TRUE", gives:
Code:

.................... #ifdef test
....................      delay_us(10);
.................... #else
....................      delay_us(20);
000F:  MOVLW  20
0010:  MOVWF  77
0011:  DECFSZ 77,F
0012:  GOTO   011
0013:  GOTO   014
0014:  NOP


Correctly switching what is compiled. Even just using #test=" " (with a space), happily switches....

Simplify a bit and try a test like this.

I've used this on many occasions to give different version programming, without problems.

Best Wishes
nikolai



Joined: 28 Apr 2010
Posts: 5
Location: Houston

View user's profile Send private message

PostPosted: Tue Oct 22, 2013 8:00 am     Reply with quote

As expected I made a stupid error. I had an #endif commented out and all of the defines below it weren't being detected. No initializing the variables in the command line to ANY value works as expected now.

Thanks
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Oct 23, 2013 2:04 am     Reply with quote

I haven't used any command line tools for nigh on 15 years. I never saw the attraction with remembering tens of often non-intuitive options and arcane syntax. I'd much rather get an IDE to deal with that for me. That said, I do face the same sort of issues in my compilations. I have code that, through conditional compilation, compiles to several targets. Heck, in the mainframe/mini era it was often used to build operating systems. My first exposure to the technique was in sysgen'ing RT-11 and RSX-11M.

What I do is not try to control the compilation through options, i.e. defines, in the project options/command line/build script. Instead I have a wrapper C file for each target which simply has the relevant defines and possibly includes and then includes the top level code of the generic codebase. With this you simply build the required wrappers. All the options are in the actual source code, and not in a somewhat ephemeral project/build script, and therefore can be secured in a CVS more simply (as its C code not some version/environment/user specific script file in some relatively obscure and unfamiliar syntax that cannot easily be ported to any other compilation environment, or in may cases to another PC, or even to another location on the SAME PC!)

I also prefer self-selecting includes to implement optional functionality. This is where the include has a define to show its present, which is used in the main code to activate the calling code for the functionality. So whether the function is included in the target or not simply comes down to whether the relevant code/header was included or not. Something like:

Code:

// in application code.

// To turn off run time logging simply uncomment this include.
#include "Run_Time_Logging.c"

...

#ifdef RUN_TIME_LOGGING
    Save_Run_Times();
#endif

// Run_Time_Logging.c

#define RUN_TIME_LOGGING

...

void Save_Run_Times(void)
{

...

}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group