Cross compilation requirements for C
I have some basic knowledge about compiling C but need to get a couple of gen开发者_运维百科eric cross-compilation questions answered. In my case, I am trying to cross-compile a program on my Fedora Linux box that is going to be run on an ARM single board computer.
My first question is about headers. I have downloaded the arm Linux tools package and it contains headers files such as stdio.h in an include directory. Am I supposed to use this "target" include directory as opposed to my system include directories when I am cross-compiling? Or is it OK to point to my system's include dirs such as /usr/include? (These header files seem to be different when I diff them.)
What happens if a header file does not exist. In my case, I am also planning to utilize the cURL library on the ARM board. Can I simply point to the include directory present in the curl source package that I downloaded without worrying about the target architecture? If yes, does this mean my first question is irrelevant?
Let's say I want to statically link to a library. Does this static library need to be compiled for the target ARM platform before this happens? Or can I use the static libraries installed on my system directly (hoping that the cross compilation process takes care of business)?
If I decide to dynamically link to a library, the only requirement would be that the target system has this library compiled for ARM and installed in one of the LD_LIBRARY_PATH directories on the ARM board, am I correct?
Thanks for the help.
- Always use the target headers. They may differ from your host headers. The compiler should already have them as part of its default include path for the standard issue, such as libc.
- You will need to build cURL using the cross compiler into a fake "target" system directory, and build your application with cURL in this target directory. As you need a cURL library as well, you MUST use the cross compiler. For compiles which are not cross compile friendly (such as building programs and running then as part of the compile), you will need to modify the build process. Sometimes
fakeroot
can be helpful for dirty build systems. - You can't arbitrarily use a static library for a different architecture from your system. They must be built by the cross compiler.
- Incorrect. The library generally must be present.
Any library you intend on using, including the libc, must be built for the target platform before you can link against it. Use the target headers instead of the host headers for building so that you're assured of using the correct API.
If you have control over the include paths and toolchains in both compilers, you need to make sure you have a platform specific implementation for each system you are compiling for. It common that the embedded system creates mock headers to fulfill commonly used headers such as <stdio.h>
, <stdlib.h>
and <math.h>
. The platform specific compiler/settings then compile using different libraries for these common headers. Hence, using a bare #include <stdio.h>
works without issue.
If you have access to the compiler can can create separate include paths, you can built separate libraries for each platform.
If you're like me and don't have direct access to the compiler (vendor SDK hides it, makes it ugly to work around), then you need to create a mock header that defines the header depending on tags that get set at compile time by upstream dependencies. There should be some magic flags that get set by the compiler in upstream headers that you can look for to determine if you should create a header for the embedded versus host system, such as #if defined(__TMS320C6X__) && defined(__TI_EABI__)
to help differentiate. You can dig around in the embedded library include files to get an example (stddef.h is usually a good reference). For the embedded system, use a header guard with a unique name such as #define _MyHeader_H
to flag that the header has been defined. At the end, you can do #ifndef _MyHeader_H
to create to host system header as a fallback case.
Consider a case where you need <complex.h>
, which is defined for the embedded system but not the host system.
You will have 3 header files: a dummy header to disambiguate which cross compile is needed, an embedded system implementation, and a host implementation.
complex_choice.h
#if __STDC_VERSION__ >= 199901L
#include <complex.h>
#endif //using a C99 compiler
#include <complex_host.h> // ! using a C99 compiler
complex.H
#ifndef _COMPLEX_H
#define _COMPLEX_H
//Embedded system implmentation here
#endif /* _COMPLEX_H */
Complex_host.H
#ifndef _COMPLEX_H
#define _COMPLEX_H
//Host system implmentation here
#endif /* _COMPLEX_H */
精彩评论