How to make a linux command-line program work in windows? - c++

I'm a beginner with programming, and I've been doing work in C/C++ in Ubuntu. When I tell something to cin/cout/cerr or printf/scanf or take arguments from the command line, this all happens from the linux terminal in Ubuntu.
Now if I want to run these same programs (very simple programs, beginner-level) and run them in Windows, how do I run them from the Windows command line? A previous course I've taken had us download cygwin to simulate the linux command line in windows, but what if I want to just run the program from the ordinary windows command line? Is that possible, and does it require modification of the software?

You can cross-compile the program for Windows from linux.
On Ubuntu, process is basically this:
sudo apt-get install wine mingw32 mingw32-binutils mingw32-runtime
...
i586-mingw32msvc-g++ -o myProgram.exe myProgram.cpp
Easy, right? Google for "ubuntu cross-compile windows," there's a ton of information out there.

It's exactly the same. You run cmd and write the command (almost) exactly as you would in Linux.
For example, if you build your program to program, you would run it in Linux like this:
./program --option1 -o2 file1 file2
And in Windows, first you have to make the output have a .exe suffix and then in cmd you would write:
program.exe --option1 -o2 file1 file2
Basically saying, cmd is Windows' terminal. It's nowhere near as good as the Linux terminal, but that would be all you get without installing additional software.
cin/cout/cerr and printf/scanf/fprintf(stderr, ...) use the standard C preopened files stdin, stdout and stderr which are defined both in Linux and Windows. Once you run the application from Windows' terminal (cmd), you see the input/output exactly as you would in the Linux terminal. I/O redirection is also very similar.

