Conditional Compilation

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Conditional Compilation

3,139 Views
SebaS
Contributor III
Hello everybody, I need your help again....

Don't be scared, it's long but it's not hard to understand

Today's about conditional compilation... I had a project with 2 different hardware interface, but the same sources code (almost). I've been working on these 2 projects separately and now I want to create an UNIQUE project containing the prevoius 2. There only little differences between them... Before continuing I want to illustrate what I'm saying: (those are examples of what I have in each file)

code_1.c:
                byte var 1;
                void func_1 (void){
                    CODE
                }
               
code_1.h:
                extern byte var 1;
                extern void func_1 (void);


code_2.c:
                byte var 2;
                void func_2 (void){
                    CODE
                }

                func_1();      // ***** FUNCTION FROM CODE_1.c*********
               
code_2.h:
                extern byte var 2;
                extern void func_2 (void);

So what I have is 2 .c files with variables and functions definitions and each .c file has its header file with the variables and functions declarations. I also have a file main.c where I include the prev 4 files:

main.c:
    #include code_1.h
    #include code_2.h

    #include code_1.c
    #include code_2.c

I don't want to mess with your head, so I'll try to be as clear as I can. Like I said before I had 2 hardware interfaces... well the first one uses the 2 code files (code_1.c and code_2.c) but the second one only uses code_2.c... So my first attempt to create an unique project was to use compiler directives (I'm starting to learn about that) and I change my main.c file:

main.c:
        #include code_1.h
        #include code_2.h

        #ifdef   HARD_1
            #include code_1.c
       #end if
        #include code_2.c  

So, by defining or not the macro HARD_1 I choose to compile code_1.c or not... I do not use the conditional compilation for the header files since they only contain declarations and not any code... So I guess I can leave them like that (is that correct?)...
But now, here's the problem... If I don't declare HARD_1 code_1.c is not compiled. But code_2.c uses a function from code_1.c and so the linker says that this function is not defined... How can I solve that??... Because the shared function (func_1) is not necessary for the second project but it is for the first project... At first I think that since func_1 is declared in code_1.h that error wouldn't appear.... I know there's a way to solve it by modifing code_2.c like that:

code_2.c:
               byte var 2;
                void func_2 (void){
                    CODE
                }
               
                #ifdef HARD_1
                    func_1();      // ***** FUNCTION FROM CODE_1.c*********
                #endif

But I don't want to do that because I had a LOT of sources files and I don't want to touch them....


Please help!!! THANKS!!!!
      





Labels (1)
Tags (1)
0 Kudos
6 Replies

587 Views
Lundin
Senior Contributor IV
Never ever #include .c files. If you "must" do that, something is wrong in the structure of your program. It is the linker that keeps track of .c files, not the compiler. On most IDEs you simply add the .c files to a "project" and the linker fixes things automatically.

In your case, if code_2 is calling functions from code_1, you really have no other choise but compiling code_1. There is no magic compiler switch that will save you from that.

Nothing is however stopping you from moving the common functions into a third .c file, and include the .h file corresponding to that code from both of the other two .c files.
0 Kudos

587 Views
mke_et
Contributor IV
I'm not doing it from C, but what's the problem of conditional inclusion of files?

If it's referenced in the project and not used, the most that could happen is you get an unnecessary build if you touch only the non-included file. If you write your modules appropriately, then you can just switch them on or off at build with includes with no problems. IF you write them correctly.

I do it all the time with assembly. I'm using a 128K part, and I have every flash page used. In fact, I sometimes have more than one 'module' on a flash page (in one case 3 of them). If I were to build every single option for the board, I'm out of space, so I CAN'T build everything. Usually though I have 2 empty flash pages free for all but a miniscule number of customers (about 20 out of 20000) and even for those 20 I have 1 free, but a different one than I have for the others.
0 Kudos

587 Views
bigmac
Specialist III
Hello Mike,
 
For assembly projects, what you need to explicitly include, and what can be done via the project file and the linker would depend to a large extent on whether the code format is absolute (no linker) or relocatable.  However, C projects are generally relocatable.
 
Using the linker to sort out which functions need to be incorporated within the code output can potentially avoid errors due to multiple definitions of the same function, that can occur with multiple includes of the same file.
 
I assume that a further advantage of using the linker is that functions within a file that are compiled, but remain unused by the project, will actually not be linked into the generated code.  This applies to library functions, and I am assuming it is generally applicable.
 
Regards,
Mac
 
0 Kudos

587 Views
mke_et
Contributor IV
Ok, I see your point. I guess it could still be done, but the amount of care I had to put into making it work with assembly would be kicked up another order of magnitude to use the same scheme with C.

Probably what helped in my case is I did EVERYTHING for my code. When I started my first project with a 9S12 I quickly found I didn't want to use any of the defaults or other tricks, tips, and tools that came with the development package and did everything myself, even stuff like the cold start and flash page management. The only thing I really used from the provided package was the file that defined the register names. Then I got bit on that when I found one of the registers I needed to use named something different in the include file from what it was named in the 9S12 reference book.
0 Kudos

587 Views
SebaS
Contributor III
Thank to all for your contribution.... Sadly I didn't manage to solve the problem, so I'm doing it as I was going to do it for the first time....  I'm gonna put the condition inside each file... I mean:

main.c:
    #include code_2.c
   
    #ifdef MACRO_1
       #include code_1.c
    #endif


code_2.c:
    #ifdef  MACRO_1
       func_1();
    #endif

    void    func_2 (void){
    }

So I don't call the function unless code_1.c is compiled... This way I also save a little ROM memory...

THANKS A LOT!!!

One more thing, I didn't understand why you said I should never ever #include file.c I do that so I can have a better control of the sections where I put the code (I also use #pragma to allocate code pages)... Before, I added the C files to the project and they were automatically compiled but it was kind of messy to control the page where the code was at (note: I use HCS12)... I do that also because I'm mixing C and ASM and in ASM I do it that way (include file.asm)

The thing is that I also have to use the conditional compilation in ASM so I use the "ifdef" and "endif"... If you know an easyest way to make this kind of projects, please let me know... Thanks again!
0 Kudos

587 Views
mke_et
Contributor IV
I'm not a 'C' person, but if it were me, I'd duplicate the function in both the files and set it up so either of the files compiles alone but not with the other. Then use an ifdef else endif structure, and include either but not both of the files.

This also gives you some flexibility in code that may be specific to the file you're including it in. But be careful that in/out parameters are consistant, or other places in your program that call the routines may act strange.

Or, for further flexibility change the ifdef variable to an equate, and have multiple files, and which one you pick depends on the value of your variable.
0 Kudos