Undefined Reference to .s file

I have a function called message_send It is defined in a file called message_send1.s. I also have a file called message_send1.h as well.
In my Arduino code, I include two files. one is the message_send1.h file, and the other is called kilolib.h file, which references the file message_send1.h.
Here is the code that is giving me the error:

#include <kilolib.h>
#include <message_send1.h>
int led = 9;
message_t msg;

void setup() {
msg.crc = message_crc(&msg);
}

void loop() {
message_send(&msg);
}

When I run this code, I keep getting this error:

C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/kilolib.cpp:511: undefined reference to message_send(message_t const*)' sketch_oct20b.cpp.o: In function loop’:
C:\Program Files (x86)\Arduino/sketch_oct20b.ino:22: undefined reference to `message_send(message_t const*)’


It says that message_send is undefined, but the function is defined in both the .s and .h files. Does anyone know what is causing this error?

Which IDE version? I don't think that the 1.0.x versions support assembler (.s) files; 1.5.x might, although I think the chances are better with a capital S (foo.S)

Why not write/define the function in C++? And, if you have, change the file extension to .cpp instead of .s

Here is my code:

//#include <Arduino.h>
//#include <stdint.h>
#include <bitfield.h>
#include <bootldr.h>
#include <debug.h>
#include <kilolib.h>
#include <macros.h>
#include <message.h>
#include <message_buffered.h>
#include <message_crc.h>
#include <message_send1.h>
#include <ohc.h>
#include <ringbuffer.h>

int led = 9;
message_t msg;

void setup() {
msg.crc = message_crc(&msg);
}

void loop() {
message_send(&msg);
}

When I run it as is (with the first two libraries commented out), I get this error:

In file included from sketch_oct21a.ino:4:0:
C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/bootldr.h:4:5: error: ‘uint8_t’ does not name a type
uint8_t page_address;
^
C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/bootldr.h:5:5: error: ‘uint8_t’ does not name a type
uint8_t page_offset;
^
C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/bootldr.h:6:5: error: ‘uint16_t’ does not name a type
uint16_t word1;
^
C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/bootldr.h:7:5: error: ‘uint16_t’ does not name a type
uint16_t word2;
^
C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/bootldr.h:8:5: error: ‘uint16_t’ does not name a type
uint16_t word3;
^
C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/bootldr.h:9:5: error: ‘uint8_t’ does not name a type
uint8_t unused;
^
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:24:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:223,
from sketch_oct21a.ino:17:
/Arduino/hardware/tools/avr/avr/include/stdio.h:649:8: error: declaration does not declare anything [-fpermissive]
extern int printf(const char *__fmt, …);
^
Error compiling.

When I uncomment the first library (as in, I include Arduino.h) I get the following error:

sketch_oct21a.cpp.o: In function loop': /Arduino/sketch_oct21a.ino:25: undefined reference to message_send(message_t const*)’
kilolib-master_all1\kilolib.cpp.o: In function __vector_14': C:\Users\preethv\Documents\Arduino\libraries\kilolib-master_all1/kilolib.cpp:489: undefined reference to message_send(message_t const*)’
collect2: error: ld returned 1 exit status
Error compiling.

And finally, when I uncomment the second library (as in, I include stdint.h) I get the following error:

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h:24:0,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,
from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:223,
from sketch_oct21a.ino:17:
C:\Users\preethv\Documents\Arduino\libraries\include/stdio.h:649:8: error: declaration does not declare anything [-fpermissive]
extern int printf(const char *__fmt, …);
^
Error compiling.

I just want to get my code to compile, so if anyone knows how to fix any of these or get me started on a particular path, that would be appreciated!!

It is actually a capitalized .S file (not a .s file as I originally said). Here is a thread with more specific errors that I've been having:

http://forum.arduino.cc/index.php?topic=273872.new#new

When I run it as is (with the first two libraries commented out), I get this error:

Well, clearly you should not be commenting out the include of Arduino.h.

When I uncomment the first library (as in, I include Arduino.h) I get the following error:

That's not a compiler error. That's a linker error. It's telling you that message_send() was not found in any object file the compiler created. Why do you think that it is?

message_send() is included in a .S file, which I am guessing arduino is not able to access. Do you know how to fix this?

message_send() is included in a .S file, which I am guessing arduino is not able to access. Do you know how to fix this?

Since you STILL haven't shown the damned .S file, NO!

C++ allows for function overloading. But, since it's still C under the covers, and function names must be unique, the C++ compiler creates a unique name by a process called name mangling, where the actual function name is defined by the supplied function name and the types of all the arguments.

The C and assembler compilers do not perform name mangling, so YOU must take care to tell the linker that name mangling has not been performed on functions defined in C and S files.

It sounds like you have not done this.

I'm just curious as to why you would insist on using a .S file? From what it sounds like you're trying to do, C++ code would be easier to write and implement. Is there a specific reason you need to use Assembly code?

Is there a specific reason you need to use Assembly code?

I'm guessing it's because OP didn't write the code.

He's going to have to check the library code for a correct definition of

extern "C" {
    message_send(message_t const*);
}

or similar, then. I don't think the Arduino compiler will do that for him.

I don't think the Arduino compiler will do that for him.

It won't. It's why we (repeatedly) ask people to post their code - so we can see whether they've done this, or not.

I can't even visualize what files you have. Please zip up the entire project and attach that to your reply. What version of the IDE are you using? Please don't just post snippets. http://snippets-r-us.com/

My apologies, here is exactly what I am trying to do: I want my Arduino Nano Atmega 328 to communicate with kilobots (a collective robotics platform, all of the information about kilobots is on: www.kilobotics.com). A summary of how the kilobots work in terms of this project: an external controller uploads a program to the kilobots that tells them what to do. Several capabilities can be uploaded, including the ability to sense distances between one another via infrared transmissions. I want my Arduino to have that capability. I have successfully created this circuit (scroll down to "Build Your Own Controller" https://www.kilobotics.com/documentation). However, I do not want to upload the program that is listed on the site, which would just make the arduino able to upload programs to the kilobots. Rather, I want my arduino to essentially act like another kilobot. By this I mean that I want the arduino's IR lights to be able to send commands to the robots. In order to do this, I am playing around with the kilobot library (https://github.com/acornejo/kilolib). So far, all I have done is change the names of functions that have the same name in both the kilobot library and the arduino's built-in library. So, for example, wherever you see delay() in the kilobot source code, I canged it to delay1(). This successfully got rid of several of the errors I was having. However, I am still having the issue that the Arduino does not seem to be recognizing the .S file in the kilobot library (the github link above).

We would need your Arduino sketch to check how it's utilizing that library.

It is included in my original post

Ah, I didn't see that because of how many #include statements you have. Is there a reason you've included all of those? Shouldn't you only need kilolib.h?

I couldn’t reproduce your problem. Using IDE 1.0.6, after fixing a few things unrelated to the .S file it compiled:

Binary sketch size: 3,614 bytes (of a 32,256 byte maximum)

These are the changes I made:

diff --git a/blank.c b/blank.c
index 5221da5..f0d314b 100644
--- a/blank.c
+++ b/blank.c
@@ -1,3 +1,4 @@
+#if 0
 #include "kilolib.h"
 
 void setup() {
@@ -18,3 +19,4 @@ int main() {
 
     return 0;
 }
+#endif
diff --git a/bootldr.c b/bootldr.c
index 9f040b6..cd779d6 100644
--- a/bootldr.c
+++ b/bootldr.c
@@ -1,3 +1,5 @@
+#if 0
+
 #include "kilolib.h"
 #include "bitfield.h"
 #include "bootldr.h"
@@ -99,3 +101,6 @@ int main() {
 
     return 0;
 }
+
+#endif
+
diff --git a/bootldr.h b/bootldr.h
index 70124b8..a394e2a 100644
--- a/bootldr.h
+++ b/bootldr.h
@@ -1,3 +1,5 @@
+#include <Arduino.h>
+
 /** @internal */
 
 typedef struct {
diff --git a/kilolib.h b/kilolib.h
index bbaf72c..f68b7b4 100644
--- a/kilolib.h
+++ b/kilolib.h
@@ -297,7 +297,7 @@ uint8_t estimate_distance(const distance_measurement_t *d);
  * use timers to create delays.
  * @see kilo_ticks
  */
-void delay(uint16_t ms);
+void delay1(uint16_t ms);
 
 /**
  * @brief Hardware random number generator.

Plus in the test sketch:

void loop() {  
  //message_send(&msg);
  }

How did you install this kilolib library? Please describe in detail including path names.

We would need your Arduino sketch

Not really. For testing purposes, I took an existing library (onewire, as it happens) and created a new and empty (except for a comment) "qOneWire.S" file in ~/Documents/Arduino/libraries/OneWire/qOneWire.S Then I compiled one of the onewire examples, with "verbose" compilation messages turned on. The expected behavior is that if the IDE recognizes the .S file, it should generate a compile command for it that appears in the log (and then it should link in the empty .o file as part of the link command as well.) If it doesn't recognize the .S file, it will just compile the other library files.

Sure enough, 1.5.7 compiles the .S file, but 1.0.5 doesn't.

So - upgrade your IDE to 1.5.8 (current latest version), make sure the .S file is in with the rest of the libraries, make sure the .h definitions for the .S functions are "extern "C"", and you should make additional progress.