I would like to cross compile my C code to other platforms, is there a way to cross compile it on everything ("everything" in here being everything that could support C), If my code is only using standard library headers?
(preferably I would like to not have to include any platform specific includes)
I tried compiling normal code using clang from linux to windows, but there were some problems
(
fatal error: 'stdlib.h' file not found
#include <stdlib.h>
)
Related
I was porting a project to Windows using mingw32 and the project depends on a library called libfec. Libfec has a lot of assembly code to optimize the inner workings. In Linux (with GCC 5.4) the library compiles fine. Today I tried to compile it on windows using mingw32 (with as well gcc 5.4) and I got this error:
as -o mmxbfly27.o mmxbfly27.s
mmxbfly27.s: Assembler messages:
mmxbfly27.s:10: Warning: .type pseudo-op used outside of .def/.endef ignored.
mmxbfly27.s:10: Error: junk at end of line, first unrecognized character is `u'
make: *** [mmxbfly27.o] Error 1
The warning about .type happens in Linux as well, but the Error doesn't. I checked the binutils and they're actually different (on linux it was 2.26 and in mingw was 2.25) but the code of libfec is a bit old (few years) and its compilable even with binutils 2.0.
I'm not sure why I can't compile this on windows. The full code is here:
https://github.com/quiet/libfec/blob/master/mmxbfly27.s
I asked a friend that has experience with compilers, and he couldn't find a problem in the code (and it does compile fine in linux).
Ok so the solution was really simple: just comment the .type directive. The PECOFF doesn't need that. Now I'm able to compile and run just fine.
I know how to compile a C application without linking any library using GCC in bare metal embedded application just setting up the startup function(s) and eventually the assembly startup.s file.
Instead, I am not able to do the same thing in Windows (I am using MINGW32 GCC). Seems that linking with -nostdlib removes also everything needed to be executed before main, so I should write a specific startup but I did not find any doc about that.
The reason because I need to compile without C std lib is that I am writing a rduced C std lib for little 32 bits microcontrollers and I would like to test and unit test this library using GCC under Windows. So, if there is an alternative simplest way it is OK for me.
Thanks.
I found the solution adding -nostdlib and -lgcc together to ld (or gcc used as linker). In this way the C standard lib is not automatically linked to the application but everything needed to startup the application is linked.
I found also that the order of these switches matters, it may not work at all, signal missing at_exit() function or work without any error/warning depending by the order and position of the options.
I discovered another little complication using Eclipse based IDEs because there are some different approaches in the Settings menu so to write the options in the right order I needed to set them in different places.
After that I had a new problem: I did not think that unit test libraries require at least a function able to write to stdout or to a file.
I found that using "" and <> forces the compiler and linker to use the library modules I want by my library and the C standard library.
So, for instance:
#include "string.h" // points to my library include
#include <stdio.h> // points to C stdlib include
permits me to test all my library string functions using the C stdlib stdout functions.
It works both using GCC and GCC Cross Compilers.
I have tried to run the functions "strlwr", "strupr", "strcmpi", "strrev" from the string.h under Ubuntu and the gcc compiler; getting the next message:
warning: implicit declaration of function ‘strupr’ [-Wimplicit-function-declaration]
as well
(.text+0x84): undefined reference to `strupr'
Once I tried over Windows, same compiler, everything works perfectly.
I looked over the string.h in linux under "/usr/include" which states that was part of the GNU C library ISO C99 7.21 string handling (also tried to compile with the -std=c99, din't work) and I've learned from the header file that I could use the "strcasecmp" function, instead of the "strcmpi".
Can not do the same in Windows (look under the code of the header file) since the headers and libraries files are kind embedded under the compiler code, Am I right?(1)
Again searching for the string.h file in Linux, I have found nearly 50 files with the same name under different paths such as /usr/include/linux;
/usr/include/x86-64-linux-gnu/bits others under the directories of Oracle VB and the Arduino directory.
Why are so many files that handle the strings in C but doing in different fashion? How does the compiler knows which one to take in order to do the work? Is there any way, under the C file or during the compile process to define one of the multiple headers files?(2)
Am I using out of date headers and libraries, Is there any "official" source to know if any library have come depreciated? How to know what are under the Windows headers and libraries?(3)
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5) is what I am using and Windows 8.
Im a programming OpenCL via pyopenCL on a Ubuntu 16.04.3 64bit,
on Nvidia's Tesla K10.G2.8GB.
So far, anything runs smoothly as long as I don't include header files into my OpenCL kernel. As soon, as I put #include <stdlib.h> on top of my header file, the compilation of my openCL kernels fails with different files missing, amongst them being
gnu/stubs-32.h
sys/cdefs.h
Searching for that problem, brings up answers like
Error "gnu/stubs-32.h: No such file or directory" while compiling Nachos source code
or
https://askubuntu.com/questions/470796/fatal-error-sys-cdefs-h-no-such-file-or-directory
baiscally suggesting to install libc6-dev-i386 or gcc-multilib and g++-multilib, supposing that the underlying problem is a 64bit/32bit problem. My question is, are my OpenCL binaries for the GPU compiled as 32bit binaries (how can I check?)?
If yes:
Are there other caveats, when I want to compile 32bit binaries on a 64bit OS?
Furthermore: Can I use 64bit floats, when my kernel is compiled in 32bit?
(e.g., will #pragma OPENCL EXTENSION cl_khr_fp64 : enable still work?)
If no:
Do I have to manually locate / copy all the needed header files and include them by hand?
Also: Some of my co-workers even doubt, that including standard C headers into OpenCL kernels is possible due to missing linkers. Any light on that is also appreciated.
Standard C library and other system headers cannot be included
into OpenCL C code, basically because they are only compatible
with the current system (a host), whereas an OpenCL C code could
run on a different device with a different architecture (a GPU in
your case).
As a replacement for standard C functions, OpenCL C defines a set
of built-in functions, which are available without any #include:
printf, large number of math functions, atomics, image-related
functions, etc.
See the "OpenCL Specification: 6.12 Built-in Functions" for a
complete list:
https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf
That doesn't mean you can't create a header with OpenCL C code
and #include it into an OpenCL C program. This works fine:
// foo.h
void foo() {
printf("hello world!");
}
// kernel.cl
#include "foo.h"
__kernel void use_foo() {
foo();
}
I am using codeblock 13.12 and it uses mingw (GCC 4.7 & 4.8 Series)
It supports call by reference (func1(int &a)) eventhough I am selecting C project and not CPP project. If I am not mistaken, there is no concept of call by reference in C and everything is call by value even if it is making use of pointers.
My question is how to use C only features? Any settings for this? I saw that in toolchain it is using mingw32-gcc.exe for c compilations.
How to know which compiler version (Like C11, C99 etc) it is really using?
Name your files with an extension of .c. And definitely not .cc or .cpp
Compile with gcc as the command line, not g++
And if in doubt, use the -std= command line parameter to force the flavor of C you want (e.g. -std=C90, -std=C99, or even -std=C11 ). There's also -ansi.
Also, a cheap and dirty way to validate if your code is getting compiled as C and not C++ is to add this block of code within your source code. If it's C++, then the compiler will generate an error.
#ifdef __cplusplus
int compile_time_assert[-1];
#endif