Compiling gcc with AVR options - gcc

I want to generate the assembly file of my code oriented to the AVR architecture, I am using gcc version 4.7.2 with the following arguments:
g++ -O3 -Wall -S -Wp,-mmcu=atmega8 -o "src\Compression.o" "..\src\Compression.cpp"
but I am getting the following error:
cc1plus.exe: error: unrecognized command line option '-mmcu=atmega8'
But I got the command options from the gcc website:
http://gcc.gnu.org/onlinedocs/gcc-4.7.3/gcc/AVR-Options.html#AVR-Options
There should be something that I am missing, could you help me with this please!

If gcc does not accept -mmcu, you are probably not using a gcc with support for the AVR architecture.
It's normally used like this:
avr-gcc -mmcu=atmega328p
because it's not only the preprocessor, it's actually other tools as well which require this setting (linker, assembler).
Normally the architecture gcc is compiled for is indicated by a prefix, in this case it's avr- by convention.
So the solution is to get a toolchain with AVR support. You can download it from Atmel's web site, even for Linux.
Update
If you like to check the configuration of your gcc, you can use -dumpmachine to check for the target processor
$ gcc -dumpmachine
i486-linux-gnu
$ arm-none-eabi-gcc -dumpmachine
arm-none-eabi
$ avr-gcc -dumpmachine
avr
If you look at the target specific options using --target-help
$ gcc --target-help | grep march
-march= Generate code for given CPU
you can see that the Linux gcc does accept -march as well. It probably fails later.
gcc is a very complex piece of software, because it just supports so many different architectures. From that perspective it works amazingly well.
Another interesting option is -v
$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8'
[...]
to see how that gcc has been built.
And there could be another trap down the road (multi-libs), as you can see here

Related

How can I compile with LLVM/Clang to RISC-V target?

I want to compile a simple program "int main(){return 0;}" to RISC-V processor.
LLVM/Clang version is 9.0 and I want to run the compiled program with a RISC-V simulator like this https://github.com/riscv/riscv-tools
My problem is that I can't list the clang supported targets only the LLC-s whith these commands:
llc --version
llc -march=xxARCHTYPExx -mattr=help
And there is no any type of riscv processor listed.
So I tried to look the triple file: llvm-project\llvm\include\llvm\ADT\Triple.h
and try a command like: clang hello.c -target riscv32 -march=rv32imafd
But I get the following error:
error: unable to create target: 'No available targets are compatible
with triple "riscv32"'
Can somebody help me to how get a valid RISC-V target? I just simple can't compile the program but I know LLVM has a RISC-V support.
LLVM 9 release notes explicitly state that RISC-V support was promoted from experimental to official.
And indeed, on my Fedora 31 machine, the LLVM 9 Fedora package does support RISC-V:
$ llvm-objdump --version | grep riscv
riscv32 - 32-bit RISC-V
riscv64 - 64-bit RISC-V
Also, I can create RISC-V binary code with the LLVM toolchain:
$ clang --target=riscv64 -march=rv64gc rotate.s -c -o rotate.o
$ file rotate.o
rotate.o: ELF 64-bit LSB relocatable, UCB RISC-V, version 1 (SYSV), not stripped
Although it doesn't include a libc for RISC-V targets:
$ clang --target=riscv64 -march=rv64gc hello-world.c -o hello-world
hello-world.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^~~~~~~~~
1 error generated.
However, you don't really need one - you could directly call syscalls for your hello world, e.g.:
$ clang --target=riscv64 -march=rv64gc hello.s -c -o hello.o
$ ld.lld hello.o -o hello
$ spike --isa=RV64gc ~/local/riscv/pk/riscv64-unknown-elf/bin/pk ./hello
bbl loader
Hello World
I don't use clang for linking because it seems that I can't convince clang with -fuse-ld to use another linker besides /usr/bin/ld.

How to cross compile solaris 32-bit