cin and cout, and printf and scanf, work much the same in Windows as they do in Linux. (I'm pretty sure cerr does too, but that one i'm not 100% sure about. At the very least, though, it's there and works.) The biggest difference is that Windows typically won't expand wildcards (stuff like *.txt) before running your program; you have to do that yourself in most cases.
Basically, as long as the app doesn't use anything specific to Linux or GCC, you could just recompile it on the target machine using whatever compiler you like to test.
If you don't want to recompile...well...good luck with that. Even Cygwin won't run native Linux binaries. You'd need a virtual machine with Linux on it.

Well, if you program is portable and not using any features specific to Linux, you would have to compile it from source on Windows to make it work on Windows.
You would need the GCC tool-chain for windows to do that, which you can get from the TDM-GCC homepage. Its MinGW internally and the installer allows you to choose the features you want to install as well as the target directory for installation. It also adds itself to Windows path so that the compiler commands are available from the shell prompt.
I have to do the cross compilation regularly and it works without any issues for me. There is one change which you must make if your project is using Makefiles. For the target binary, such as <target>.out in linux, you would have to edit your Makefile and rename it to <target>.exe so that it runs on the command line. If you are not using Makefiles and just doing gcc <file.c>, the a.exe is produced by default (similar to a.out in Linux).

Say you have this program code you want to run on UNIX and Windows:
#include <stdio.h>
int main()
{
printf("Hi\n");
return 0;
}
When you type a command in a UNIX shell it will be something like this.
/usr/home/bobby# gcc main.c
/usr/home/bobby# ./a.out
Hi
/usr/home/bobby#
On Windows you'd have to first choose your development environment/compiler. Without going to something like Cygwin, you could install the Windows SDK or Visual studio (although if the latter you might just want to develop in the GUI).
Start -> Run -> cmd /k ""C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" x86
C:\Windows\system32>cd c:\bobby
C:\bobby>cl main.c
C:\bobby>main.exe
Hi
C:\bobby>

When a C program is compiled into an executable this is done in a system dependent way. On Ubuntu the ELF format is used and on Windows we have PE.
When you start a process the ELF or PE is read giving instructions/map on how to allocate memory and where to put various pieces of the process in a virtual memory table. Further it links up to dynamically loaded libraries, already in physical memory, that it share with other processes which is using the same libraries. Or if the dynamic libraries is not present load them. (Linux .so, windows .dll). If it has static libraries these are allocated and linked in (Linux .a, Windows .lib). - Very simplified.
Memory restrictions etc are inherited from previous process.
Environment variables are put into the running environment for the process. This being paths, arguments, etc. Then main() is added to the stack and called.
Now everything happening before main is called and how linkage etc are resolved, and so many other things, depends on the system. This is why one simply can't run an executable compiled on Linux on Windows.
Using cygwin one is simply creating a virtual environment where those linkages etc are the same and would work. One create an ELF environment.
To get it linked for native Windows command line one would have to compile for Windows. On that matter I see there is lots of answers already.
The ELF and PE, as on different systems, also have different ways of handling environment variables etc. What these are etc. So i.e. file expansion is handled differently. However both running processes has the default streams like stderr, stdout and stdin. But below your code in C they are not the same.
It is like driving a diesel vs a petrol car. Much is the same but under the hood quite a few things is different.
Be aware that i.e. signals are handled different on Windows.

Related

Windows executable got executed on my linux

I wrote a simple code and compiled using g++ in linux in .exe format, suprisingly it got executed in my linux terminal. Can u say the reason for this ? Can linux terminal execute machine code in any format ? Can I run the same in windows ?
Code :
#include<iostream>
using namespace std;
int main(){
cout<<"Hello World !"<<endl;
return 0;
}
Compile code:
g++ main.cpp -o program.exe
OS: Linux Mint 20 Cinnamon.
I execute by typing ./program.exe
Q: I wrote a simple code and compiled using g++ in linux in .exe format, suprisingly it got executed in my linux terminal
A: There's nothing "surprising". I assume you compiled it under Linux? So why shouldn't you be able to run it under Unix?
Q: Will an .exe I build on Windows run on Linux (if I copied the binary)? A: Short answer: No.
Longer answer: you can install Wine to run Windows applications on Linux.
Q: Will an .exe I build on Ubuntu run on Windows? A: No.
Q: Does an executable I build on Ubuntu need to have the suffix .exe? A: No. File suffixes are irrelevant.
Q: Does an executable I build on Windows need to have the suffix .exe? A: Yes.
To answer your additional questions:
There are many reasons why an .exe built for one platform cannot load or run on a different platform.
Sam Varshavchik put it well:
It's for the same reason a radiator for your Toyota won't fit into a
Dodge
More to the point, an "executable image" is much more than just "the machine code".
An .exe is an example of "executable images". They come in many different formats: https://en.wikipedia.org/wiki/Category:Executable_file_formats. Most of these formats are platform-specific.
Any image must be loaded by the operating system in order to become a running process. This, too, is platform-specific.
The running process will need resources like file I/O , memory and shared libraries, which are also platform-specific.
I hope that helps...
Since you compiled the code using g++ on Linux, you should be able to run it on Linux but it won't work on Windows because the binary executable is compiled for Linux.
On Windows, .exe is the extension of the executable file but the binary code must be compiled for Windows so that it can run. On Linux, you can use any extension, .mp4 or anything and it will still run when typing ./program.mp4 in terminal.

VS2017 - How to configure project for remote debugging

I want to create an MP3 player on my Raspberry Pi (OS: Raspbian). The problem is, that i don't have any experience with Linux programming, and I'm having a huge problem with project configuration, becouse of cross platform compiling. I want to add two liblaries:
mpg123
libao
I'm able to compile the code on linux machine with gcc -O2 test.cpp -lmpg123, but I can't force Visual Studio to make see those libs.
I'm also having a problem with using wiringPi lib while I'm trying to remote debugging my program, since I have to run it as root for GPIO configuration. Is there any way for any way to force Visual Studio to run my compiled code with root privilages?
Personally I come from a long history of C/C++/MFC/Windows programming with no Linux experience at all. I started programming for the Raspberry a year or so ago, when I got one from my son for my birthday. With a C/C++ history it's really not that hard, but you just have to read in a bit because on Linux a lot is the same, and a lot isn't :). Just read and read and in time, you're an experienced Linux programmer! It takes some time I'm afraid.
So, I'm sort of an experienced newbie on this I think :). I found a lot of info on www.die.net (and other Linux man pages). If you search there for a function, say printf(), look at the (3) pages - they explain how you should use 'm.
But although VS2017 does a really good job on this, it's not always going as smooth as you would like. Sometimes it's just necessary to reboot your Raspberry, restart VS and try again. The Linux cross-compiling is quite new in VS and isn't perfect yet.
A few tips:
Use a Raspberry with a fresh Stretch image to start with. Of course after a sudo apt-get update && sudo apt-get -y upgrade.
Set the debugger in Visual Studio to gdb instead of gdbserver. This will prevent certain debugging problems.
Place all your source files (.h and .cpp) in the main folder of your project alongside the main.cpp. If you place them in different directories and then include in your project, you can debug your program but you won't be able to step through.
Start simple and debug your program often when you're developing. Don't add too much code before your next check. In a cross-compile setup there are just a lot more things than normal that can (and will) go wrong.
VS2017 has default Linux include files in C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\Linux\include. If you need others, place them in a folder of you own and include the path.
With cross-compiling VS itself doesn't do any compiling, you use it to maintain your project. When the project has to be compiled, all necessary files are copied to the Raspberry and the compiler and linker there are invoked by VS.
On your question how to configure a project for remote debugging: it's probably best to start with the Blink example in Visual Studio 2017 (File, New, Project, Installed, Visual C++, Cross Platform, Linux => Blink). It should run without problems. From there, you can build further on your project.
In the Blink example, they use wiringPiSetupSys() and the remote command gpio export 17 out to run your program without sudo. I've found that changing that to wiringPiSetup() and disabling the remote command, it still is possible to run and debug the program. On the Raspberry I can run the program from it's folder by issuing ./[programname]. If that doesn't work for you, you could run the program by issuing sudo ./[programname].

