Go Down

Topic: Does the IDE include c files? (Read 13076 times) previous topic - next topic

jimLee

I'm compiling a bunch of code and there are some .c files in the bunch. Everything compiles, but the linker doesn't seem to be bringing in the code from the .c files. Is there something I need to do to make .c code link in?

I see where others use .c files so it must be doable.

thanks!

-jim lee
PNW Ardiuno & Maker club
1012 9Th Street, Anacortes, WA 98221 (Around the back of building)
GITHUB -> https://github.com/leftCoast

Coding Badly

#1
Apr 20, 2017, 07:45 am Last Edit: Apr 20, 2017, 07:45 am by Coding Badly

extern "C" / C++ name mangling.



jimLee

Wait, how do I do that for an entire file?

-jim lee
PNW Ardiuno & Maker club
1012 9Th Street, Anacortes, WA 98221 (Around the back of building)
GITHUB -> https://github.com/leftCoast

westfw

#3
Apr 20, 2017, 08:15 am Last Edit: Apr 20, 2017, 08:16 am by westfw
You don't need to do it for the entire file; you need to do it in the .h file that defines the APIs for that .c file.

Just put

Code: [Select]
#ifdef __cplusplus
extern "C" {
#endif

At the beginning of the .h file describing the API, and


Code: [Select]
#ifdef __cplusplus
} // extern "C"
#endif

at the end of the file.


Also, make sure none of your .c files overlap the same names as your .ino or .cpp files.
Having a "myprogram.ino" and "myprogram.c" is a bad idea.

jimLee

#4
Apr 20, 2017, 08:47 am Last Edit: Apr 20, 2017, 08:48 am by jimLee
That does't seem to be the issue.

I see other libraries use these from .cpp file without issue. The only thing I see them doing is..

Code: [Select]
extern "C" {
  #include "bsp/include/nm_bsp.h"
  #include "bsp/include/nm_bsp_arduino.h"
  #include "driver/source/nmasic.h"
  #include "driver/include/m2m_periph.h"
  #include "driver/include/m2m_wifi.h"
  #include "driver/include/m2m_ssl.h"
}


in the .cpp & .h files

I think doing the same thing, but I must be missing something.

Error log.