We are currently building our Go executables for several platforms including Solaris 64-bit. We have requests for a 32-bit Solaris executable version as well and I am unable to get this to work (the person who setup the Solaris 64-bit cross compiler is gone and unreachable).
I tried just setting -m32 flag on go build using our existing solaris cross compilation, but that didn't work, so I am attempting to build a Solaris 32-bit specific cross compiler.
I googled and found some vague examples, so I am following this process:
Copy headers and libraries from a 32-bit Solaris machine to my Linux build machine.
D/L and build binutils and gcc pointing SYSROOT to the downloaded 32-bit Solaris headers and libraries where:
$TARGET=sparc-sun-solaris2.10
$SYSROOT=/path/to/solaris32/includes
$PREFIX=/path/to/gcc-output
binutils-2.31/configure -target=$TARGET --prefix=$PREFIX -with-sysroot=$SYSROOT -v
gcc-8.2.0/configure --target=$TARGET --with-gnu-as --with-gnu-ld --prefix=$PREFIX -with-sysroot=$SYSROOT --disable-libgcj --enable-languages=c,c++,go -v
Create a symlink to gogcc and put GCC on the path
Compile a trivial test go program like this:
go build --compiler gccgo --gccgoflags "-m32 -O3 -static-libgo -Wl,-dy -lnsl -lsocket -lrt -lsendfile" -o ${GOTOOLS}/${BINARIES}/${PROJECT_NAME}/test/solaris_sparc32 test/main.go
This fails as follows:
go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags
command-line-arguments
gccgo: error: may not use both -m32 and -m64
Clearly I don't know what I'm doing. Can anyone point me in the right direction?
Solaris 32-bit does not appear to be supported, according to the list of supported OS/arch targets:
The valid combinations of $GOOS and $GOARCH are:
$GOOS $GOARCH
...
solaris amd64
...
That is, Solaris 64-bit is explicitly listed as a supported platform but Solaris 32-bit is not listed.
As such, there is good reason to believe that go programs will not run reliably on Solaris 32-bit systems and you probably should not agree to support that platform (if you do happen to get that cross compilation working) mainly because the go team itself does not support it!

Link a "toy" OS using llvm/clang

