Some context:
My program uses libary libfl.a (flex library).
I compile it under linux:
gcc lex.yy.c -lfl
I have mingw compiler installed i586-mingw32msvc-gcc (simple 'hello world' stuff compiles without problem)
I use ubuntu (probably does not matter)
I want to compile under linux for windows (produce binary .exe file which would be usable on windows)
My problem and questions:
When I try compiling my program
i586-mingw32msvc-gcc lex.yy.c -lfl
I get errors:
[...] undefined reference to '_yywrap'
[...] undefined reference to '_WinMain#16'
Do I understand correctly that I have to compile the content of libfl.a also with i586-mingw32msvc-gcc to be able to use it in this cross-compilation?
In the source code there is function yywrap(), but not _yywrap(). Why I get error for function with underscore _?
Whats up with the _WinMain#16? (no usage in source code)
My goal would be to understand what is happening here.
If I get it to work, then its bonus points :)
Any help is appreciated
Yes, certainly. And here's why:
C++ encodes additional semantic information about functions such as namespace/class affinity, parameter types etc. in the function name (that is called name mangling). Thus C++ library names are somewhat different from what you see in the source code. And each compiler does it in it's own way, that's why generally you're unable to link against C++ functions (C function names don't get mangled still) of a library built with a different compiler.
Judging to mangling style, the undefined symbols are brought in by the Microsoft C++ compiler. I don't know exactly about why it needs WinMain, but after you recompile the libs with it, all these errors likely will be gone. And yes: maybe the WinMain() thing rises from msvc using it instead of main(), which presence is obligatory for a well-formed program? ;)
Related
I'm attempting to port a large set of modules from AIX to Linux. Unfortunately, the AIX xlc compiler allowed you to define a static function and use it prior to the definition with no prototype. Not good, but at least you get the proper static scope. In any case, the code is there, and I can't get it to compile on Linux without explicitly adding a static prototype.
So, is there any way to inhibit the "static declaration follows non-static declaration" error in gcc (or make it a warning instead of a hard error), or do I have to edit each of these modules to add prototypes wherever they're missing? As I understand it, this is a case where the standard behavior is undefined - so it's kind of nasty if gcc wouldn't allow you a way to relax its internal standard to allow for code that compiles elsewhere, no...?
This has been a hard error in GCC since 2004. The only option to get this to compile is to downgrade to a really old version of GCC. I verified that GCC 3.4.6 still compiles this, but GCC 4.0.3 does not.
Of course, depending on your target, getting GCC 3.4 to work might be close to impossible.
It's said that linux loader is /usr/bin/ld, but usually we use gcc/g++ to link libraries and executables, we barely use "ld".
The last time I used "ld" manually was when I was learning linux assembly, the only way to generate executable is to ld a .o file to generate executable directly without any library.
My question is, is gcc/g++ containing some function wrappers of "ld", because raw "ld" is too difficult to use? Or we should never use "ld" explicitly for c/c++ program linking, because of blablabla?
gcc supplies a few default options to ld.
ld doesn't know anything about C++, or any other language. ld has no idea what libraries your code needs to link with. If you try to link your compiled C++ code with ld directly, it'll bail out on you, since ld, by itself, has no idea where it can find libstdc++, gcc's C++ runtime library. Do you use strings? vectors? Most of that is template code that gets compiled as part of your object module. But there are a still few precompiled bits, in libstdc++, that need to be linked with.
When you give your compiled code to gcc to link, gcc will be courteous enough to pass all your files along to ld, and tell ld which libraries, in addition to any ones you explicitly specify.
You can link with ld directly, if you want to, as long as you specify the same libraries and link option gcc uses. But why would you want to do that? Just use gcc to link your gcc-compiled code.
You shouldn't attempt to directly use ld to link a C++ program because you need to know the implementation detail of where the static part of the C++ runtime library is located. g++ knows these implementation details, such as where to find the file libstdc++.a. If you tried to use ld directly, you would have to supply all these "missing" static libraries.
My question is, is gcc/g++ containing some function wrappers of "ld"
That's right.
because raw "ld" is too difficult to use?
Well, not really; you could use it yourself without too much trouble, but it's convenient to manage the entire build process through a single executable, with a single suite of flags, and often with a single command.
It's also likely that you'd have to provide absolute paths to some runtime libraries (e.g. libstdc++.a) yourself if you bypassed the wrapper (though I haven't tested this).
Or we should never use "ld" explicitly for c/c++ program linking, because of blablabla?
You're free to do so if you want. The only reason people might raise their eyebrows is to ask why you're not doing it in the conventional manner. If you have a good reason to invoke ld directly, rather than going through g++ and passing through any linker flags that way, then go right ahead!
I was trying to compile an openMP example and he refuses to compile saying "undefined reference to 'OSCR_init', undefined reference to `OSCR_getarg_int' and several other functions. Then I located these functions in the file OmpSCR.h, that came in another folder, searched inside it and saw that these funcions were defined externally, I believe that in omp.h. I included the file with "include " in the example source (OmpSCR.h was already included) hoping that it would solve the question, but nothing improved. I do have omp.h, it came with the os. Can it be a version conflict? I got the example file from OMPSCR_v2.0.tar.gz What should I do?
An "undefined reference" error means that no definition of the function was found at link time. A declaration in a header (such as omp.h) doesn't provide an implementation for the function; it just tells the compiler that the function exists somewhere. You have to link your program with a library that actually provides the function's implementation.
Basically, you just need to link your program to an OpenMP library. The way to do this depends on which compiler and which OpenMP implementation you're using, neither of which you've specified, so I can't provide specifics. (But if you happen to be using GCC, you should use the -fopenmp option for both compiling and linking.)
I'm using DLL injection in a video game for the purpose of modding (I'm building a game API).
I want to directly access structures and variables in the EXE from my new DLL. The absolute addresses of variables are known (the EXE has a fixed image base) .
According the GNU ld documentation, I can use --defsym=symbol=expression to create a global symbol in the output file, containing the absolute address given by expression.
I can't get it to work.
If I declare the symbols as extern in my code, and use ld --defsym, I get undefined reference errors. But if I define the symbols in my code, it just uses the local (DLL) versions, not the EXE ones.
It seems the --defsym options are having no effect. Any insights would be greatly appreciated.
Update: --defsym works perfectly under Linux. When I try compiling on Windows using mingw, I get undefined reference errors.
I've figured out the problem.
After inspecting the assembly produced by mingw, I found the C symbol names are being prefixed by an underscore. This happens on Windows, but not on Linux.
There is a gcc option -fno-leading-underscore, but this results in an undefined reference to WinMain.
Simply adding leading underscores to the symbol names works.
Example: if my my symbol is named alien in C, using gcc --defsym=_alien=0x500000 works fine.
I am trying to compile some code for an STM32 chip using CodeBench G++ Lite tools. However, it generates an error.
startup.o: In function `LoopFillZerobss':
(.text.Reset_Handler+0x2a): undefined reference to `__libc_init_array'
I have googled and it appears that libc_init_array is probably part of some standard gcc library...but I am not sure how to fix this error?
I also have errors such as this
arm-none-eabi-ld: cannot find libc.a
and similarly for libgcc.a and libm.a
The function __libc_init_array is part of CodeSourcery's 'CS3' mechanism for 'start up' code which ensures all of a programs static initialisation happens before main is executed.
Start by ensuring all of the libraries are found. That might be enough to fix all your problems.
One approach is to use arm-none-eabi-g++, and not use arm-none-eabi-ld directly, to do the linking because g++ should correctly pass some important parameters to arm-none-eabi-ld. In some case, that might be all that is needed to find and link the correct libraries.
If you aren't sure how to build on the command line, or arm-none-eabi-g++ isn't doing everything to resolve the missing libraries, go and have a look at LeafLabs web site, where they show how build from the command line using Makefiles
http://leaflabs.com/docs/unix-toolchain.html
They provide a free, Open Source, IDE for STM32, built for Windows, Linux and Mac, which includes a working gcc-based toolchain for each of those platforms, and enough of the libraries to get started http://leaflabs.com/docs/maple-ide-install.html
Even if you'd prefer to use your toolchain for the actual build, it may be worth using theirs, with their Makefiles, to sanity check the process you are using to build your program.
I am not a member of LeafLabs staff, and have no relationship with the company other than I have bought some of their products, and try to answer questions on their forum.