error linking separate modules

Hi, All:

I’m trying to understand how to use the linker in the case that a project is divided up into many separate modules.

Here is a very simple example of a useless Arduino program (excerpted from a much larger project) that fails to link properly. Comparing to what others have done that does link properly, I don’t see what I’m doing incorrectly. I’m using Arduino 1.6.11. All advice appreciated!

Code is in three files, all in a folder titled “power”

Arduino power.ino

#include "power.h"

int LED_PIN = 13;

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);
}


void loop()
{
  power_save();
}

power.c

#include <avr/power.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

#include "power.h"

void disable_bod_and_sleep()
{
  /* This will turn off brown-out detection while
   * sleeping. Unfortunately this won't work in IDLE mode.
   * Relevant info about BOD disabling: datasheet p.44
   *
   * Procedure to disable the BOD:
   *
   * 1. BODSE and BODS must be set to 1
   * 2. Turn BODSE to 0
   * 3. BODS will automatically turn 0 after 4 cycles
   *
   * The catch is that we *must* go to sleep between 2
   * and 3, ie. just before BODS turns 0.
   */
  unsigned char mcucr;

  cli();
  mcucr = MCUCR | (_BV(BODS) | _BV(BODSE));
  MCUCR = mcucr;
  MCUCR = mcucr & (~_BV(BODSE));
  sei();
  sleep_mode();    // Go to sleep
}

void power_save()
{
  /* Enter power saving mode. SLEEP_MODE_IDLE is the least saving
   * mode, but it's the only one that will keep the UART running.
   * In addition, we need timer0 to keep track of time, timer 1
   * to drive the buzzer and timer2 to keep pwm output at its rest
   * voltage.
   */

  set_sleep_mode(SLEEP_MODE_IDLE);
  sleep_enable();
  power_adc_disable();
  power_spi_disable();
  power_twi_disable();

  sleep_mode();    // Go to sleep

  sleep_disable();  // Resume after wake up
  power_all_enable();
}

power.h

#ifndef __POWER_H__
#define __POWER_H__
//exported functions
void disable_bod_and_sleep();
void power_save();

#endif // ifndef __POWER_H__

Error message is

Arduino: 1.6.11 (Windows 7), Board: "Arduino/Genuino Uno"

... (compiler messages, all modules compile without error)

Linking everything together...
"C:\Program Files\Arduino\hardware\tools\avr/bin/avr-gcc" -w -Os -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p  -o "C:\Users\Justme\AppData\Local\Temp\buildf7114074d33be4576434a6d3719e2b8c.tmp/power.ino.elf" "C:\Users\Justme\AppData\Local\Temp\buildf7114074d33be4576434a6d3719e2b8c.tmp\sketch\power.c.o" "C:\Users\Justme\AppData\Local\Temp\buildf7114074d33be4576434a6d3719e2b8c.tmp\sketch\power.ino.cpp.o" "C:\Users\Justme\AppData\Local\Temp\buildf7114074d33be4576434a6d3719e2b8c.tmp/core\core.a" "-LC:\Users\Justme\AppData\Local\Temp\buildf7114074d33be4576434a6d3719e2b8c.tmp" -lm
C:\Users\Justme\AppData\Local\Temp\ccqqXGZQ.ltrans0.ltrans.o: In function `main':

ccqqXGZQ.ltrans0.o:(.text.startup+0x144): undefined reference to `power_save()'

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Arduino/Genuino Uno.

power.c is compiled by the C compiler. The C compiler does NOT produce code that the C++ linker can use, since the C++ linker expects the C++ compiler to have performed name mangling.

Either rename to power.cpp or use the extern "C" {} wrappers to make the C compiler produce output that the C++ linker can use.

So simple! Thanks!!