Code: [Select]
LC_WiFi_Example:13: warning: deprecated conversion from string constant to 'char*'
/var/folders/v_/nvnwrxts2c52kkh49p5666y80000gn/T/arduino_build_518336/libraries/LC_WiFi/WiFiObj.cpp.o: In function `WiFiObj::WiFiObj(int, int, int)':
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:47: undefined reference to `gi8Winc1501CsPin'
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:47: undefined reference to `gi8Winc1501IntnPin'
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:47: undefined reference to `gi8Winc1501ResetPin'
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:47: undefined reference to `gi8Winc1501ChipEnPin'
/var/folders/v_/nvnwrxts2c52kkh49p5666y80000gn/T/arduino_build_518336/libraries/LC_WiFi/WiFiObj.cpp.o: In function `WiFiObj::init()':
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:103: undefined reference to `nm_bsp_init'
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:106: undefined reference to `m2m_wifi_init'
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:109: undefined reference to `m2m_ssl_set_active_ciphersuites'
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:123: undefined reference to `nmdrv_firm_ver'
/var/folders/v_/nvnwrxts2c52kkh49p5666y80000gn/T/arduino_build_518336/libraries/LC_WiFi/WiFiObj.cpp.o: In function `WiFiObj::handleProvisionInfo(void*)':
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:163: undefined reference to `m2m_wifi_connect'
/var/folders/v_/nvnwrxts2c52kkh49p5666y80000gn/T/arduino_build_518336/libraries/LC_WiFi/WiFiObj.cpp.o: In function `WiFiObj::begin(char*, char*)':
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:70: undefined reference to `m2m_wifi_connect'
/Users/jimlee/Documents/Arduino/libraries/LC_WiFi/WiFiObj.cpp:76: undefined reference to `m2m_wifi_handle_events'
collect2: error: ld returned 1 exit status
Error compiling for board Teensy 3.2 / 3.1.


Compiles fine, won't link.

P.S. I did try adding the #ifdef __cplusplus stuff and saw no change.

-jim lee
PNW Ardiuno & Maker club
1012 9Th Street, Anacortes, WA 98221 (Around the back of building)
GITHUB -> https://github.com/leftCoast

Coding Badly


All files placed in a sketch directory...

test.h
Code: [Select]

#ifndef __TEST_H__
#define __TEST_H__

#ifdef __cplusplus
extern "C" {
#endif

int dummy( void );

#ifdef __cplusplus
} // extern "C"
#endif

#endif


test.c
Code: [Select]

#include "test.h"

int dummy( void )
{
  static int rv;
  return ++rv;
}


whatever.ino
Code: [Select]

#include "test.h"

void setup()
{
  Serial.begin( 250000 );
}

void loop()
{
  Serial.println( dummy() );
}



Success...

Sketch uses 1724 bytes (5%) of program storage space. Maximum is 32256 bytes.
Global variables use 188 bytes (9%) of dynamic memory, leaving 1860 bytes for local variables. Maximum is 2048 bytes.


Coding Badly


What is the name of the file that contains gi8Winc1501CsPin?

What is the name of the file that contains nm_bsp_init?


jimLee

#7
Apr 20, 2017, 09:46 am Last Edit: Apr 20, 2017, 09:55 am by jimLee
nm_bsp_init() is in nm_bsp_arduino.c

I tried this..

In my .cpp file..
Code: [Select]


extern "C" {
  #include "bsp/include/nm_bsp.h"
  #include "bsp/include/nm_bsp_arduino.h"
  #include "driver/source/nmasic.h"
  #include "driver/include/m2m_periph.h"
  #include "driver/include/m2m_wifi.h"
  #include "driver/include/m2m_ssl.h"
}

extern "C" {
int8_t gi8Winc1501CsPin;
int8_t gi8Winc1501ResetPin;
int8_t gi8Winc1501IntnPin;
int8_t gi8Winc1501ChipEnPin;
int8_t nm_get_firmware_info(tstrM2mRev* M2mRev);
int8_t m2m_wifi_connect(char *pcSsid, uint8 u8SsidLen, uint8 u8SecType, void *pvAuthInfo, uint16 u16Ch);
sint8 nm_bsp_init(void);
}


The extern C for the .h files was how the file I was looking at seemed to accomplish this. Its been in my file since the beginning. I added the second block and that seems to have fixed the trouble with the variables but not the functions.

The files are from WiFi101. I'm rewriting the Wifi class from scratch so I can understand it better. Then I can add a normal Berkley sockets interface to it. Hopefully one I can make work.

-jim lee
PNW Ardiuno & Maker club
1012 9Th Street, Anacortes, WA 98221 (Around the back of building)
GITHUB -> https://github.com/leftCoast

Coding Badly

I tried this..
Works for me...

test.h
Code: [Select]

#ifndef __TEST_H__
#define __TEST_H__

/*
#ifdef __cplusplus
extern "C" {
#endif
*/

int dummy( void );

/*
#ifdef __cplusplus
} // extern "C"
#endif
*/

#endif



test.c
Code: [Select]

#include "test.h"

int dummy( void )
{
  static int rv;
  return ++rv;
}



.ino
Code: [Select]

extern "C" {
#include "test.h"
}

void setup()
{
  Serial.begin( 250000 );
}

void loop()
{
  Serial.println( dummy() );
}

Coding Badly

nm_bsp_init() is in nm_bsp_arduino.c
Where is that file in your directory structure?

Put an obvious syntax error in that file then try to build.  Do you get an error?


jimLee

#10
Apr 20, 2017, 06:44 pm Last Edit: Apr 20, 2017, 06:45 pm by jimLee
Good idea. I'll try that.

All the c files are in sub folders of the one I'm working on.

-jim lee
PNW Ardiuno & Maker club
1012 9Th Street, Anacortes, WA 98221 (Around the back of building)
GITHUB -> https://github.com/leftCoast

sterretje

#11
Apr 20, 2017, 07:15 pm Last Edit: Apr 20, 2017, 07:19 pm by sterretje
All the c files are in sub folders of the one I'm working on.
I think that does not work. Try to create a src directory in the sketch directory.  Under that src directory you can create library directories in which you can place  h and c files.
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

jimLee

Wait, I mean..

What I'm working on is a library. There is a .cpp & .h I'm writing and a bunch of source folders along side of it. The sketch is by itself in a sketch folder.

Now I notice the library I started from has all this code & folders in a src folder. Could that possibly change anything? WTH, Ill try it.

Oh! I also found the #ifdef c++ { in
-jim lee
PNW Ardiuno & Maker club
1012 9Th Street, Anacortes, WA 98221 (Around the back of building)
GITHUB -> https://github.com/leftCoast

Jiggy-Ninja

Zip up your library and post it so we see what you're doing. I'm not going to play 20 questions to figure out your directory structure and header arrangement, and I'm surprised that this thread has gone through a dozen replies with none of your code posted.
Hackaday: https://hackaday.io/MarkRD
Advanced C++ Techniques: https://forum.arduino.cc/index.php?topic=493075.0

jimLee

#14
Apr 20, 2017, 09:46 pm Last Edit: Apr 20, 2017, 09:49 pm by jimLee
Calm down jiggly! I Got it!

This was the ticket..

My lib folder was "LC_WiFi" Now, typically I just dump .ccp & .h files in library folders and everything just works. This time I had to follow someone else's crazy format. So I dumped all their source files into my folder and added my stuff along side of them. This seems t work fine as long as everything is .cpp or .h files. It seems that it just ignores the .c files.

Now sterretje made the suggestion that use a src folder inside my library folder. I noticed that this is how they did it. With everything in the source folder. I tried i with my stuff outside the folder and that was a hot mess. So copying their format I put all the source on the src folder. Then it couldn't even find my include in the .ino file.

What to do? Look for differences. I notice that my LC_WiFi folder was NOT showing up on the library list so there is something odd going on. I notice the library.properties file, open it and edit it to match what I'm writing. Presto! Everything works!

So what I gather is.. Setting up a folder and dumping .cpp & .h files in it to create a library works fine. But once it gets subfolders & .c files, you need the scr folder with the matching library.properties file for it to work.

Thanks for the help everyone!

-jim lee
PNW Ardiuno & Maker club
1012 9Th Street, Anacortes, WA 98221 (Around the back of building)
GITHUB -> https://github.com/leftCoast

Go Up