How do I use a cross compiler?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
lollynoob
Member
Member
Posts: 150
Joined: Sun Oct 14, 2007 11:49 am

How do I use a cross compiler?

Post by lollynoob »

Hello, I've finally decided to use a cross-compiler for development, and because of the fact that I needed to mix 16 and 32-bit code for my second-stage bootloader (along with other reasons), I compiled binutils and gcc to target i386-aout. Now that's not the problem; everything built correctly there. I'm just wondering now that I've got my toolchain compiled, how do I use it? I've gotten everything working from the command line and batch files (using cygwin1.dll), but gcc doesn't output anything when I try to compile source files (regardless of flags; even "gcc -o main.o main.c" doesn't give me anything).

Where am I going wrong? Do my source files need to have Unix-style carriage returns? Do I need to run gcc from bash or sh? Sorry if I sound lost, I'm just used to my old tools (djgpp) working, and these new ones (gcc-i386-aout) not doing the same has sort of thrown me off. Any help would be appreciated.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Best thing would be to run the Cygwin tools from the Cygwin shell. Not sure if they work that well otherwise.

GCC doesn't say anything? No error message, no output file, no nothing? :?:
Every good solution is obvious once you've found it.
User avatar
t0xic
Member
Member
Posts: 216
Joined: Sat May 05, 2007 3:16 pm
Location: VA
Contact:

Post by t0xic »

I have a GCC cross compiler through cygwin and I have been able to run gcc through make, and the command line (batch should work). Also, you don't need Unix-style line returns. Don't know if that helps, as I didn't really solve your problem
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Not sure if they work that well otherwise.
I have the cygwin bin path in my system path. The only significant difference is that you use the run dialog/windows command prompt, with the different syntax from bash.

The good thing is that I don't have to bother about making the distinction between ls and dir anymore :twisted:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
lollynoob
Member
Member
Posts: 150
Joined: Sun Oct 14, 2007 11:49 am

Post by lollynoob »

Well, I've found what my problem is. I ran gcc (cross compiler) from bash in cygwin, and it gives me this error:

Code: Select all

/usr/cross/lib/gcc/i386-aout/3.4.3/../../../../i386-aout/bin/ld: cannot find -lc
Now, I've looked around, and apparently this has something to do with libc, which is weird, since I'm not using a libc for my kernel and I didn't enable using one (unless such a thing is enabled by default) in my options when I built gcc. I'm not from a Unix background, as you can probably tell, so could anyone tell me if I'm missing anything obvious or, if it's not an obvious problem, could anyone point me in the right direction?

Also, in case this was important, I followed the cross compiler tutorial on the wiki word-for-word, aside from targetting i386-aout instead of i586-elf.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

You forgot to add "-nostdlib" to your compile line.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

lollynoob wrote:...I'm not using a libc for my kernel and I didn't enable using one (unless such a thing is enabled by default)...
It is. Look at the Bare bones tutorial for a "known good" set of compiler options.
Every good solution is obvious once you've found it.
User avatar
lollynoob
Member
Member
Posts: 150
Joined: Sun Oct 14, 2007 11:49 am

Post by lollynoob »

Well, I just tried using the flags the bare-bones tutorial suggests I do (-nostdlib -nostartfiles -nodefaultlibs), and I get this error. Pardon me for throwing error codes out there for people to fix, but I'm not really sure how to resolve this problem.

Code: Select all

cczKLNk2.o:(.text+0x1d): undefined reference to `___main'
As far as my code goes, it's just a simple main() with code to put an 'A' into the first character of the text mode buffer.

Edit: I'm not sure I understand why (I'll look it up), but using "gcc -o main.o -c main.c" (as the bare-bones tutorial did) worked, whereas my old "gcc -o main.o main.c" did not. Thanks for the help, everyone.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Edit: I'm not sure I understand why (I'll look it up), but using "gcc -o main.o -c main.c" (as the bare-bones tutorial did) worked, whereas my old "gcc -o main.o main.c" did not. Thanks for the help, everyone.
Thats because the first method doesn't invoke the linker, and what you're getting is a linker error.

Some compilers add "_" characters to the front of every C symbol. If you're calling C code from ASM, watch out for that. You may have to prepend a "_" yourself so the correct symbol is called.
User avatar
lollynoob
Member
Member
Posts: 150
Joined: Sun Oct 14, 2007 11:49 am

Post by lollynoob »

Well, I've got my main.c to compile to cmain.o (a.out) and my 16-bit assembly code to compile to amain.o (a.out), but now when I try to link the two to a single binary, I get this error:

Code: Select all

bin/cmain.o:bin/cmain.o:(.text+0x1d): undefined reference to `___main'
If this is a simple problem, could someone point me in the right direction to solve it? Also, if more information is needed (my code, build script, makefile, or linker script, for example), I can post anything related that's important.

Thanks for helping.

Edit: I've decided that instead of messing with mixing 16 and 32-bit code in one binary, I'll just concatenate my 32-bit binary to the end of my 16-bit one. This should work more smoothly than making an ugly mix when I don't need to.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

For some reason, three underscores have been added to the start of your main symbol - try calling that.

Cheers,
Adam
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Hint #1: main() is the entry point for a userspace application. If your kernel binary contains any references to main(), some part of your toolchain tries to build a userspace binary.

Hint #2: To avoid confusion, do not call your kernel's entry point main(). Use kmain(), kstart() or similar. This makes error messages more helpful.

Hint #3: Make sure your Assembler and your Compiler agree on the "underscore rule" (whether to prefix a function name with an underscore or not). Personally I prefer toolchains that do not add underscores, because it's the kind of implicit, unexplained behaviour that gives you headaches. Create a dummy .asm and .c file containing one function only, and use objdump to check which "underscore rule" is applied by your respective tools.

Hint #4: Do this kind of learning about your toolchain in userspace if at all possible.
Every good solution is obvious once you've found it.
Post Reply