Is it possible (within reason) to build a "toy" OS on a mac using llmv/clang (and the other "normal" build tools)? By "toy" OS, I mean the simple, "Hello, World" examples found on OSDev (http://wiki.osdev.org/Bare_Bones) and x86 Bare Metal (https://github.com/cirosantilli/x86-bare-metal-examples).
My main problem is I can't figure out how to specify precisely where the linker should place the code (i.e., that the starting point should be 0x7c00, that bytes 510 and 511 need to be 0xaa55, etc.).
I would say yes it is possible within reason, at least if you consider waiting for a build of lld (and its dependency llvm) reasonable. Instructions to build lld can be found on their website or as part of this answer.
Compiling and linking for a different target than the host is relatively easy with clang. You just have to set a target, for example -target i386-none-elf for an ELF binary. Cross-compilation using clang is explained in more detail here.
As for macOS, as Micheal Petch noted, you have to use another linker than the standard ld installed. You could in theory install binutils to get an ELF ld but then you have to compile it yourself to set the target. My recommendation is to use lld which can target many architectures without the need to recompile.
With clang and a lld in place we can compile sources with
clang -c -o file.o file.c -target i386-none-elf # freestanding flags omitted
and then link them with
clang -o kernel.bin file.o -target i386-linux-elf -nostdlib -Wl,linkerscript.ld -fuse-ld=lld
Note that for linking I am using i386-linux-elf because there is a bug in clang where they just forward their input to gcc. But when using -nostdlib it is essentially the same.
If you want to see a complete example ready to build, you can take a look at https://github.com/Henje/x86-Toy-OS.

C compiler for mac?

I'm working through a text on linking, and wanted to work along with some examples in said text.
To better understand whats going on when I invoke the gcc driver, I was looking into doing all the compilation old-school by hand;
preprocessing using cpp
compiling with cc1
assembling with as
linking using ld
Unfortunately, on my Mac I don't seem to be able to reference cc1directly (no listing of cc1 in man). What are my options?
Read some material about GCC internals. First the wikipage on GCC. Then, you could play with the MELT probe (you may want a Linux system to use it).
Then read the GCC manual. And the GCC resource center
Use gcc -v -Wall to compile, it will show what cc1 is running (and -Wall is always useful). So try compiling with gcc -v -Wall hello.c -o helloworld.bin
the cc1 program don't sit in your PATH or in /usr/bin/ but -on my system- in /usr/lib/gcc/x86_64-linux-gnu/4.8/cc1
The command gcc -print-prog-name=cc1 will tell you which cc1 is used by your gcc. See GCC debugging options for more.
The preprocessing is now inside cc1.
The gcc program is just a driver, starting cc1 (which does most of the compiling work), then as, ld etc...
The MELT site contains some documentation, and some slides explaining GCC, which you could find interesting. MELT is a domain specific language to extend GCC.
See also the picture on http://starynkevitch.net/Basile/gcc-melt/cc1-internals.svg and the below picture
picture from http://starynkevitch.net/Basile/gcc-melt/gcc-MELT-inside.png, done by me, CC BY SA
The cc1 is producing a .s assembly file; the as (started by gcc) is transforming it into .o. The ld linker (started by gcc) will produce a library or an executable.
PS. I have a Linux system, but things are very similar on MacOSX.
reference on linking
A good book about linking is Levine's Linkers & loaders book.
PS. MELT is obsolete in 2021, but I am working on the Bismon static source code analyzer and on RefPerSys (which generates C++ code).
For reference, I installed gcc-10 with brew on my macOS (Catalina).
While cc1 is not directly accessible (via PATH), it can be found in
/usr/local/Cellar/gcc/10.2.0/libexec/gcc/x86_64-apple-darwin19/10.2.0
If you are lost, try gcc -v and from the verbose information you may find where your cc1 is.

Problem compiling gcc 4.4.0 on OpenSolaris 2009.6

I am attempting to compile gcc 4.4.0 on opensolaris 2009.6
Currently in the box (which is a AMD 64bit machine), I have the gcc 3.4.6 installed.
I unpacked the gcc 4.4.0 tarball.
I set the following env variables:
export CXX=/usr/local/bin/g++
export CC=/usr/local/bin/gcc
Then I ran "configure && make" and this is the error message that I got:
checking for i386-pc-solaris2.11-gcc... /export/home/me/wd/gcc/gcc-4.4.0/host-i386-pc-solaris2.11/gcc/xgcc -B/export/home/me/wd/gcc/gcc-4.4.0/host-i386-pc-solaris2.11/gcc/ -B/usr/local/i386-pc-solaris2.11/bin/ -B/usr/local/i386-pc-solaris2.11/lib/ -isystem /usr/local/i386-pc-solaris2.11/include -isystem /usr/local/i386-pc-solaris2.11/sys-include -m64
checking for suffix of object files... configure: error: in `/export/home/me/wd/gcc/gcc-4.4.0/i386-pc-solaris2.11/amd64/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details.
Anyone has any suggestion as to how to work around this error message?
/Edit:
Content of the config.log is posted here: link text
Normally the GCC build is bootstrapped, i.e. first it uses the system compiler to build GCC C compiler, and then it uses the freshly built compiler to recompile GCC once again (and then even once more time again). The configure line shows that it is not the system compiler but the already-built GCC compiler which is used for configure test there.
Since it fails, the problem is that the freshly-built GCC is somehow "stillborn" here. If config.log will not help you, I'd suggest to ask at gcc-help#gcc.gnu.org.
EDIT: Ah-ha, I think it is the assembler. You are using GNU assembler, but the unsupported options look like they were meant for Sun assembler. This should be solved by adding --with-gnu-as configure option (and then possibly having to specify its path explicitly with --with-as=/usr/gnu/bin/as)
You can also take a look at Solaris-specific GCC build instructions.
There's a readily available build for gcc4, which you can try updating. Its current version is 4.3.3. To get started, install pkg-get from OpenCSW and check out the build from the subversion repository:
svn co https://gar.svn.sourceforge.net/svnroot/gar/csw/mgar/pkg/gcc4/trunk/ gcc4
cd gcc4
gmake package

Resources