# Commandline Pp And Linker

## Recommended Posts

Hello,

I set up a PIC project, using eclipse. Don't ask me why, but I simply prefer this IDE above others. This means I try to compile and link my files using the commandline (via GNU Make).

I'm trying to compile and link my project .c files to a .hex file. I'm using multiple source files (both .c and .h).

/* Main.c */
#include <system.h>
#include "Standard_Types.h"
#include "Standard_Functions.h"

#include "RGBLeds.h"
...

/*RGBLeds.c */
#include <system.h>
#include "Standard_Types.h"
#include "Standard_Functions.h"

#include "RGBLeds.h"
...

/* RGBLeds.h */
#ifndef RGBLED_H
#define RGBLED_H

#include <system.h>
...
#endif

/* Standard_Functions.h */
#ifndef STANDARD_FUNCTIONS_H
#define STANDARD_FUNCTIONS_H

/* defined some functions */

#endif

When linking I get an error saying that the functions in Standard_Function.h are being redefined. Which is because I include the Standard_Functions file multiple times. But I think it should be fixed by using the preprocessor statements #ifndef STANDARD_FUNCTIONS_H and #define STANDARD_FUNCTIONS_H.

I think the problem is that i'm not actually using the .pp files from the preprocessor. But I don't now how to use them or where and when to use them. At link time?

BagascuW

Edited by BagascuW

##### Share on other sites

Ok, I think I solved the problem. Is it correct to compile the .pp files?

I'm now getting an other link time error, which I can't explain:

Couldn't find function/label by name:main

Does anyone know what causes this error, or how to fix it? Is it actually caused at link time, or are my .obj file not correctly created (compile time)?

I just can't get it to work, this is my command:

C:\PROGRA~1\SourceBoost\boostlink.pic -ld C:\PROGRA~1\SourceBoost\Lib -p RGB_LED -t PIC16F887 Main.obj RGBLeds.obj Buttons.obj libc.pic16.lib

Baga

##### Share on other sites

Here is what I'd do. Compile/link same project under SourceBoost IDE. If you get same build errors the problem is in your code. If everything builds fine than problem is in your Eclipse set up. This will indicate where to look further.

Pavel

##### Share on other sites

Ok, I tried to compile my project in SourceBoost IDE, but I get the error I had before about redefining functions. This is the output. Does it have anything todo with the fact I'm using multiple (sub)folders?

(BTW. The PP is invoked automatically in SourceBoost IDE, right?)

Building...
BoostC Optimizing C Compiler Version 6.85 (for PIC16 architecture)
http://www.sourceboost.com
Copyright(C) 2004-2008 Pavel Baranov
Copyright(C) 2004-2008 David Hobday

Single user Lite License (Unregistered) for 0 node(s)
Limitations: PIC12,PIC16 max code size:2048 words, max RAM banks:2, Non commercial use only

Main.c

success
BoostC Optimizing C Compiler Version 6.85 (for PIC16 architecture)
http://www.sourceboost.com
Copyright(C) 2004-2008 Pavel Baranov
Copyright(C) 2004-2008 David Hobday

Single user Lite License (Unregistered) for 0 node(s)
Limitations: PIC12,PIC16 max code size:2048 words, max RAM banks:2, Non commercial use only

Button\Buttons.c

success
BoostC Optimizing C Compiler Version 6.85 (for PIC16 architecture)
http://www.sourceboost.com
Copyright(C) 2004-2008 Pavel Baranov
Copyright(C) 2004-2008 David Hobday

Single user Lite License (Unregistered) for 0 node(s)
Limitations: PIC12,PIC16 max code size:2048 words, max RAM banks:2, Non commercial use only

RGBLed\RGBLeds.c

success
http://www.sourceboost.com
Copyright(C) 2004-2008 Pavel Baranov
Copyright(C) 2004-2008 David Hobday

failure
"C:\Program Files\SourceBoost\boostc.pic16.exe" Main.c -t PIC16F887 -I RGBLed -I Button -I C:\PROGRA~1\SourceBoost\include
"C:\Program Files\SourceBoost\boostc.pic16.exe" Button\Buttons.c -t PIC16F887 -I RGBLed -I Button -I C:\PROGRA~1\SourceBoost\include
"C:\Program Files\SourceBoost\boostc.pic16.exe" RGBLed\RGBLeds.c -t PIC16F887 -I RGBLed -I Button -I C:\PROGRA~1\SourceBoost\include
"C:\Program Files\SourceBoost\boostlink.pic.exe" /ld "C:\Program Files\SourceBoost\lib" libc.pic16.lib Main.obj Buttons.obj RGBLeds.obj /t PIC16F887 /d C:\svn\PIC_RGB_LED\Implementation\Src /p RGB_LED
Exit code was -2.
Removing target: RGB_LED.hex
Standard_Functions.h function redefinition: porta_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: portb_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: portc_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: portd_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: porte_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: porta_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: portb_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: portc_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: portd_flush(void) in Standard_Functions.h
Standard_Functions.h function redefinition: porte_flush(void) in Standard_Functions.h
Failed to locate output file 'C:\svn\PIC_RGB_LED\Implementation\Src\RGB_LED.hex'
Done