Compile C++ code under windows for linux, as ready to run

Im new about compile code for linux. It's propably Debian 5.0. And I need compile my cpp code for it as ready to run, i mean the other person can easly run program like in Windows, by just clicking on it.
Anybody can help?
I use virtualbox for this. It's easy and convenient. You can run multiple Linux distros and multiple versions of Windows provided you have the proper licenses. You can also run subversion, etc on each virtual machine so that you can sync your changes across all of them when building.
Assuming you want to be able to compile something on Windows and have it work on any Linux machine, that's simply not possible. Debian and Ubuntu both support many architectures, many of which have absolutely no binary compatibility. If you know what type of hardware your friend has you can build a binary targeted to that architecture.
If you want a quick and dirty answer, you can build for i386 since a 64bit machine can probably still run it fine (not guaranteed though).
Once you compile it, you can easily create a shortcut on the Desktop -or add an entry on a menu- to launch your program via a script; something like:
#!/bin/bash
/path/to/your/progam
Save it as launch.sh -for example- and give it ugo+x permissions as such
chmod ugo+x launch.sh
When you create the shortcut, you can associate a icon to your script exactly in the same way you do it in Windows.
UPDATE
If you are sending the compiled program to your friend (let's assume via email). You can simply instruct your friend to launch the terminal window in the same directory where he downloaded your file and run the following:
chmod ugo+x your_program
./your_program
Or you can send him 2 files: one with your program and one with a "launch" script as I described above. Since both files will be downloaded to the same directory, you can change your launch script to:
#!/bin/bash
./your_program
When he clicks on launch.sh, your program will be executed.

running unix like command "./a.out <data.txt" in windows environment on c++ file

How do I run a command like interface on windows and use the g++ and ./a.out
I am a beginning programmer used to using putty/ssh to write (nano), compile (g++ command), and run (./a.out) c++ programs.
Our class has now switched to netbeans, but our latest assignment requires us to use the ./a.out <datafile.txt-like command.
Or is the input redirection style ./a.out <data.txt unique to unix and cannot be done in windows?
edit: the < input redirection marks made my post mostly unreadable. Sorry about that
2nd edit: There is actually a terminal built into netbeans that VERY conveniently starts in your project directory. open it in netbeans by selecting Window -> output -> Terminal
Cygwin is a collection of tools which provide a Linux look and feel environment for Windows.
start,
run,
cmd,
cd directory,
g++ a.cpp,
a.exe
Windows includes . in $PATH, so the ./ at the beginning is superfluous (and wrong, since it would be .\). The rest is the same.

I have a flash drive and I want to compile everywhere

I came from gnu/linux world but recently I must to work on a windows system and I want to be able to compile my c/c++ console programs on it. The problem is I don't have administrative privilegies to install anything.
I looked for portable apps. I'd find gvim and mingw but I don't know how to make them work together on a flash drive. I'd found also a vim plugin called msysportable that's supposed to do the job but I don't know how.
So my question is: how can I make a portable windows c/c++ development environment using gvim?
(don't tell me to use code::blocks or visual studio, I've this installed but I want vim)
copy your development environment to your flash-drive. Create a batch file to setup environment variables for paths to include dirs ,lib dirs ,executables ,etc. Then use this environment in cmd session with console commands. If you have installed MSVC on your own system then there is a batch-file called vcdirs.bat thar does this on youre system, Take it as example how to make a portable environment. By the way ,INSTALLING youre tools at a vlient-site may be a license violation. The portable environment is not as long as you do not install it.