linker returns undefined reference to 'kernel_main()'? - c++

I like programming, and recently I have been interested in operating systems. So once I found a working tutorial I would start programming, and modifying as much as I knew was possible (at least for me). But there came a time where I realized that programming everything in assembly just wasn't all that great, and I wanted to try programming an operating system in c++ and assembly. Every tutorial out there says it works, but I get one common error when linking: Undefined reference to 'kernel_main', even though the function exists. I tried to see if I spelled it wrong, but I didn't. I also made sure that everything was exactly as it was in the tutorials. Here is the link to an example that didn't work for me:
http://www.cplusplus.com/articles/zv07M4Gy/
I have indeed gotten past the compilation. The problem is simply sat within the linking of the two object files. Thanks in advance.
NOTE: I am running a 64 bit version of windows 10, so I am using the linker built in to gcc instead of the default windows one. Keep in mind that other tutorials also say to use C as the language for the kernel, and I am also doing that.
EDIT:
For one tutorial, I would use:
gcc_directory/i686-w64-mingw32/bin/ld.exe -m elf_i386 -T linker.ld -o main.bin boot.o kernel.o
For the one linked above, you can find the compilation info in the "How to compile it" section.
EDIT2: https://www.youtube.com/watch?v=wmR-_rxWvYc&t=234s

Related

I cannot compile this simple C++ program involving gd.h

This isn't my code, I am not a programmer but I did not expect simply compiling a provided source code would be so difficult.
Here it is, taken from Joel Yliluoma's page about "arbitrary-palette positional dithering algorithm", it was written in 2011.
This was my troubleshooting process, using MinGW:
The code didn't seem to make sense at all, so I realized it was written in an earlier version of C++, and added -std=c++98.
It couldn't find gd.h, I downloaded that from libgd's website, and directed to its directory using -I.
A bunch of gd related commands got a "undefined reference to" treatment. I tried to direct the compiler to gd.h/gd.c directory again using -l and followed by -lgd. And this is where I got stuck, as
The compiler insisted on not being able to find -lgd. I tried with different versions of libgd (especially older ones, before 2011) and sometimes it'd find what it's looking for, but then skip over them as they are incompatible.
I've also tried to compile it with another program called Dev-C++ but to no avail. Dev-C++ also gave back a "linker error". I can only assume that I messed up linking the header or library somehow, but I do not know what those terms mean frankly and just wanted a working program so I can get back to my imagery stuff. Maybe I downloaded the wrong gd.h, or I'm missing a required thing. Any help would be greatly appreciated.
Here's my current final MinGW input:
g++ -std=c++98 -Ipath\to\libgd code.cpp -Lpath\to\libgd -lgd -o executable.exe
I can assure you that path\to\libgd contains gd.h (and a bunch of other gd related stuff) and either one of these depending on which version of libgd I found: libgd.lib, libgd.dll.a, lidgb.def, libgd.rc, libgd.so.
I'm using Windows 7 64-bit.

dynamic library using boost has undefined references when built on ARM architecture

I have a C++ based dynamic library that I have built for the big 3 OSs that relies heavily on boost. Currently, I am compiling it for the raspberry pi. It took me a while to find the magic words to get the library to even build (-frepo as a compiler flag was the key, but I confess that I am not certain why this is the case).
Now, when I try to link to the library, I get an 'undefined reference' error to every boost call that my library makes, i.e.:
//`libmylib.so`: undeifined reference to `boost::shared_ptr<boost::detail::thread_data_base>::shared_ptr()'
When I build libmylib.so, I also build a custom version of boost as libboost.a. This all compiles and links fine on other OSs and non-ARM architectures so I tried putting -lboost as one of the flags, but I still get the same plethora of undefined reference errors form libmylib.so.
Needless to say, all my paths are correct.
It seems like linking behaves a bit differently on the raspberry pi than it does on other linux systems. For example, I built a static library (libmythread.a) that uses libpthread. When I link to that libmythread.a, I also get undefined reference errors unless I also use -lpthread in the build recipe. On my Thinkpad running Fedora, I would never have to do this since I included -lpthread in the compilation of the static library libmythread.a.
I would love to find a tutorial or guide that explains these discrepancies. I would also love to overcome them!
I also tried the same build on a conventional linux machine and everything linked fine, no problem. At least I know that my build process is OK. This does open up the possibility, though, that the -frepo flag is doing something funny that I don't understand and that this could be the root of the problem.
Solved. In the end, the trouble stemmed from the -frepo flag. This was necessary to compile a file called legacy_abi.cpp that is part of my library to allow third party developers using older and more exotic OSs/compilers. This isn't needed on the Pi, so I just removed it from the offending file from the build, dropped the -frepo flag and happy happy.
One final note, aptitude (for Pi, anyway) only supplies boost up to 1.49 (as far as I can tell). My project requires boost >= 1.50. This is an inherited project, so I'm still discovering all its little idiosyncracies.