Failed

Baga

##### Share on other sites
Ok, I tried to compile my project in SourceBoost IDE, but I get the error I had before about redefining functions. This is the output. Does it have anything todo with the fact I'm using multiple (sub)folders?

No it doesn't. Linker complains while processing main.obj. It will complain though when it gets to obj files that are in different directories. That happens because of the bug in IDE toolsuite that doesn't process obj files from different than project directory correctly (this problem has been fixed and update will be available really soon). The error you see seems to be related to functions that have more than one body.

(BTW. The PP is invoked automatically in SourceBoost IDE, right?)

No. PP is invoked by compiler.

Regards,

Pavel

##### Share on other sites
No it doesn't. Linker complains while processing main.obj. It will complain though when it gets to obj files that are in different directories. That happens because of the bug in IDE toolsuite that doesn't process obj files from different than project directory correctly (this problem has been fixed and update will be available really soon). The error you see seems to be related to functions that have more than one body.

OK, but the o.bj files are compiled to the project directory, so i shouldn't be a problem.

No. PP is invoked by compiler.

But does that means I have to compile *.c files or the *.pp files? When compiling the *.c files I get the error about redefining functions. So it didn't get notice about the #ifndef in Standard_Functions.h.

When compiling the *.pp files I get the error: Couldn't find function/label by name:main

Baga

##### Share on other sites
No it doesn't. Linker complains while processing main.obj. It will complain though when it gets to obj files that are in different directories. That happens because of the bug in IDE toolsuite that doesn't process obj files from different than project directory correctly (this problem has been fixed and update will be available really soon). The error you see seems to be related to functions that have more than one body.

OK, but the o.bj files are compiled to the project directory, so i shouldn't be a problem.

If all obj files are in the project directory than linker will find them.

No. PP is invoked by compiler.

But does that means I have to compile *.c files or the *.pp files? When compiling the *.c files I get the error about redefining functions. So it didn't get notice about the #ifndef in Standard_Functions.h.

When compiling the *.pp files I get the error: Couldn't find function/label by name:main

Baga

You compile C files. Preprocessing is done behind the scenes by compiler.

The rule about functions is your declare the in header (H) files and define (add body) in just one of source © files. Exceptions to this rule are inline functions and function templates.

Regards,

Pavel

##### Share on other sites

Pavel,

Thanks for helping me out!

I was unaware of the fact function bodies can't be in header files. Some compilers do support that.

I've got it all figured out now.

Baga

##### Share on other sites
..I was unaware of the fact function bodies can't be in header files. Some compilers do support that...

This is not a compiler but language feature. None of the C compilers will support this. If function body is in a header than this header is used only with one source file or this is an inline function or a function template.

Regards,

Pavel

##### Share on other sites
This is not a compiler but language feature. None of the C compilers will support this. If function body is in a header than this header is used only with one source file or this is an inline function or a function template.

Oh, my bad. I didn't know that. I might indeed be mixing up features of different languages

This is why we keep learning every day.

Thanks for your time and explanation!

Baga

##### Share on other sites

I had a hard time getting Eclipse to work with larger projects. I tend to write all my code on a USB key on a bunch of different computers. When I finally get to my PC to compile it, Eclipse yells at me.

I found an easier time just creating a Makefile. Even if you don't use this approach, it might help you to understand the steps to take.

This is the Makefile I use. A few notes first:

1 - This is for a Linux system.

