[solved] Undefined Reference error (linker error) when compiling from web IDE

Hi Everybody,

I have run into a linker issue while compiling my software on the web IDE. Essentially the problem is this:

I have my library.cpp and library.h along with 20-30 other files (with directory structure flattened). library.cpp uses functions from another file library-helper.h, therefore library.h has an #include “library-helper.h”. Now, when I compile this locally with the “firmware”, using “make PLATFORM=Photon” everything works fine, I get a .bin and it runs ok. However, when I do this on the webIDE. I get:

…/…/…/build/target/user/platform-6/libuser.a(library.o): In function XXXXXXX(unsigned char*)': XXX/XXXX.cpp:342: undefined reference toXXXX-function’

Any help appreciated!

Cheers!

Hi @jersey99

Have you tried converting to

#include library-helper/library-helper.h

Includes are a bit inconsistent right now between all the compile strategies, since the web IDE puts the include libraries into a temporary directory.

Do you mean: In my library.h, I should say

#include "library/library-helper.h"

?

If you have your own .H/.CPP files you’d stick with the #include "yourLib.h" way, but if you import a library from the Web IDE library repository it’s #include "libraryName/libraryName.h"

But one (or two) stupid question:
You do have a line #include "library.h" in your library.cpp file and your main project file (or any other header that includes the header)?
And you do have an #include "application.h" in all your headers too?

1 Like

For each automatically included library (i.e. you clicked on the library icon and say “yes, add to sketch”) you get a separate directory with the name of library. For each new click of the circle-plus to add a .h and a .cpp file, you get a file in the directory with your current sketch.

[Ah, I see @ScruffR beat me to it again!]

One other quick point–if you have libraries that are interdependent and a library header file needs to include another library header file, you should protect the header files from being loaded twice. There are two ways to do this commonly, with #ifndef and a #define or with a pragma once.

1 Like

Firstly, thanks for your help! I don’t have 2 libraries to include. Just one library that I have implemented with a ton of .c and .h files. (mind you .c).

In application.cpp

#include "library/library.h"

In library.h

#include "application.h"
#include "library-helper1.h"

in library.cpp

#include "library.h"

All this works and builds correctly locally. Just not on the web-IDE. Let me know if you need the specifics of the library etc.

Just a stab in the dark, try to not name your main project file application.cpp (in Web IDE).

And now something that should most definetly be changed :wink:
As said, if you have your library.h as a seperate file tab in Web IDE, you should use #include "library.h", since it resides in your application folder and not in a subfolder.
Next, when you added your .C files (by use of the (+) button) you should have got .CPP files - don’t change the extension.

And as @bko pointed out, wrap your header files into something like this

#ifndef _MY_LIBRARY_H_
#define _MY_LIBRARY_H_
...
// all your header contents
...
#endif

You’ll have multiple places that use #include "myLibrary.h" but you don’t want them to be included each time anew.

1 Like

:frowning: There seems to be a lot of confusion talking in the abstract space. Have a look here: This is the library I am developing:

Everything is in the firmware directory obviously. And it builds and runs fine locally, I can program the device etc. Now, when I try to do the same on the web, by running one of the examples there, I get a linking error.

../../../build/target/user/platform-6/libuser.a(httpsclient-particle.o): In function `httpWriteRequest':
httpsclient-particle/httpsclient-particle.cpp:165: undefined reference to `matrixSslGetWritebuf'

Wow, this is some library!
I’ll like to see it published on Particle Build, but it’ll take some more investigating why it doesn’t build.

But maybe @suda might have some clue about possible interna of the Web IDE that might play a role here.

1 Like

I've played arround with your library a bit.
First I did what I suggested to you earlier

So I renamed all the .C files into .CPP which lead to more elaborate error messages in Web IDE.

Once I had these error messages, I found several issues with the stricter compiler settings on the Web IDE which complained a lot about psMalloc()/psRealloc() returning void* which is unsafe to convert into typed pointers of several different sorts.

And the id enum not being found.
It's declared in x509.h

typedef struct psGeneralNameEntry {
	psPool_t						*pool;
	enum {
		GN_OTHER = 0,	// OtherName
		GN_EMAIL,		// IA5String
		GN_DNS,			// IA5String
		GN_X400,		// ORAddress
		GN_DIR,			// Name
		GN_EDI,			// EDIPartyName
		GN_URI,			// IA5String
		GN_IP,			// OCTET STRING
		GN_REGID		// OBJECT IDENTIFIER
	}								id;
	unsigned char					name[16];
	unsigned char					oid[32]; /* SubjectAltName OtherName */
	uint32							oidLen;
	unsigned char					*data;
	uint32							dataLen;
	struct psGeneralNameEntry		*next;
} x509GeneralName_t;

So if you could maybe "correct" these two main things (type safe assignments and private enum), you might get a bit further.


BTW: After having a look at this work of art I feel a bit stupid having given some of the advise above :blush:.
I didn't realize what caliber programmer you are :scream: :+1:

2 Likes

@ScruffR

Thanks for the nice words, but really, MatrixSSL does all of the heavy-lifting. It’s been around for a while I guess. Mine, was mostly a way to try to fit it in here. Let’s see what comes out of it.

Just for your amusement:
http://everythingisaremix.info/watch-the-series/

1 Like

If you are using .c code in your sources, then be sure that any header files are wrapped with

#ifdef __cplusplus
extern "C" {
#endif

#include "someheader.h"

#ifdef __cplusplus
}
#endif

Otherwise the C++ compiler will be looking for mangled names when linking, which it won’t get when linking against C.

4 Likes

@mdma

Thanks for your suggestion. I feel like we are along the right path, and a little bit of push here will help me get over this hump of getting it to work on the web IDE. Let me explain what I see:

If you have a look here:

#include "matrixsslApi.h"

is a line I have in there. This is essentially a C library, the file matrixsslApi.h is packaged with the extern “C” in itself.

Now the first of the many linking errors I get (only on the webIDE) is:

../../../build/target/user/platform-6/libuser.a(httpsclient-particle.o): In function `httpWriteRequest':
httpsclient-particle/httpsclient-particle.cpp:148: undefined reference to `matrixSslGetWritebuf'

matrixSslGetWriteBuf is declared in matrixsslApi.h which is wrapped in extern “C”, shouldn’t this be available at link? Unless matrixsslApi.h is not part of the gcc or g++ compile line?

Cheers!

Sorry to chime in here again, but as I’ve “learnt” from @BDub is that for some reason C files didn’t get pulled in by the Web IDE and for that reason there was nothing to link against.

1 Like

@ScruffR

I am guessing you mean don’t instead of didn’t?

If that is true, it is a very valuable piece of information!! What should be done about this? Is this intentional?

@mdma @BDub

Hmm! They didn't when I tried it and obviously also when Brett did try, and I haven't checked since - so it's a bit of both :blush:

But the feeling that this was the case back then was one of the reasons why I wrote this

and

Yep! We need to get @suda on the scene and see if he can resolve why the .c files are not being imported.

Yep, hence (9/24/2015)

Yes let’s follow through now :slight_smile:

1 Like

Hey @jersey99 the Build IDE is now importing .c files :slight_smile: so I have a PR submitted to you that I tested an import on. One example is compiling, the other has a few issues still which you should be able to solve now. So many files is making the IDE slow, so just give it a moment to load things if you know you clicked the button already :smile:

3 Likes