Cygwin g++ --unresolved-symbols=ignore-all - c++

I have a simple proof case file, which is called main.c
void bar(void);
void foo(void)
{
bar();
}
int main(void)
{
return 0;
}
As you can see there is no definition for bar()
My goal is to compile this on windows using cygwin's gcc.
I have figured out that I could use the following linker option:
--unresolved-symbols=ignore-all
This should tell the linker not to care about missing symbols. In the main.c example the missing symbol would not even be an issue, as foo is never called, therefore there should not be an undefined behavior when the program is executed.
I have 2 flavors of gcc, one for embedded ARM targets, and one from cygwin 64bit for windows.
The embedded ARM gcc is from here: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm , version 4_9-2015q3.
The Cygwin gcc is taken from https://cygwin.com 's 64bit installer, version 7.3.0-1
I use these compile options with the compilers:
arm-none-eabi-g++.exe -Wl,--unresolved-symbols=ignore-all main.c
g++.exe -Wl,--unresolved-symbols=ignore-all main.c
The first compiles and links without errors, as for the second I get this error message:
/cygdrive/c/Users/user/AppData/Local/Temp/ccRF8tf5.o:main.c:(.text+0x9): undefined reference to `bar()'
/cygdrive/c/Users/user/AppData/Local/Temp/ccRF8tf5.o:main.c:(.text+0x9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `bar()'
collect2: error: ld returned 1 exit status
Where clearly the undefined reference to `bar()' message should have been suppressed by the option -Wl,--unresolved-symbols=ignore-all
(The second error message does not appear, if I use gcc from the 32 bit cygwin installer.)
The --help command for the cygwin ld shows the --unresolved-symbols=ignore-all as a valid option.
I suppose the cygwin gcc has been compiled in a way, that this option does not work, even though it is not complaining that it can not validate this option.
If for example I use this command:
g++.exe -Wl,--unresolved-symbols=dummy main.c
I get this error message:
/usr/lib/gcc/x86_64-pc-cygwin/7.3.0/../../../../x86_64-pc-cygwin/bin/ld: bad --unresolved-symbols option: dummy
Which for me tells, that --unresolved-symbols is in fact is an accepted command.
My questions would be:
Is there a way to see which commands are truly accepted by gcc
Is there some other way that could work using cygwin's gcc to compile this main.c example?
Compiling gcc for windows from sources with the proper option could maybe get --unresolved-symbols to work?
My motivation for this whole thing is that I want to unit test a single function from big files, that have multiple functions. Like in the following example:
#include "foobar.h"
int foo(void)
{
return 0;
}
void bar(void)
{
foobar();
}
The declaration of foobar() is in the foobar.h and the definition is in another file called foobar.c
If I wanted to run a unit test, which just links against the symbol foo() I would still get a linker error because of the missing symbol for foobar(). (linking against foobar.o would lead me to link to the complete chain of dependencies, which I want to avoid)
If this --unresolved-symbols option would work, then I would not need to mock or stub the foobar() function in my unit test.
I do understand that there are tools that can create automatically mocks, nevertheless I would like to get this to work.
Thanks for reading through.

Related

Code stops compiling after system upgrade issuing error about relocation R_X86_64_PC32 against absolute symbol

I have a code that has accepted to compile from Ubuntu 16.04 to Ubuntu 20.04. I just reinstalled from scratch my system so now it is Ubuntu 22.04.
I have tried to reduce the code to a minimal example, but I could not test it completely as I will explain below.
main.cpp :
#include <iostream>
extern char _binary_M_0_png_size;
int main() {
std::cout << (size_t) &_binary_M_0_png_size << std::endl;
return 0;
}
I have an image M_0.png that I put in a resource file rsrc.o with
ld -r -b binary M_0.png -o rsrc.o
I compile main.cpp as follows
g++ -Wall -o main main.cc rsrc.o
And I get the following message on Ubuntu 22.04:
/usr/bin/ld: /tmp/cckW3H3g.o: relocation R_X86_64_PC32 against absolute symbol `_binary_M_0_png_size'
in section `.text' is disallowed
collect2: error: ld returned 1 exit status
Using objdump -x rsrc.o indeed shows that the incriminated symbol is *ABS*
I think this used to compile fine on 20.04. At least I have a (way) more bigger program where such a similar code is included and a similar (but longer) compilation command line was called and would work. Since I do not wish to reinstall Ubuntu 20.04 just for one test, I cannot tell if my minimal example does indeed compile and work on 20.04.
Looking into existing similar questions on forums, I found that using the compiling option -fPIC makes the program compile and work as expected. However I feel uneasy about the sudden need for this option, which is not on by default, and I am not familiar with linker considerations and do not know the cons and pros of -fPIC. Or maybe -fPIC used to be on by default and is not anymore?
Or maybe I should change my code or design: Maybe there is a better way to access the PNG image size in the resource? to compile the resource file rsrc.o? to create a single executable that contains the image?

CS50 - C++: issue with " using namespace std;" [duplicate]

There's a C++ code:
#include <stdio.h>
int main() {
int b = sizeof('a');
if(b==4) printf("I'm a C program!\n");
else printf("I'm a C++ program!\n");
}
Compile it like this:
gcc main.cpp -o main
It succeeds and gives:
I'm a C++ program!
Then add a line somewhere inside function main
int *p1 = new int [1000];
It fails with:
C:\Users\...\AppData\Local\Temp\cccJZ8kN.o:main1.cpp:(.text+0x1f): undefined reference to operator new[](unsigned long long)'
collect2.exe: error: ld returned 1 exit status
Then the following two commands successfully compile the code:
gcc main.cpp -o main -lstdc++
and
g++ main.cpp -o main
The compiler is minGW-win64 (http://mingw-w64.sourceforge.net/).
The questions are:
Which of the two last commands are better?
To my mind gcc correctly chooses the right compiler but then uses a wrong linker. Is it right?
May it be a problem in minGW-win64?
As I see (correct me if it's wrong) gcc was intended to be a main program that takes the input and decides what to do with it. So I'd better use gcc if it worked without -lstdc++. But if it's not possible I'll prefer using g++ instead as don't know what else gcc may miss.
Many thanks for your considerations
gcc is the GCC compiler-driver for C programs, g++ is the one for C++ programs.
Both will guess the language on the basis of the file-extension, unless overridden.
But if you use the wrong driver, the default-options will be wrong, like leaving out the C++ standard-library for C++ programs compiled with gcc when linking.
You can add just the library with -lstdc++, though using the proper driver is preferable, as plain gcc may be missing other, subtler options.

Embedding SpiderMonkey JS

I'm working on a C++ application. I would like to embed SpiderMonkey in the application.
I'm working with CMake, but I couldn't get that build. So, in an attempt to reduce complications, I tried the example code on this page. This wouldn't link using cmake or gcc from the command line.
So, even simpler, just to ensure I can link properly I am trying to get the following to work.
From the command line with gcc:
g++ --std=c++11
-I/home/thetasinner/moz/js/src/build_DBG.OBJ/dist/include
-L/home/thetasinner/moz/js/src/build_DBG.OBJ/js/src -DDEBUG
-Wl,--verbose -lmozjs-54a1 -lm -lz -ldl test.cpp -o test
On the following minimal code example:
#include <iostream>
#include <stdexcept>
#include "jsapi.h"
#include "js/Initialization.h"
int main(int argc, char** args) {
if (!JS_Init()) {
throw std::runtime_error("failed to initialise.");
}
std::cout << "It's alive!\n";
JS_ShutDown();
return 0;
}
Even this doesn't link. I get the errors
/tmp/ccqjx5RY.o: In function `main':
custom.cpp:(.text+0xf2): undefined reference to `JS_ShutDown()'
/tmp/ccqjx5RY.o: In function `JS_Init()':
custom.cpp:(.text._Z7JS_Initv[_Z7JS_Initv]+0xa): undefined reference to
'JS::detail::InitWithFailureDiagnostic(bool)'
collect2: error: ld returned 1 exit status
The headers are found and the linker is finding the mozjs library
attempt to open /home/thetasinner/moz/js/src/custom_build_DBG.OBJ/js/src
/libmozjs-54a1.so succeeded
-lmozjs-54a1 (/home/thetasinner/moz/js/src/custom_build_DBG.OBJ/js/src
/libmozjs-54a1.so)
I am working on Linux (Ubuntu 16.04 and Debian 8.7 tried) because that's where the build tools are. I don't even want to touch Window's yet.
The 'js' executable built in the spidermonkey build works fine, which I assume has the lib I'm trying to link inside it. So I would have thought the lib itself is built okay.
Can anybody help me resolve these linker errors? There are lots of answers to questions about much older versions of SpiderMonkey, but there's nothing for more recent versions. I'm interested in version 45 (which I've tried with very similar errors) or the tip version 52.
I'm comfortable enough digging around in the code working out how to do what I want with it once it builds, hence the interest in the latest version which isn't properly documented, I'm just completely stumped with the building step.
I suspect it's just an ordering problem on the command line:
g++ --std=c++11
-I/home/thetasinner/moz/js/src/build_DBG.OBJ/dist/include
-L/home/thetasinner/moz/js/src/build_DBG.OBJ/js/src -DDEBUG
test.cpp -o test
-Wl,--verbose -lmozjs-54a1 -lm -lz -ldl
Compilation first, followed by linking, with libraries in order of dependency. (My first guess was you'd neglected to mention mozjs on the command line. It took a second look to see it was just in the wrong place.)

Undefined reference to boost::random::random_device constructor and destructor on MinGW-w64 gcc

My OS is Windows 7 64-bit and C++ compiler I'm using is:
g++ (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 5.3.0
And I installed Boost version 1.60 using:
bootstrap.bat mingw
b2 install target=gcc
Then I tested is it working, using examples from Boost.Random tutorial.
With the first two everything was fine, but the third one gave linker errors about boost::random::random_device. I minimized the code to have only this:
// Compiled with:
// g++ -IC:/Boost/include/boost-1_60
// -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
// main.cpp
#include "boost/random/random_device.hpp"
int main() {
boost::random::random_device rng;
}
And I get the following errors:
C:\Users\Daniel\AppData\Local\Temp\cc5DfdjZ.o:main.cpp:(.text+0x15):
undefined reference to `boost::random::random_device::random_device()'
C:\Users\Daniel\AppData\Local\Temp\cc5DfdjZ.o:main.cpp:(.text+0x20):
undefined reference to `boost::random::random_device::~random_device()'
collect2.exe: error: ld returned 1 exit status
Here, on SO, I found that someone with similar problem added -lboost_system to flags, but for me it didn't helped.
Does anyone have any idea, why it isn't working? I checked, and I have random_device.hpp header in my Boost folder, with declarations of random_device() and ~random_device() in it.
I found what was wrong - the g++ command syntax, that I wanted to use to compile and link my code.
As I wrote in my question, I do this that way:
g++ -IC:/Boost/include/boost-1_60 -LC:/Boost/lib -lboost_random-mgw53-mt-1_60 main.cpp
While the correct one is with main.cpp (or any other source code file(s), that we want to include in compiling process) before the -L and -l flags.
For example:
g++ -IC:/Boost/include/boost-1_60 main.cpp -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
or even
g++ main.cpp -IC:/Boost/include/boost-1_60 -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
Hope it will help anyone, who will make such silly mistake too.

Link dynamic shared library in Linux - Undefined reference to function

I know there are many questions related to shared libraries on Linux but maybe because I'm tired of having a hard day trying to create a simple dynamic library on Linux (on Windows it would have taken less than 10 minutes) I can't find what happens in this case.
So, I am trying to create a library to be linked at build-time and used at run-time (not a static library, not a library to be embedded into the executable, in other words). For now it contains a simple function. These are my files:
1.
// gugulibrary.cpp
// This is where my function is doing its job
#include "gugulibrary.h"
namespace GuGu {
void SayHello() {
puts("Hello!");
}
}
2.
// gugulibrary.h
// This is where I declare my shared functions
#include <stdio.h>
namespace Gugu {
void SayHello();
}
3.
// guguapp.cpp
// This is the executable using the library
#include "gugulibrary.h"
int main() {
GuGu::SayHello();
return 0;
}
This is how I try to build my project (and I think this is what is wrong):
gcc -Wall -s -O2 -fPIC -c gugulibrary.cpp -o gugulibrary.o
ld -shared -o bin/libGugu.so gugulibrary.o
gcc -Wall -s -O2 guguapp.cpp -o bin/GuGu -ldl
export LD_LIBRARY_PATH=bin
This is saved as a .sh file which I click and execute in a terminal. The error I get when trying to link the library is this:
/tmp/ccG05CQD.o: In function `main':
guguapp.cpp:(.text.startup+0x7): undefined reference to `SayHello'
collect2: ld returned 1 exit status
And this is where I am lost. I want the library to sit in the same folder as the executable for now and maybe I need some symbols/definitions file or something, which I don't know how to create.
Thanks for your help!
In your C++ file, GuGu::SayHello is declared as a C++ symbol. In your header, you are wrapping it in an extern "C" block. This is actually undefined, as you aren't allowed to use C++ syntax (namespace) in that context. But my guess is that what the compiler is doing is ignoring the namespace and generating a C symbol name of "SayHello". Obviously such a function was never defined by your library. Take out the extern "C" bits, because your API as defined cannot be used from C anyway.
You are inconsistent with your GuGu, there are also Gugu's running around, this needs to be made consistent, then it works (At least on my computer are some Gugu's now)