I've used this guide to set-up cross-compiler in Linux for Windows binaries:
http://wiki.codeblocks.org/index.php/Code::Blocks_and_Cross_Compilers
Simple programs works and generates .exe files as expected. However when I try to use specific Windows.h functions - no reasonable results.
For example Code:
int main()
{
Beep(1000, 1000);
MessageBeep(MB_OK);
return 0;
}
Don't produce system beep sound neither MessageBeep() works. Any suggestions ?
EDIT:
Output from nm
Output from objdump
I don't know is it related, but also when I execute this binary on my Linux system I get some warning on console:
fixme:msvcrt:MSVCRT__wsopen_s : pmode 0x01b6 ignored
Related
Under Cygwin: How can I stop output from msvc compiled programs from being transcoded in the tty.
Under Cygwin: gcc vs msvc compiled programs appear to run differently to each other under a tty. Specifically, I am seeing some strange character set translations from only msvc generated binaries output under a tty when the character's 8th bit is set. I'd really like to know how to turn off this annoying behaviour please. Consider:
screen-cap of terminal output (duplicated in a code quote below)
! pwd
/tmp/demo_dir
! echo $LC_ALL "," $LANG "," $LC_CTYPE
, ,
! ./compiled_with_gcc.exe | hexdump
0000000 cece cece
0000004
! ./compiled_with_msvc.exe | hexdump
0000000 cece cece
0000004
! ./compiled_with_gcc.exe
▒▒▒▒!
! ./compiled_with_msvc.exe
╬╬╬╬!
The problem is the last line. The output from the msvc compiled version is not as expected. The two programs are demonstrated above to be outputting the same data: so the last two outputs should be the same. But the tty version (without the pipe) gets changed in only the msvc case. gcc compiled program outputs are passed through the tty unharmed. The output presented here is from the cygwin terminal, but I see exactly the same output difference in xterm.
I am confident it is happenning in the tty not the terminal: because I written a standalone cygwin program in C that runs either the gcc and msvc compiled programs, either under a pipe or under a tty that is not connected to a terminal. The program logs the actual bytes received from the tty.
When running the gcc compiled one, the tty gives the '0xce's bytes as expected.
But a sequence of '0x8ec3' patterns is instead received from the msvc compiled program when listening to it via an identical tty.
When using a pipe instead of a tty, they both output '0xce's.
This notes that the msvc compiled program's output via a tty has an increased width. Given cygwin's preference for UTF-8: it is easy to suspect something is going wrong here and cygwin is causing an extra transcoding that does not happen with gcc compiled programs. I wish to turn that off... How do I successfully disable UTF-8 translations in todays cygwin.
I note that LC_ALL does not appear to be respected to stop this happenning for msvc compiled binaries accessed via a tty. Even when the C program begins with setlocale(0,"");
The output-generating program (to be alternately compiled with the two compilers for the test) is exactly as you'd expect it to be. The same C source in both cases. It simply calls printf or write with some bytes. The msvc version is compiled with Visual Studio 2019 cl.exe (all running on Windows10).
reproduce with:
#ifndef __CYGWIN__
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <io.h>
#include <fcntl.h>
#include <locale.h>
int main()
{
if(!setlocale(LC_ALL, "")) {
return 77; //historically: non-filesystem permission-denied exit-code
}
#ifndef __CYGWIN__
//Irrelevent: But avoids stackexchange users asking for it.
_setmode(1,_O_BINARY);
_set_fmode(_O_BINARY);
#endif
char *dat="\316\316\316\316";
write(1,dat,4); // printf/fflush here gives same results.
return 0;
}
#echo off
:: ugly msvc build script. ms_cl.bat
:: full of M$ hardcoded paths. Likely includes some unused libraries.
:: Load compilation environment
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
:: Invoke compiler with any options passed to this batch file
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30037\bin\Hostx64\x64\cl.exe" /std:c17 %* kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Build msvc version with:
! ms_cl.bat code.c
Run in terminal with:
! ./code.exe | hexdump
! ./code.exe
Build gcc version with:
! gcc code.c
Run in terminal with:
! ./a.exe | hexdump
! ./a.exe
Note identical programs, with identical output in a hex, have output transcoded differently. The msvc one being 'wrong' in my usage case.
I obviously, suspected M$ was doing some translation: so I have tried every combination of _fmode setmode() and more to set binary mode. I suspected some failed cygwin UTF-8 detection situation, so tried setting LC_ALL etc. to plain "C" mode with export in the shell. I similarly tried setting the locale within the msvc source.
Cygwin does a lot of work to make a unix-like environment under windows. Given the hexdumps above I can only guess Cygwin (or some hidden msvc console layer) are doing something quite specialised here and getting in my way. It maybe related to cygwin's migration to ConPty. Either way. I'd like help turning it off.
OP: It's been a little while. And the problem presented in the question presently remains unsolved. However, I have discovered a hacky hack hack from the planet hack that allows for avoiding the problem without solving it. I am posting this non-answer problem-avoidance-hack as an answer and will (eventually) mark it as the solution.. But only if no actual solutions to the problem can be found..
To avoid the output of msvc-compiled program from being transcoded in the tty: first pipe the output of the msvc-compiled program to a gcc compiled program that simply repeats it (such as 'cat' or 'tail -f') and connect that gcc-compiled program to the tty instead.
This hides whatever is going on in the msvc case by seperating it from the tty. The environment is then respected. The tty only knows it is connected to a gcc-compiled program -and works right.
! ./compiled_with_gcc.exe # gcc_compiled->tty = good
▒▒▒▒!
! ./compiled_with_msvc.exe # msvc_compiled->tty = bad
╬╬╬╬!
! ./compiled_with_msvc.exe|cat # msvc_compiled->gcc_compiled->tty = hacky but good
▒▒▒▒!
This question already has an answer here:
gcc compiler in Cygwin output .exe
(1 answer)
Closed 5 years ago.
When I compile below "hello_world.c" through cc hello_world.c,
it makes an 'a.exe' instead of 'a.out'
#include <stdio.h>
main()
{
printf("hello, world\n");
}
What is a difference between "a.out" and "a.exe" ?
Why I get an "a.exe" instead of "a.out" ?
That depends on your platform. For example gcc will produce .out on linux, and .exe on windows if you don't give it any additional parameters. (i.e. run cc / gcc "source").
You can force gcc to produce a .out on windows with gcc "source" -o "dest.out".
If your compiler outputs one extension by default (in your case it seems that .exe is the default which is perfectly OK for Windows), I would stick with it. No need to worry about not getting the other type.
Binary executing files in Windows have extension exe. I am not sure about com-files supporting, but it is not our case. Extension out usually uses for writing a text protocol when some program is working. I could guess that it is your program itself, being launched, creates out-file. For more help, provide at least what program environment is used to compile your C-program.
a.out temporary file that is created after compilation of a c program is actually an Object Code for Unix-like operating systems. Object code is used for writing system calls which implements the code functionality and relocation information for linker to help it find the object code in memory(more info here).
Compiler compiles the code and writes a file known as object code and in linux/unix the file is known as a.out.
This file can be further linked to definitions(OR more technically libraries) present in the operating system to form the executable image.
For example in Windows :
Should a daemon on an embedded device using Busybox be written in C or as a script?
All the examples I have seen use #! /bin/ash at the top of the file and that is for scripting? But in the device I'm writing to has only complied C files (I think) and symbolic links in /usr/bin.
Every way I try to compile a C file with #include </bin/ash> (e.g. gcc -Wall -o daemon_busybox daemon_busybox.c) I get error after error report in /bin/ash:
/bin/ash:174:1: error: stray ‘\213’ in program
/bin/ash:174:1: error: stray ‘\10’ in program
/bin/ash:174:1: error: stray ‘\273’ in program
/bin/ash:174:1: error: stray ‘\204’ in program
/bin/ash:174:1: error: stray ‘\342’ in program
Note I have set this: /bin/ash -> busybox
Any ideas which way I should go?
Update:
I've been given the task trying to see if a daemon can be run on a small device that runs Linux (2.6.35-at-alpha4) and Java (SE Embedded Runtime Environment) with very limited memory (i.e. a 10 second wait to get java -version to report back).
Two weeks ago I didn't know much about daemons — only knew the word. So, this is all new to me.
On my development machine I have built two different daemon files, one in C and one as a script. Both run very nicely on my Linux machine.
But because of the very small size of the target device there is only busybox (no /lib/lsb/init-functions). So I'm trying to build a 3rd daemon file. I believe it should be written in C for this device, but all examples for busybox point to scripting.
Once your question is edited so that the file name you're trying to #include is visible, the problem becomes self-evident:
#include </bin/ash>
This tries to make the C compiler include the binary of busybox (via the symlink /bin/ash) into the code to be compiled. The average binary is not a valid C source file; this is doomed to failure.
Perhaps you simply need to drop that line — the C compiler stands a better chance of working if it is given header files and source files to compile. Maybe there's more work needed; we don't have enough information to help there.
Many daemons are written as C programs, but a carefully written shell script could be used instead.
Personally, I would like to do this as a script (I've never liked C). But on the device everything in the /usr/sbin folder looks like a C file. So, the conservative coder in me says C is the way to go. I know: ask the guys developed the device — but they're long gone. Right now my daemon is just a test (i.e. printf("Hello World\n"); ). I'm trying to get printf passed to Busybox. But so far I cannot get this file to compile. I just need a simple daemon in C to start.
OK; your C code for that should be just:
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
return 0;
}
Save it in hw_daemon.c. Compile it using:
gcc -o hw_daemon hw_daemon.c
If that won't compile, then you've not got a workable C development environment for the target machine. If that will compile, you should be able to run it with:
./hw_daemon
and you should see the infamous 'Hello World' message appear.
If that does not work, then you can go with the script version instead, in a file hw_script.sh:
#!/bin/ash
printf "Hello World\n"
You should be able to run that with:
Predicted output — not output observed on a machine.
$ ash hw_script.sh
Hello World
$ chmod +x hw_script.sh
$ ./hw_script.sh
Hello World
$
If neither of those works at all, then you've got major problems on the system (maybe Busybox doesn't provide a printf command workalike, for example, and you need to use echo "Hello World" instead of the printf).
Looking into learning C. As I understand it when I say #include <stdio.h> it grabs stdio.h from the default location...usually a directory inside your working directory called include. How do I actually get the file stdio.h? Do I need to download a bunch of .h files and move them from project to project inside the include directory? I did the following in a test.c file. I then ran make test and it outputted a binary. When I ran ./test I did not see hello print onto my screen. I thought I wasn't seeing output maybe because it doesn't find the stdio.h library. But then again if I remove the greater than or less than signs in stdio the compiler gives me an error. Any ideas?
I'm on a Mac running this from the command line. I am using: GNU Make 3.81. This program built for i386-apple-darwin10.0
#include <stdio.h>
main()
{
printf("hello");
}
Edit: I have updated my code to include a datatype for the main function and to return 0. I still get the same result...compiles without error and when I run the file ./test it doesn't print anything on screen.
#include <stdio.h>
int main()
{
printf("hello");
return 0;
}
Update:
If I add a \n inside of the printf it works! so this will work:
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
Your code should have preferably
printf("hello\n");
or
puts("hello");
If you want to know where does the standard header file <stdio.h> comes from, you could run your compiler with appropriate flags. If it is gcc, try compiling with
gcc -H -v -Wall hello.c -o hello
Pedantically, a standard header file is even not required to exist as a file; the standard permits an implementation which would process the #include <stdio.h> without accessing the file system (but e.g. by retrieving internal resources inside the compiler, or from a database...). Few compilers behave that way, most really access something in the file system.
If you didn't have the file, you'd get a compilation error.
My guess is the text was printed, but the console closed before you got the chance to see it.
Also, main returns an int, and you should return 0; to signal successful completion.
#include <header.h>, with angle brackets, searches in standard system locations, known to the compiler-- not in your project's subdirectories. In Unix systems (including your Mac, I believe), stdio.h is typically in /usr/include. If you use #include "header.h", you're searching subdirectories first and then the same places as with <header.h>.
But you don't need to find or copy the header to run your program. It is read at compilation time, so your ./test doesn't need it at all. Your program looks like it should have worked. Is it possible that you just typed "test", not "./test", and got the system command "test"? (Suggestion: Don't name your programs "test".)
Just going to leave this here : STILL! in 2018, December... Linux Mint 18.3
has no support for C development.
innocent / # cc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # gcc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # apt show libc6
(Abbreviated)::
Package: libc6
Version: 2.23-0ubuntu10
Priority: required
Section: libs
Source: glibc
Origin: Ubuntu
Installed-Size: 11.2 MB
Depends: libgcc1
Homepage: http://www.gnu.org/software/libc/libc.html
Description: GNU C Library: Shared libraries
Contains the standard libraries that are used by nearly all programs on
the system. This package includes shared versions of the standard C library
and the standard math library, as well as many others.
innocent / # apt-get install libc6-dev libc-dev
So, magic... and a minute later they are all installed on the
computer and then things work as they should.
Not all distros bundle up all the C support libs in each ISO.
Hunh.
hardlyinnocent / # gcc ThoseSorts.c
hardlyinnocent / # ./a.out
20
18
17
16
... ... ...
When I am running below code in Code::Blocks in Windows OS.
I used to get an error called undefined reference to fork().
I did set/choose GCC compiler as my default compiler.
#include<stdio.h>
#include<unistd.h>
void main()
{
int x;
x = 0;
fork();
x = 1;
...
....
}
Please help me and tell me, can I right unix/linux programs in Code::Blocks in windows environment?
And I write another program,
main()
{
int x = 0;
if(x == 0)
{
printf("X = %d", x);
sleep(1000);//used delay also
x = 1;
printf("Now X = %d", x);;
}
}
Here it gives eroor that undefined reference to sleep() and / * delay also* /.
Please help me.
No, you can't write Unix code on Windows like that, no matter what IDE you use. However, you should try cygwin, and that should provide the compatibility layer you need.
2017 update: These days we also have Windows Subsystem for Linux.
There is no fork system call on Windows.
fork() is a unix system call, so it will definitely produce an undefined reference when you do this in windows OS. Windows does not support fork().
You try using cygwin Also I am not sure, but there's this equivalent called system call spawn() in ms-dos environment. you may try using that.
There is no fork() system call in windows, instead you can try cygwin or pthreads.
I also struggled a bit with this, install Cygwin from https://www.cygwin.com/
Make sure you check gcc-core and gcc-debug info packages from the package window.
Install the packages from the internet, then change the default Compiler to Cygwin GCC from the codeblock as demonstrated below
Confirm whether the Compiler installation directory is well placed, if not, click Autodetect button as shown below: