shared library missing bcm_host.h function mappings - c++

I'm attempting to write a wrapper library and compile it to a shared object in order to access various C functions in my C# application necessary to communicate with a piece of hardware. (following this tutorial initally https://www.olegtarasov.me/build-cross-platform-c-library/)
When I build the shared object, even though it compiles I run into a missing symbol issue with various functions related to "bcm_host.h". For other missing symbols I've been able to include the .c files where the functions are housed, but for bcm_host.h there aren't .c files storing the functions that I can find.
Reading online people solve seem to solve this issue by installing missing kernel headers (https://raspberrypi.stackexchange.com/questions/36121/fatal-error-bcm-host-h-no-such-file-or-directory-compilation-terminated)
However following these steps doesn't solve my issue. I've downloaded the library that holds the various files including bcm_host.h,
and included bcm_host.h which solves my issue with the compiling, but again, when any function is called that attempts to access these methods I hit a missing symbol error.
Is there an issue with the way that I'm linking headers? So far I've had to link .c files in order to have their functions properly map to address spaces once the library is built.
I'm sure I'm missing something quite obvious to someone who knows this area better than I do, any help would be greatly appreciated.

Related

How is linking failing: Undefined reference to library

I have inherited a code project that contains several individual libraries of code that compile separately and then are linked in the compiled tools. It's supposed to be a Chinese menu of what each tool wants. This all written on Linux, in C++, with Qt. There are several issues with the current design, but I'm learning to deal.
This latest issue has me really dumbfounded. The main library is the Utilities. It contains a handful of classes and it compiles into a .a library file. Another library is our DatabaseInterfaces. It has class files that refer to header files from Utilities (they are all shared) but the CPP files are not included in DatabaseInterfaces. DatabaseInterfaces also compiles into a .a library. Finally, we have a CMDPrompt tool that imports both the Utilities.a and DatabaseInterfaces.a libraries. CMDPrompt does not compile. Instead, I get several errors indicating that I have an undefined reference for one of the objects in Utilities.
After several different attempts to fix this, I finally directly included the CPP file in the CMDPrompt.pro. It worked or at least it is now finding new undefined references for other classes in Utilities. This confirms to me that somehow the projects are not linking correctly. I would have expected that because the Utilities library is linked in I would have gotten all of the H/CPP goodness with it. I suspect the problem is that the DatabaseInterfaces library is compiling against the H files only and needs the same Utilities.a library. I tried adding that LIB into the DatabaseInterfaces.pro, but it didn't have any effect.
I am not a C++ programmer by training and while I believe I understand the main points of the linking process, I am obviously missing something. Here are my questions. Given the relationship between the different libraries, how should the linker work? Why is the DatabaseInterfaces.a compiling at all with just the H files? What is the best way to resolve this issue?
You need to link the libraries in the right order - it sounds like Utilities.a needs to be linked last. I don't know how you do that in Qt but that's what you need to achieve.

undefined symbol when loading shared library

I'm sorry about the vagueness of this post, but I'm not able to share the code, and anyway, it would be too much to share anyway.
I have this shared library, "shared", which is loaded by another library. The problem is that when loading the shared library, I get the error message saying "undefined symbol: _ZplPKcRK18ExampleClass"
The problem I have is that ExampleClass is declared and defined in the shared library. I made sure that I the ExampleClass is properly defined, and that the .h and .cpp are actually getting compiled.
I'm really confused about this, so any insight would be really helpful.
I'm building using cmake 3.6.2 and gcc 4.8.5 on CentOS 7.
This is a problem that usually occurs when loading in a shared library and then trying to code from that library. Since linking of the library did not happen directly after compile time, you will not get any linker errors that would be associated with the file and what is dynamically loading it. Look into a demangler(c++filt) and try to get more information about what that "_ZplPKcRK18ExampleClass" references.
In my experience, it is usually something along the lines of a method signature mismatch and the code does not know where to branch after the library is loaded.

Can't compile glew when using it via my own library : CodeLite

I have edited out a lot of my original situation to try keep things simple; it can be seen in the revisions.
Basically I have been following a tutorial in which a game engine is being created.
Most of the code has been separated into its own CodeLite project and successfully compiled into a static library (libbengine.a using mingw32 via TDM-GCC-32).
(For the record, the code compiled fine before separation)
Back in the main game code (main.cpp, etc) the compiler knows the relevant include and lib directories and compilation can at least locate the necessary headers and lib.
However, I get this error: undefined reference to '__glewCreateProgram'
Any ideas as to what is getting lost in translation (so-to-speak)?
I have been reading around all over the place; researching compilation, static libraries, ar.exe, but am having no luck (I am still looking).
If you want any more pertinent information, I will happily provide it; for now I shan't clog up the post any further.
Cheers
To give a basic idea of the error in CodeLite:
Main project linker settings:
bengine project linker settings (compiled as static lib.a):
It seems the problem was solely with linking order. As can be seen in the second image in my question (Main linker setting) - "Bengine" should have been at the top of the list, not the bottom.
This may be mingw32 specific; I am not sure.
Well, after all those hours, I feel somewhat foolish...
At least I have learned some things along the way.

What am I doing when I compile a library like SFML?

I've been trying to get SFML 2.1 working on my linux mint 15 install on my laptop, and that's when I found I should compile it from the source. So after fumbling through the tutorial on compiling SFML using cmake, I'm finally able to get some code working. But now I'm curious...what did I just do?
When I think of compiling, I think of compiling c++ code into object files, and then linking the object files into an executable. But I don't really understand what it means to compile something like SFML. When I think of a library, I think of a bunch of functions and objects that are made available to me through header files and source files created by another programmer, not necessarily something that needs to be compiled. My knowledge on the compilation and linking process is rather limited, so that might be my biggest issue at this point.
So what does it mean to "compile" a library?
EDIT: After looking at this particular question: How does the compilation/linking process work?
I noticed two bits of info that may further refine my question.
Linking: the linker takes the object files produced by the compiler
and produces either a library or an executable file.
and
The linker is what produces the final compilation output from the
object files the compiler produced. This output can be either a shared
(or dynamic) library (and while the name is similar, they haven't got
much in common with static libraries mentioned earlier) or an
executable.
So perhaps my real question is what does it mean to compile a dynamic library? What am I accomplishing by doing this?

How can I link with (or work around) two third-party static libraries that define the same symbols?

I can't be the only one to run into this.
I have a C++ application that needs to link with one third-party and another static library set in an SDK. The SDK has, for some hideously frustrating reason, recompiled a subset of that same third-party library into their own (renamed) lib, although the symbols themselves are named the same and they are not encapsulated within a namespace. My application itself depends upon the same third-party library.
I've considered a few options, but maybe I'm missing something and hopefully a fresh look will help me out. Perhaps I'm close and someone will know the next step for one of these . I'll enumerate what I've tried and the shortcomings of each solution so far:
Link with both.
I get about 2500 lines of symbol redefinition / size change warnings and errors. This is when I first found that they defined the same symbols. I'm trying to recompile OpenSSL with g++ and drop it into a namespace at the moment...see edit below...
Link with the SDK only.
I get undefined symbols that my own code depends upon - this is when I found that their recompile of the third party lib is a subset, or at least was configured with one module disabled.
Link with the third party lib only.
I have a couple of undefined symbols reported by the SDK - one of them is actually a #define in a header file within the third party lib, so all references in the third party lib resolve to the definition, but references outside there do not. I moved that into the c file, which resolves that, however I still have two unresolved functions I can't find anywhere. This is the closest I've gotten so far.
Strip conflicting symbols from one lib and link in both.
So far this hasn't worked. It could be a version issue between the lib statically linked in the SDK and the versions I've tried using of the third-party lib, but it looks like some functions were moved between symbols, so by removing a symbol, I inadvertently remove a function that I need elsewhere. There doesn't seem to be a perfect mapping between functions in symbols in the SDK vs functions in symbols in the third-party lib. Is it plausible to strip functions without having to manually adjust addresses?
I've been examining symbols in libs with:
nm -C --defined-only lib<name>.a
And extracting entire objects with:
ar -x lib<name>.a <objname>.o
Hopefully this will also help others who have had to link with third-party libs that conflict with one another. For the sake of specifics, the third-party lib is OpenSSL, and the SDK is Opsec - libcpopenssl.a is the offending lib in Opsec.
**EDIT- A late entry possible workaround may be to recompile OpenSSL with g++ and put the whole thing in a namespace, and then link both libs. I'm trying that now...more to come...
A Google search indicate that SSL_get_peer_dh and DH_dup are really additions from libcpopenssl.a, and they don't exist in my copy of OpenSSL either. So you'll really have to link that library in. Mixing both libraries together (Approach 4 above) at binary level is unlikely to work -- OpenSSL is very picky about its ABI (they usually have .so files versioned down to the minor number) so you'd have to be very lucky to have an .so that's ABI-compatible to their .a file.
My suggestion is a variation of Approach 4, but at source level: you'll have link in the Opsec libcpopenssl.a, since it's a modified version of OpenSSL which include extra symbols (and possibly other modifications), and grab the extra functions you need from the OpenSSL sources and recompile those objects with libcpopenssl.a, so they can use the functions from the Opsec version. If you're only using a few OpenSSL functions which are not exported by libcpopenssl.a, this is quite doable.
Granted, that's still a cumbersome approach, but it's a guaranteed way to get symbol compatibility, provided of course that the Opsec SDK didn't make semantic changes to OpenSSL that will break the additional OpenSSL functions that you're pulling into your project.
(I'm new at StackOverflow so I don't know if this suggestion qualifies as a proper answer, but I don't have reputation points to post comments, anyway. I'll remove this if it's inappropriate.)
If you're morbidly curious, 249 files were modified in the most recent version of OpenSSL to get it to compile. The most common issue by far was the abundance of C-style pointer casts, particularly with void*. Now I see "reinterpret_cast" in my dreams.
This didn't solve it alone though - it still needs to be placed into a namespace in its entirety, which means modifying all of the files again as well as my own internal references to it. I think I'm going to pass on this for now.
Thanks for the help everyone.