This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

conditional compilation on c55x using CCS 4



Hi All...

I have a project that contains many C source and header files along with a custom linker command (*.cmd) file and a Tconf script (*.tcf) file.

I have a requirement where in I need to disable certain part in each of these three (*.c, *.cmd and *.tcf) files conditionally using some compile time switch. 

I have got it working with separate defines in each type of the above files and got it working. But I need something common for all these 3 types. I want to change the setting at only one place and I should be able to achieve it. 

Please let me know if this is possible...if yes how..?

Thanks & Regards,

Ashok

  • Ashok H.S. said:
    I have a requirement where in I need to disable certain part in each of these three (*.c, *.cmd and *.tcf) files conditionally using some compile time switch. 

    The linker supports  #define symbols, both from the command line and in source, just as C does.  So, that part is straightforward.  I don't know how to do the same thing with Tconf.  I have asked for help on that.

    Thanks and regards,

    -George

  • tconf does not support C pre-processor #include/#define/#ifdef directives. 

    However, *.tcf files are processed by the Rhino JavaScript engine and, as a result, it's easy to conditionally run portions of a config script using  "if () {...} else {...}" statements based on either arguments passed on the command line or values in the environment.  It's also relatively easy for your script to either read a #define definition from an external file or generate a file that contains a definition. 

    So, there are several alternatives to achieve a single definition to control all of the tools:

    • set the value in the *.tcf script and cause tconf to generate a file with the definition (to be read by the compiler and linker), or
    • set the value in some C header file and have the .tcf script read it
    • set the value in a makefile and use --define for the compiler and linker and use tconf command line options to pass the definition to your .tcf script.  If you're using CCS projects you can define a single macro that defines a symbol and use this macro to augment the arguments passed to each of the tools

    Each approach has it's pros and cons.  The first two require the addition of a small script function to do the file reading/writing, but may be preferred because it keeps the definition in a "standard C file.  The third requires maintaining the definition in build-tool specific files which some developers prefer to avoid.

    I can provide further details depending on your preference.

    dave

  • Hi Dave,

    Thanks for the reply. Please guide me with more details for each of the three steps you have mentioned. It will be a good learning for me and will help in future also.

    Regards,

    Ashok

  • Hi Dave/George,

    I now have defined a C header file which will have this compile time flag and I have included that header file in all C files where it is required and the linker cmd file. This is working fine. Now I only have issue with TCF file.

    Either I should be able to use the same header file to get the flag into TCF file.

    Or I should declare a variable as flag in TCF file and it should come out as part of the cfg.h file which I can include in all the places where I need that flag.

    Please let me know which one is easy here..? and the ways to do it..?

    Regards,
    Ashok
  • I'll show you how to do the harder one first. 

    You can load a function that scans a C header looking for the definition of a symbol and, based on the result, conditionally execute portions of your .tcf script.  For example, the following .tcf script scans the file myheader.h looking for the last definition of the symbol FOO and executes one of two lines depending on whether the symbol was defined or not.  Of course, you can also use the value to control what is done in the script.

    /* load the function that reads definitions from a C Header */
    utils.importFile("header.tci");

    /* look for the definition of FOO in the file myheader.h */
    var val = header.getDefinition("myheader.h", "FOO");

    if (val) {
        /* FOO was defined in myheader */
        print("FOO = " + val);
    }
    else {
        /* FOO was not defined in myheader */
        print("FOO is not defined");
    }

    The contents of header.tci is just

    header = {};
    header.getDefinition = function (fileName, symbol) {

        /* define a regular expression to match a #define of symbol */
        var pat = RegExp("^#define\\s+" + symbol + "\\s+([^\\s]+)");

        /* open the specified header file */
        var file = new java.io.BufferedReader(new java.io.FileReader(fileName));

        /* read each line in fileName, looking the last line that matches pat */
        var line;
        var match = null;
        while ((line = file.readLine()) != null) {
            var tmp = String(line).match(pat);
            if (tmp) match = tmp;
        }
        file.close();


        /* if a match was found, return the defined value; otherwise return null */
        return (match ? match[1] : null);
    };

    Writing a C header file is even easier; there is no need to create a regular expression to "parse" the lines of the C header.  See rtsc.eclipse.org/.../The_XDCscript_Language for an example of writing files from Rhino.

  • Thanks a lot Dave. This really helped. 

    Regards,

    Ashok

  • One more Question..!

    I have around 5 different projects out of which one is the main project which has this CMD and TCF files. All other projects are library builds and the main project is the executable build which needs all the other 4 project libraries to be built before it gets built.

    But out of the other 4 projects, 3 projects require the configuration header file that gets generated from TCF file. So unless I build the main project I can't build the other 3 and unless the other 3 are built, I can't build the main. Some catch 22 situation..!!! how do I overcome this..?

    Right now I am building twice. Is it the only solution or is there a better way to handle it..?

    Regards,
    Ashok
  • CCS4 is quite old, so the following may not work, but ...

    In CCS, it's possible to separate the configuration step from the creation of an executable:

    • create a "configuration-only" project (that contains just the configuration file)
    • create a executable project (i.e., you main project) that references the configuration project and does _not_ have a configuration file

    Now you can build the configuration project, the library projects, and finally the main project without any circularity.  There is an example of this in CCS5 and CCS6 (look for the "configuration only" project for SYS/BIOS when creating a new project via File>New>CCS Project ).

    The CCS experts should be able to provide more information about whether this is possible in your version of CCS and, if so, more specific instructions.

  • Thanks a lot Dave. 

    I tried it in CCS4 but I don't have any option other than building it as library or as executable. 

    So looks like I'm stuck with 2 builds to get the proper build output.

    Any experts have any different solution to this..?

    Regards,

    Ashok

  • Ashok H.S. said:

    I tried it in CCS4 but I don't have any option other than building it as library or as executable. 

    So looks like I'm stuck with 2 builds to get the proper build output.

    Any experts have any different solution to this..?

    Unfortunately I couldn't find a way to create a separate configuration project for DSP/BIOS and CCSv4.