2 - The "make install" directive is to burn the hex file to the chip using the PicKit2. I installed the PicKit2 software from Microchip (there's a Linux version) to /opt.

3 - I invoke the compiler and linker through wine.

4 - This project uses NOVO.

5 - I tried to keep the macros as standard as possible.

6 - The header macros are mostly for header files that include other header files. It's so I only have to change one spot in the Makefile for a modification to each source file.

# Project specific setup
# Note: Use "pic16" for pic12 devices
CORE = pic18
TARGET = PIC18F4553
PROJNAME = apartment_cpu
# NOVO requires -swcs
LFLAGS += -swcs

OBJECTS = apartment_cpu.obj setup.obj i2c_interface.obj novosys.obj \
pc_interface.obj temperature_sensor.obj status_led.obj \
heart.obj structures.obj nv_database.obj interrupt.obj

STRUCTURES = structures.h
SETUP = setup.h
I2C_INTERFACE = i2c_interface.h $(STRUCTURES) NOVO = novocfg_apartment_cpu.h NOVOPROJ =$(NOVO) novoenum_apartment_cpu.h
PC_INTERFACE = pc_interface.h $(STRUCTURES) TEMPSENSOR = temperature_sensor.h STATUS_LED = status_led.h HEART = heart.h$(STRUCTURES)
SENDPACKET = sendpacket.h $(I2C_INTERFACE)$(NOVOPROJ) $(STRUCTURES)$(PC_INTERFACE)
NV_DATABASE = nv_database.h
INTERRUPT_H = interrupt.h

# BoostC stuff
BOOSTDIR = ~/.wine/drive_c/Program\ Files/SourceBoost
CC = $(BOOSTDIR)/boostc.$(CORE).exe
LD = $(BOOSTDIR)/boostlink.pic.exe INCDIR =$(BOOSTDIR)/include
LIBDIR = $(BOOSTDIR)/Lib NOVODIR =$(BOOSTDIR)/novo
LFLAGS += -ld $(LIBDIR) LIBS = libc.$(CORE).lib

# PICkit2 stuff
PK2DIR = /opt/pk2cmdv1-20Linux2-6
PK2CMD = $(PK2DIR)/pk2cmd -B$(PK2DIR) -P$(TARGET) -F$(PWD)/$(PROJNAME).hex PKFLAGPROG = -M PKFLAGVERIFY = -Y PKFLAGEXTPOW = -W all:$(PROJNAME).hex

apartment_cpu.obj: apartment_cpu.c $(SETUP)$(I2C_INTERFACE) $(NOVOPROJ) \$(STATUS_LED) $(HEART)$(INTERRUPT_H)
$(CC) -t$(TARGET) -I $(INCDIR) apartment_cpu.c interrupt.obj: interrupt.c$(INTERRUPT_H) $(NOVOPROJ)$(SETUP) $(PC_INTERFACE)$(CC) -t $(TARGET) -I$(INCDIR) interrupt.c

temperature_sensor.obj: temperature_sensor.c $(TEMPSENSOR)$(NOVOPROJ)
$(CC) -t$(TARGET) -I $(INCDIR) temperature_sensor.c nv_database.obj: nv_database.c$(NV_DATABASE) $(NOVOPROJ)$(CC) -t $(TARGET) -I$(INCDIR) nv_database.c

setup.obj: setup.c $(SETUP)$(CC) -t $(TARGET) -I$(INCDIR) setup.c

pc_interface.obj: pc_interface.c $(PC_INTERFACE)$(STRUCTURES) \
$(I2C_INTERFACE)$(HEART)
$(CC) -t$(TARGET) -I $(INCDIR) pc_interface.c i2c_interface.obj:$(I2C_INTERFACE) i2c_interface.c $(STRUCTURES)$(NOVOPROJ)
$(CC) -t$(TARGET) -I $(INCDIR) i2c_interface.c status_led.obj: status_led.c$(STATUS_LED) $(NOVOPROJ)$(CC) -t $(TARGET) -I$(INCDIR) status_led.c

heart.obj: heart.c $(HEART)$(NOVOPROJ) $(STRUCTURES)$(STATUS_LED) \
$(SENDPACKET)$(NV_DATABASE)
$(CC) -t$(TARGET) -I $(INCDIR) heart.c structures.obj: structures.c$(STRUCTURES)
$(CC) -t$(TARGET) -I $(INCDIR) structures.c novosys.obj:$(NOVO) novosys.c
$(CC) -t$(TARGET) -I $(INCDIR) -I$(NOVODIR) novosys.c

$(PROJNAME).hex:$(OBJECTS)
$(LD) -t$(TARGET) $(LFLAGS)$(LIBS) -p $(PROJNAME)$(OBJECTS)

clean:
\rm -f $(OBJECTS) \rm -f *~ \rm -f$(PROJNAME).asm
\rm -f $(PROJNAME).casm \rm -f$(PROJNAME).cof
\rm -f $(PROJNAME).hex \rm -f$(PROJNAME).lst
\rm -f $(PROJNAME).stat \rm -f$(PROJNAME).tree

install: $(PROJNAME).hex$(PK2CMD) $(PKFLAGPROG)$(PKFLAGVERIFY)

install_extpow: $(PROJNAME).hex$(PK2CMD) $(PKFLAGPROG)$(PKFLAGVERIFY) $(PKFLAGEXTPOW) - Bill #### Share this post ##### Link to post ##### Share on other sites Bill, Thanks for your reaction. It wasn't clear from my previous post(s), but I'm actually using GNU Make for building my project. I only had a hard time adding the compile$(CC) and link \$(LD) commands. Which was basically caused by wrong code in a header file.

Thanks for your input anyway, I'm sure other users find this to be usefull and it sure gives me some ideas to improve my makefiles!

Baga

## Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.