I just built a cross compiler using crosstools "mips-unknown-linux-gnu-gcc" and I compiled a hello world program. The compilation went fine using the command: "mips-unknown-linux-gnu-g++ hello.cpp -o hello" but when I run the command "./hello" I get the following error:
babbage-dasnyder 50% mips-unknown-linux-gnu-g++ hello.cpp -o hello
babbage-dasnyder 51% ./hello
./hello: Exec format error. Wrong Architecture.
Why is this? Did I make the wrong cross-compiler? I'm running this on a linux machine.
Just as a note, crosstools did say it could run a trivial program:
+ /home/seas/grad/dasnyder/opt/crosstool/gcc-3.4.5-glibc-2.3.6/mips-unknown-linux-gnu/bin/mips-unknown-linux-gnu-gcc -static hello.c -o mips-unknown-linux-gnu-hello-static
+ /home/seas/grad/dasnyder/opt/crosstool/gcc-3.4.5-glibc-2.3.6/mips-unknown-linux-gnu/bin/mips-unknown-linux-gnu-gcc hello.c -o mips-unknown-linux-gnu-hello
+ test -x /home/seas/grad/dasnyder/opt/crosstool/gcc-3.4.5-glibc-2.3.6/mips-unknown-linux-gnu/bin/mips-unknown-linux-gnu-g++
+ cat
+ /home/seas/grad/dasnyder/opt/crosstool/gcc-3.4.5-glibc-2.3.6/mips-unknown-linux-gnu/bin/mips-unknown-linux-gnu-g++ -static hello2.cc -o mips-unknown-linux-gnu-hello2-static
+ /home/seas/grad/dasnyder/opt/crosstool/gcc-3.4.5-glibc-2.3.6/mips-unknown-linux-gnu/bin/mips-unknown-linux-gnu-g++ hello2.cc -o mips-unknown-linux-gnu-hello2
+ echo testhello: C compiler can in fact build a trivial program.
testhello: C compiler can in fact build a trivial program.
+ test '' = 1
+ test '' = 1
+ test '' = 1
+ test 1 = ''
+ echo Done.
Done.
Just as a note, crosstools did say it could run a trivial program:
testhello: C compiler can in fact build a trivial program.
When you cross-compile to a different architecture, you are generating instructions for the new architecture and thus you may not be able to run these instructions on your current architecture. You are cross-compiling to be able to compile the code on a more powerful machine and then transfer it to the device for testing. If you are wanting to test the code directly on your machine you need to compile with your native architecture's compiler.
Related
Let's say we have a simple c++ file named hello.cpp which prints "Hello World!".
We generally create the executable using g++ hello.cpp. When I tried executing the command c++ hello.cpp it creates the executable successfully. Shouldn't it throw an error saying there is no c++ command available? and suggest us to use g++?
I tried running man c++ on the terminal, this brings up the GNU C Project page. So, does the terminal replace our c++ hello.cpp with g++ hello.cpp internally? It shouldn't do that right?
Additional Info:
Similarly, if I have a hello.c program that prints "Hello World!". When I execute c hello.c on the command line, I get the error:
$ c hello.c
c: command not found
This is expected since we have to use gcc hello.c. Why am not getting a similar error for the c++ hello.cpp?
On my Ubuntu system, I see this:
$ ls -l /usr/bin/c++
lrwxrwxrwx 1 root root 21 May 6 2019 /usr/bin/c++ -> /etc/alternatives/c++
$ ls -l /etc/alternatives/c++
lrwxrwxrwx 1 root root 12 May 6 2019 /etc/alternatives/c++ -> /usr/bin/g++
So c++ is actually an alias (symbolic link) to g++
The alternatives system allows changing what compiler c++ is an alias to:
$ update-alternatives --display c++
c++ - auto mode
link best version is /usr/bin/g++
link currently points to /usr/bin/g++
link c++ is /usr/bin/c++
slave c++.1.gz is /usr/share/man/man1/c++.1.gz
/usr/bin/clang++ - priority 10
/usr/bin/g++ - priority 20
slave c++.1.gz: /usr/share/man/man1/g++.1.gz
So c++ could actually be either g++ or clang++
For a C compiler, you don't want the c command, but cc, which again, could be either gcc or clang.
My CentOS system isn't quite so obvious with the symlinks, but g++ --version and c++ --version give the same output and both say they are g++. However, cc is a direct symlink to gcc there.
Shouldn't it throw an error saying there is no c++ command available? and suggest us to use g++?
Weeelll, there are no regulations or standards that restrict or require c++ command to do anything, so there is no "should" or "shouldn't". However, it would be strongly expected that c++ is a working C++ compatible compiler, that supports similar or same flags as cc does.
does the terminal replace our c++ hello.cpp with g++ hello.cpp internally?
A terminal is the device that displays things. Terminal does not replace it, it has no effect on it.
Most probably your system designer, but maybe administrator or publisher or distributor or package designer (or anyone in the chain), configured your system to provide a command named c++. Usually, that command is a symbolic link to a working C++ compiler, usually g++ on Linux systems. On my system, /usr/bin/c++ program is just installed with package named gcc, but some systems allow it to be configurable.
It shouldn't do that right?
As stated above, terminal shouldn't replace commands, it has no effect on it.
This is expected since
It is expected since there is no command named c. There are endless other unknown commands.
cc is the good old name for a C compiler. c99 is the standardized name of C99 compatible compiler.
Why am not getting a similar error for the c++ hello.cpp?
Because a command named c++ exists on your system.
I am using Ubuntu(latest). If I have a test.cpp file in my home directory, I write two commands in terminal to compile and run this file.
prateek332#pp-pc:~$ g++ test.cpp
prateek332#pp-pc:~$ ./a.out
Is there a way to write these two command simultaneously (or maybe even a better way). I used pipelining but it doesn't work.
prateek332#pp-pc:~$ g++ test.cpp | ./a.out
This doesn't work. It doesn't compile to new changes in test.cpp file, instead just runs the old code in file.
g++ test.cpp && ./a.out
First compile and then, if it was successfull, run the code.
You can create a shell function since this is something you will do often.
In ~/.bashrc (or whatever your shell config is like ~/.zshrc)
function cpp() { g++ $1 && ./a.out; }
Now you can just type
cpp test.cpp
You can name the function whatever you want. Open a new shell window to load the function (or run source ~/.bashrc).
I have some C++ code that has been running fine for a long time now. I just upgraded my Mac to macOS Catalina and now about 50% of the time when I compile, it runs fine and 50% of the time when I compile and then run I get
sh: ./file: Input/output error
I can compile no problem. The issue is on executing the file.
I'm compiling with g++ -std=c++11 -I ext/ file.cpp -o file -ffast-math -O3 -DEIGEN_STACK_ALLOCATION_LIMIT=0
I have no idea what's going on or how to fix this. I can run everything else seemingly fine.
EDIT
When I run ls -l I get
-rwxr-xr-x 1 NAME staff 12872 Feb 27 15:21 ./file
And file ./file returns
./compilation_tests/runnable_c_files/3D_P1_non_zero/1/3D_P1_non_zero2: Mach-O 64-bit executable x86_64
The really weird thing is that now when I run the first time I get the same Input/output error. However, no matter what, the second time I run it goes perfectly. Further, if I recompile, it works the first time I run.
BUT...when I put this into a python script (using os.system to run shell commands) it never works. I need to compile and run twice from my terminal.
EDIT #2
I've run a simple hello world and am encountering the same bug. The code is:
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
cout << "Hello world!" << endl;
return 0;
}
I compile with g++ -std=c++11 test.cpp -o test -ffast-math -O3 -DEIGEN_STACK_ALLOCATION_LIMIT=0 and permutations thereof (mixing flags etc).
And about 50% of the time I am getting the same error. Is this just a hardware issue?
I have no clue what's going on.
I'm learning C++ and trying to run a simple hello world program. It compiles but it won't execute. It worked on Windows, but it won't run on Zorin OS.
I read online that the command to run it is ./test or ./test.exe.
This is what is looks like on the terminal:
$ g++ test.cpp -o test.exe
$ ./test
bash: ./test: No such file or directory
I looked at the questions similar to this, but none have helped me.
You can not expect to be able to execute the same commands on both Windows and Linux. They use different shells with different syntax and different behaviors.
Here's a typical example of compiling a file on GNU/Linux:
dir$ g++ myfile.cpp -o myfile
dir$ ./myfile
Here's a typical example of compiling the same file on Windows:
dir> g++ myfile.cpp -o myfile.exe
dir> myfile
Note in particular:
Linux doesn't use .exe or other extensions on executables, but Windows does.
Windows doesn't require specifying directory to run files in the working directory, but Bash on GNU/Linux generally does.
The only reason why the compilation command is as similar as it is is that g++ is a Unix tool ported to both platforms. Windows normally uses / instead of - for flags like -o
As commands get more complex, they start diverging even further.
I've come across a weirdest problem I ever met. I'm cross-compiling an app for ARM CPU with Linux on-board. I'm using buildroot, and all goes well until I'm trying to run the application on the target: I'm getting -sh: ./hw: not found. E.g.:
$ cat /tmp/test.cpp
#include <cstdio>
#include <vector>
int main(int argc, char** argv){
printf("Hello Kitty!\n");
return 0;
}
$ ./arm-linux-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw
load the executable to the target; then issuing on the target:
# ./hw
-sh: ./hw: Permission denied
# chmod +x ./hw
# ./hw
-sh: ./hw: not found
# ls -l ./hw
-rwxr-xr-x 1 root root 6103 Jan 1 03:40 ./hw
There's more to it: upon building with distro compiler, like arm-linux-gnueabi-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw, the app runs fine!
I compared executables through readelf -a -W /tftpboot/hw, but didn't notice much defference. I pasted both outputs here. The only thing I noticed, are lines Version5 EABI, soft-float ABI vs Version5 EABI. I tried removing the difference by passing either of -mfloat-abi=softfp and -mfloat-abi=soft, but compiler seems to ignore it. I suppose though, this doesn't really matter, as compiler doesn't even warn.
I also thought, perhaps sh outputs this error if an executable is incompatible in some way. But on my host PC I see another error in this case, e.g.:
$ sh /tftpboot/hw
/tftpboot/hw: 1: /tftpboot/hw: Syntax error: word unexpected (expecting ")")
sh prints this weird error because it is trying to run your program as a shell script!
Your error ./hw: not found is probably caused by the dynamic linker (AKA ELF interpreter) not being found. Try compiling it as a static program with -static or running it with your dynamic loader: # /lib/ld-linux.so.2 ./hw or something like that.
If the problem is that the dynamic loader is named differently in your tool-chain and in your runtime environment you can fix it:
In the runtime environment: with a symbolic link.
In the tool-chain: use -Wl,--dynamic-linker=/lib/ld-linux.so.2