Static linking of Glibc

How can i compile my app linking statically glibc library, but only the code needed for my app? (Not all lib)
Now my compile command:
g++ -o newserver test.cpp ... -lboost_system -lboost_thread -std=c++0x
Thanks!
That's what -static does (as described in another answer): unneeded modules won't get linked into your program. But your expectations on the amount of stuff which is needed (in a sense that we can't convince linker to the contrary) may be too optimistic.
If you trying to do it for portability (running an executable on other machines with older glibc or something like that), there is one easy test question to see if you're going to get what you want:
Did you think of the problem with libnss, and are you sure it is not going to bite you?
If your answer is yes, maybe it makes sense to go on. If the answer is no, or the question seems too obscure and there is no answer, just quit your expirements with statically linked glibc: it has more chance to hurt than help.
Add -static to the compile line. It will only add what your application needs [and of course, any functions the functions you application calls, and any functions those functions call, including a bunch of startup code and some other bits and pieces], so it will be around 800K (for a simple "hello world" program) on an x86 machine. Other architectures vary. Since boost probably also calls the standard library at least a little bit, it's likely that you will have more than 800K added to your appliciation. But it only applies functions used by any of the code in the final binary, not the entire library [about 2MB as a shared library].
If you ONLY want link glibc, you will need to modify the linking line to your compile to:
-Wl,-Bstatic -libc -Wl,-Bdynamic. This will prevent any other library from being linked statically [you sometimes need to have more than one of these statements, as sometimes something pulled in by another library requires "more" from glibc to be pulled in - don't worry, it won't bring in anything more than the linker thinks is necessary].

gcc compiler linking differently on two servers

I have a large source-controlled C++ codebase which compiles and links without error on one Linux server.
I am now trying to set up the same application on a new server, so have checked out the same code on a new box.
However, when I execute an identical make command on identical code on this new box, I get errors. The cause appears to be because on the old box, shared library (.so) files are created. On the new box - which is using identical code and therefore makefiles - makes static libraries (.a).
The compiler being used appears to be the same as well - gcc-3.4.6.
Obviously, I have some config set differently somewhere but can anyone advise or where this config might be? I can't think of any small change which would cause this effect.
Note that the linker ld is part of binutils, which is delivered with the standard binaries as part of the Unix distribution you have, and is not part of the gcc suite.
Therefore, when you get from an old server to a new server, chances are that you pass from an old ld to a new ld.
Since a library is first created by the linker, it would be interested to check it out.
Note that if you suspect the compiler (since it performs the call to ld), you can write a ld executable script that just echoes the arguments it receives and then calls the real ld behind the scenes (meddling with $PATH should get you going).
It sounds natural that it is either a case of different arguments (why ?) or a different binray, figure out which and you'll be one step closer to solving your issue.
configure stuff might have generated slightly different Makefile-s.
And when you link with -lfoo, the linker first try dynamic libfoo.so then static libfoo.a.
GCC is now at version 4.6.2 so your 3.4.6 version is very old. Consider upgrading it, because GCC has made a lot of progress since.
Try using gcc -v (perhaps as make CC='gcc -v') to understand what is going on when building.
And give much more detail if you want real help. What are the actual libraries involved?

Using GCC through Xcode to compile basic programs

So, I'm a brand new CS student, on a Mac, and I'm learning C++ for one of my classes. And I have a dumb question about how to compile my super basic C++ program.
I installed Xcode, and I'm looking through the documentation to try and figure out how to use it (and I highly suspect it's extremely overpowered for what I'm doing right now) and eventually end up going into Terminal and going "gcc [filename]". And I've got a screen full of text that starts with "Undefined Symbols", and goes on about trying to reference things, so I'm wondering if I didn't hook up something somewhere, especially as when I'm actually in Xcode with a C++ program open, most of the menu items are greyed out.
So. In really really basic terms. What did I miss doing, and how do I fix it? Is there a basic guide to Xcode? Most of the documentation is aimed at real developers, and I'm totally missing a lot of what is being assumed.
If XCode is installed then everything is set up correctly.
If you typed gcc on the command line then you invoked the 'C' compiler (not the C++ compiler). Usually this does not matter as GCC compensates by looking at the file extension. But what does matter is that it does not invoke the linker with the correct C++ flags.
What you should do (from the command line) is use g++
g++ <fileName>.cpp
By default the output file is a.out and placed in the same directory.
g++ has a flag to specify a different output name -o
g++ -o <outputName> <fileName>.cpp