I am attempting to enable UBIFS support into u-boot but have encountered several undefined reference errors when compiling. In my board configuration, I have enabled the following:
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_PARTITIONS
#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_UBI
#define CONFIG_RBTREE
#define CONFIG_CMD_UBIFS
#define CONFIG_LZO
And get the following undefined reference errors when compiling:
uboot/fs/ubifs/lpt_commit.c:1232: undefined reference to dbg_chk_lpt_free_spc
uboot/fs/ubifs/lpt_commit.c:1235: undefined reference to `dbg_check_ltab'
fs/built-in.o: In function `layout_cnodes':
uboot/fs/ubifs/lpt_commit.c:322: undefined reference to `ubifs_dump_lpt_lebs'
fs/built-in.o: In function `ubifs_add_bud_to_log':
uboot/fs/ubifs/log.c:194: undefined reference to `ubifs_commit_required'
uboot/fs/ubifs/log.c:225: undefined reference to `ubifs_request_bg_commit'
uboot/fs/ubifs/log.c:265: undefined reference to `ubifs_write_node'
fs/built-in.o: In function `ubifs_log_end_commit':
uboot/fs/ubifs/log.c:479: undefined reference to `ubifs_write_master'
fs/built-in.o: In function `do_write_orph_node':
uboot/fs/ubifs/orphan.c:248: undefined reference to `ubifs_write_node'
dbg_chk_lpt_free_spc, db_check-ltab, ubifs_dump_lpt_lebs, ubifs_write_node, and ubifs_write_master are"ifdef'd" out (#ifndef __UBOOT__ but...obviously __UBOOT__ is defined).
With a quick grep, ubifs_commit_required, ubifs_request_bg_commit are completely missing implementations.
Does u-boot not support UBIFS entirely, or is it currently broken? (Using 2016.07 release). Or am I perhaps missing a step...
UBIFS was indeed broken in the mainline for several architectures. A proposed patch can be found in the pipemail at http://lists.denx.de/pipermail/u-boot/2016-September/265474.html, but it hasn't been approved yet. The patch applied without issues and I can now compile, though whether the filesystem works with it remains to be seen...
Related
First of all, I have read this post Why do you need an explicit `-lm` compiler option & this gcc: why is the -lm flag needed to link the math library?. I wanna know why It doesn't happen in case of constants (when I say constants, I mean random floats/doubles)? If you're confused, call it floating-point literals.
Why do we have to use -lm to tell the linker to use math.h functions only when using variables as parameters but not constants? If I use sqrt(N)(N is some number), it compiles fine without any errors but when I pass some variable, let's say sqrt(var), it doesn't. It says:
/usr/bin/ld: /tmp/cc5P9o72.o: in function `main':
sq.c:(.text+0x1b): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
It should behave the same all the time (I think so, but I am wrong, of-course) as I am using the same function from the same library. Either its variable or constant. I first thought its some kind of compiler optimization (if it's the same value every time, why not calculate it while compiling by some other way, i.e not using the library, as it's not working) but it's doesn't work even if I pass some variable that has a fixed value from beginning to the end. So, I was wrong there. What is actually happening here?
Following is the snippet I tried:
#include <stdio.h>
#include <math.h>
int main () {
float a=9;
printf("%f",sqrt(a));
return 0;
}
It is very simple. When you pass the constants many compilers will evaluate it (in such a trivial example when the result is not float inaccuracies and implementation differences prone) compile time without calling the math.h functions.
Even if you do not pass the constants values and compile it with no math error checks and fast math, the compiler will generate the direct float machine code instructions without calling the library ones
Before asking check the generated code for example using the godbolt.org, and usually it will answer all of your questions
Wy redefinition of function already present in dynamic library does not throws any compilation and linking error?
In the below function
#include "calc_mean.h"
#include <stdio.h>
int mean(int t, int v) {
return 0;
}
int main () {
int theMean = mean(3,6);
printf("\n %d\n",theMean);
}
Inside the shared library Definition of mean function already present as below.
#include <stdio.h>
#include "calc_mean.h"
int mean(int a, int b) {
return (a+b)/2;
}
The definition of mean function is already present in the shared library libmean.so. But during compilation I don't see any redefinition error and compilation is successful.
And on successful execution the o/p I see is 0 instead of 4 so the function definition of mean inside the shared library is not getting executed but the one inside the main module is getting executed.
Why is this happening so?
The linker only links in a function from a library if the function had not yet been found during the compilation/linking process.
The reason for the difference in functionality is that there are different types of symbols. A library function is a weak symbol. It is only included if it is not already defined. nm is a tool for listing the symbols in an object or executable. In its man-page you can find a list of the types of symbols.
There is also a wikipedia page on weak symbols.
Having two definitions of one externally-visible function (even if the definitions are identical, for non-inline functions) causes undefined behaviour, with no diagnostic required. (Ref: C99 6.9#5 and Annex J.2)
In C, some illegal code requires a compiler diagnostic and some doesn't. Typically the ones that do not require a diagnostic are because:
it would be considered too prohibitive to require all compilers to detect and report the error
there were existing systems in use that did not diagnose it and the Standard committee did not want to render an existing implementation non-conforming.
In this case, my guess would be that this is a case of the first one; they wanted to leave open the option for compilers/linkers to implement weak symbols as an extension, so they did not specify that the compiler must give a warning here. Or possibly it is actually difficult to detect this in general, I've never tried to write a linker!
It should be considered a quality-of-implementation issue if no diagnostic is given. Perhaps it is possible to pass different flags to your linker so that it does reject this code; if not then you could put a in bug report or a feature request.
Did you link correctly the shared library because the compiler should give the error :
multiple definition of 'mean'
I am compiling a project with lot of external libraries. The project has some warnings , but i believe that it should not hamper the creation of the .hex file. So when i compile the project I get a list of linking errors.
Compiling C:\liblwm2m\Libs\ExternalLib\heap.s
* Total program memory used (bytes): 0x28ef3 (167667) 64%
* Total data memory used (bytes): 0x360a (13834) 84%
x_object_device.o(.text+0x688):C:\liblwm2m\Libs\ExternalLib\object_device.c: undefined reference to `strdup'
x_object_device.o(.text+0x68a):C:\liblwm2m\Libs\ExternalLib\object_device.c: undefined reference to `strdup'
x_object_device.o(.text+0x6b6):C:\liblwm2m\Libs\ExternalLib\object_device.c: undefined reference to `strdup'
x_object_device.o(.text+0x6b8):C:\liblwm2m\Libs\ExternalLib\object_device.c: undefined reference to `strdup'
x_object_device.o(.text+0x6e4):C:\liblwm2m\Libs\ExternalLib\object_device.c: undefined reference to `strdup'
x_object_device.o(.text+0x6e6):C:\liblwm2m\Libs\ExternalLib\object_device.c: more undefined references to `strdup' follow
x_observe.o(.text+0x3c2):C:\liblwm2m\Libs\ExternalLib\observe.c: undefined reference to `object_read'
x_observe.o(.text+0x3c4):C:\liblwm2m\Libs\ExternalLib\observe.c: undefined reference to `object_read'
x_liblwm2m.o(.text+0x86):C:\liblwm2m\Libs\ExternalLib\liblwm2m.c: undefined reference to `strdup'
x_liblwm2m.o(.text+0x88):C:\liblwm2m\Libs\ExternalLib\liblwm2m.c: undefined reference to `strdup'
x_management.o(.text+0x48):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_read'
x_management.o(.text+0x4a):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_read'
x_management.o(.text+0xa6):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_create'
x_management.o(.text+0xa8):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_create'
x_management.o(.text+0x154):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_isInstanceNew'
x_management.o(.text+0x156):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_isInstanceNew'
x_management.o(.text+0x16e):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_create'
x_management.o(.text+0x170):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_create'
x_management.o(.text+0x188):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_write'
x_management.o(.text+0x18a):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_write'
x_management.o(.text+0x1a2):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_execute'
x_management.o(.text+0x1a4):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_execute'
x_management.o(.text+0x1da):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_write'
x_management.o(.text+0x1dc):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_write'
x_management.o(.text+0x208):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_delete'
x_management.o(.text+0x20a):C:\liblwm2m\Libs\ExternalLib\management.c: undefined reference to `object_delete'
x_registration.o(.text+0x8c):C:\liblwm2m\Libs\ExternalLib\registration.c: undefined reference to `prv_getRegisterPayload'
x_registration.o(.text+0x8e):C:\liblwm2m\Libs\ExternalLib\registration.c: undefined reference to `prv_getRegisterPayload'
C:\Program Files\Microchip\MPLAB C30\bin\bin/pic30-coff-bin2hex.exe: a.cof could not be opened.
The system cannot find the file specified.
---------------------------------- COMPILING ERROR ---------------------------------------
Here the strdup function is in which is supported by openpicus and i have also declared it. What surprises me is that the program compiles correctly but throws linking errors. Any thoughts about this ?
Thanks in advance
These are the errors in the code
undefined reference to strdup'
undefined reference toobject_read'
undefined reference to object_create'
undefined reference toobject_isInstanceNew'
undefined reference to object_create'
undefined reference toobject_write'
undefined reference to object_execute'
undefined reference toobject_write'
undefined reference to object_delete'
undefined reference toprv_getRegisterPayload'
P.S. these are not warnings!!
The error indicates that there is no definition of the functions "strdup", ... , "prv_getRegisterPayload". The linker does not find the references to these routines, and it terminates with a link time error. No linking means no hex file produced, that is the standard behavior of all toolchains.
Check the libraries that you have attached to the project. Add the libraries that have references/definitions for these routines, and the code should then build fine.
A pseudo code that will produce a similar error is as:
extern void parabola ();
int main(void)
{
parabola (); // ERROR here "undefined reference to `parabola'
}
-- Where is the definition of the function parabola? Shouldn't it be
void parabola ()
{}
int main(void)
{
parabola (); // Builds like magic
}
When compiling this code:
PCONSOLE_FONT_INFOEX Font_Info;
//Adjust heights
Font_Info.dwFontSize.X = 9;
Font_Info.dwFontSize.Y = 9;
SetCurrentConsoleFontEx( StdHandle, FALSE, Font_Info);
GCC reports
undefined reference to 'SetCurrentConsoleFontEx'
But MSDN says that the header is #include<windows.h>
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686200(v=vs.85).aspx
Why? And how to resolve this problem ? THANKS.
PS,
I couldn't find any declaration in wincon.h and windows.h
This would not be the first time a function is missing from MinGW's SDK, and especially not a recent function like SetCurrentConsoleFontEx which is only exposed from Vista onwards.
Your libkernel32.a is too old for it; if you want to use this function from MinGW, you may need to access it dynamically instead.
Undefiend reference refers to a linkage problem. Definition may be in windows.h but you need to link to the appropriate library (Kernel32.lib) to generate final binary.
I'm trying to build a wrapper library with VC++'s compiler.
ErlDriver.c
#define __WIN32__
#define DLL_EXPORT __declspec(dllexport)
#include "erl_driver.h"
DLL_EXPORT int _driver_output(ErlDrvPort port, char *buf, int len) {
return driver_output(port, buf, len);
}
build.bat
cl /I%ERL_DRIVER_H% /LD /MD ErlDriver.c
When I attempt to build this, I get the following linker error:
ErlDriver.obj : error LNK2019: unresolved external symbol _WinDynDriverCallbacks referenced in function __driver_output
erl_win_dyn_driver.h (included in erl_driver.h)
typedef struct {
WDD_FTYPE(driver_output) *driver_output;
// a ton more of those
} TWinDynDriverCallbacks;
extern TWinDynDriverCallbacks WinDynDriverCallbacks;
#define driver_output (WinDynDriverCallbacks.driver_output)
So, as you can see, WinDynDriverCallbacks is defined declared.
What could be causing the linker error, then?
No, it's not defined (at least in what you quoted). It's declared. The "extern" keyword means "the definition for this symbol appears in another compilation unit (source file)." You need to be linking with the object file (or library) produced from compiling the source file that defines that symbol.
There is a subtle difference between "declaring" something and "defining" it in C or C++. When you declare it, it tells the compiler that a certain symbol will be defined somewhere else - this can allow the code to use that symbol without needing to see the actual definition. You still have to define the symbol somewhere in the code that is linked in, or else you will get the error message you are seeing.
For example, this is a declaration of the symbol WinDynDriverCallbacks:
extern TWinDynDriverCallbacks WinDynDriverCallbacks;
Your code has this declaration - it allows the code that uses the symbol to successfully compile (but not link).
You need to add a definition somewhere:
TWinDynDriverCallbacks WinDynDriverCallbacks;
The definition must go into a source code file somewhere (not generally in a header file). This tells the compiler to allocate space in the object code for that object and allows the program to link successfully.
I got a very similar problem building a NIF on Windows. Unresolved external symbol _WinDynNifCallbacks. Turns out this is defined by the ERL_NIF_INIT macro and in my case the entire macro needed to be enclosed in a extern C block.
ie this failed
extern "C" ERL_NIF_INIT(...)
while this succeeded
extern "C"
{
ERL_NIF_INIT(...)
}
I strongly suspect this problem is due to the same issue but with the DRIVER_INIT macro for an erlang port driver.
Driver_Init is the main loop that declares "TWinDynDriverCallbacks WinDynDriverCallbacks;" but it's properly declared in the multiple line define for driver_init. You shouldn't need to wrap it in extern "c".
since this thread came up about a million times while trying to setup my barebones erlang port driver i will say this here. I am working out of Joe Armstrong's programming erlang book, chapter 12 interfacing techniques. Using erl5.9 and vs2010.
The code in the book had a omission and a error in example1_lib.c. Though the error is most likely due to the age of the book versus erlang version changes.
Needed to set (#define WIN32) at the very top of example1_lib.c otherwise erlang defaulted to all the Linux options.
Second needed to change (int bufflen) to (ErlDrvSizeT bufflen) in example_drv_output.
After that it built clean.