Android.mk change local C include directory depending on file - c

I am building a dynamic library (.so) file for android with around 100 local c files. The files all include a file c_macros.h, but the c_macros.h in question changes for different groups of files. For example, foo0.c and bar0.c need to include c_macros.h in the directory 0/ whereas foo1.c and bar1.c need to include c_macros.h in the directory 1/.
I see that one can define LOCAL_C_INCLUDES for the entirety of a compilation so that all .o files will use those local includes. However, can the LOCAL_C_INCLUDES be specified for a single file (or a group of files) and then change so that the right directories can be included for the right files?
One solution is just to build different .so files depending on which c_macros.h is being used, but this adds an overhead of around 10KB for each .so file, so I'd like to squash everything in one big .so file if possible, but then I'd need to sort out the LOCAL_C_INCLUDES issue.

You can build it into separate static libraries (where you can easily set different LOCAL_C_INCLUDES for each), and just build one single .so file that includes the static libraries. When linking the final .so file, this doesn't incur any extra overhead (the object files from static libraries behave just as normal individual object files).

Related

Scons: customize default builders

I have an embedded software entirely written in C and Assembly and for its build process I am using Scons and GCC. The source code is organized in different folders and each folder represents a "standalone" sub-project (i.e., application elf, static libray, etc.).
The main SConstruct file, located inside the main folder of the project, builds a default environment, adding to it some compilation flags shared among all the sub-projects, then it invokes the SConscripts placed in every sub-project, exporting the default environment.
Each sub-project builds a new environment cloning the default one and customize it with new builders, new compilation flags, etc.
The issue comes out because I have to add, for all sub-projects, some actions after each object file's compilation. In short, I need to generate preprocessed file for each ".c" and ".S", invoking the preprocessor with the same flags used by the normal compilation. To do this I think the best solution is to add the compilation flag "-save-temps=obj" to the default environment (this flag tell to the compiler to keep the temporary files), so all sub-projects will inherit this behavior.
The issue is that SCons doesn't track each generated temporary file. Considering that:
for each .c file, gcc will create the two temporary file .i and .s
for each .S file, gcc will create the single temporary file .s
I need to add to the default Object builder:
A SideEffect to tell scons that a .c to .o compilation will create also a .i file;
A SideEffect to tell scons that a .c to .o compilation will create also a .s file;
A SideEffect to tell scons that a .S to .o compilation will create also a .s file;
Is there a way to do this only using the file suffixes and without the enumeration of each target object file?
Furthermore, on each temporary file, I need to invoke a custom tool, again with the same compilation flags used for its compilation, in order to create other files with other debug information. How can I do this? Is there a way to add a post-action to the Object builder?
Thanks,
Ciro

contents of a .a static library file

I was shared a static library file('.a' file). When i opened it with 7z, it included two files, one without extension and one with .o extension. What are these files. Is the .o an object file here and which one of these file is actually linked during linking process.
More info about the .a file:
Lets name the file xyz.a:
When i un compress it or view it with 7z, i can see two files:
- xyz
- abc.o
The '.a' file can contain several '.o' files added by the ar utility. It can also contain an index mapping global symbols to the '.o' files that contain them. On some systems (mostly SysV or GNU based), ar's s option is used to update the index. On other systems (mostly BSD based), the index is updated by a separate ranlib utility.
To answer your questions, the '.o' files are the object (code) files that make up the library, the other file is the index, and some subset of the '.o' files will be linked by the linker, with the assistance of the index to determine which '.o' files are needed.
With the ld linker, the option -l foo would search for a dynamic library called libfoo.so or a static library called libfoo.a. Other ld options control whether it looks for a static or dynamic library and where to look for it.

C Header Files with the same declarations but different implementations

I have two sets of header files and .c files in my project i will only ever be including one of these headers but i want the option to quickly swap the header im including. Both header files have some declarations that are exactly the same but the implementations in the .c files are different. Basically what I need is way to tell the compiler to only compile the .c file that is associated with the header im including elsewhere in my program.
You could always specify the .c or .o file that you're going to link against at compile/link time for instance
gcc -o myexe file1.c/file1.o
or
gcc -o myexe file2.c/file2.o
you could even make this a different make directive if you have a makefile if you have the same header file but 2 different implementations. I would recommend just using 1 header file and changing the underlying implementation, no point in having 2 headers with similar declarations.
If both header files are exactly the same then you don't need to maintain two header files. You can keep only one copy. Whichever code includes the header file can include this single header file only.
You can always specify which .c file you want to compile while compiling. In gcc, you can mention the C file to be compiled in the command line. In Visual Studio, you can include the correct C file.
I guess you should maintain only one header file and include that in your code. Introduce a flag to the makefile to link which implementation to be linked. You have not mentioned what are you using to build.

how to do include within include statement

I wanted to include a file say a.h in my program which is located at some location say (/ws/uname/bd/lib) & that file in turn has different include statements whose files are located in vastly different locations.
How can i do that by just including the file with "/ws/uname/bd/lib/a.h".
I dont want to change any of the header file.
Appreciate your help
What compiler are you using? If it's clang or gcc, you can use the -I flag to add search paths for header files. From the gcc(1) man page:
-Idir
Add the directory dir to the head of the list of directories to be searched for header files. This can be used to override a system header file, substituting your own version, since these directories are searched before the system header file directories. However, you should not use this option to add directories that contain vendor-supplied system header files (use -isystem for that). If you use more than one -I option, the directories are scanned in left-to-right order; the standard system directories come after.

Copy C files to include

I have a set of C files that I would like to use. Can I just copy them to my include directory, or do I have to compile them. I would think they would be compiled in the final binary.
You need to compile those C files if you want to use them.
To make use of what's in those C files, you'll nead a header file that declares what's inside them.
Those header files is what you'd put in your include folder, and you'll compile the C files together with your other C files. (Or you could make a library out of those C files)
Yes, they need to be compiled so that they are available at the linking step. C is not an interpreted language, so having the sources present in an include directory would do nothing for execution.
You can keep the source files at the same location. The include files will be in the include directory. You can use the compilation option -I./<include-file-directory> to specify from where to fetch the include files.
The final binary will be compiled version of all your source files which you give to the compiler. You have to explicitly specify every file to be compiled along the with final executable name.
In case you dont do so a default executable is created with the name a.out(i am assuming the platform to be linux and compiler to be gcc) in the directory where you compile.
Check the link for more details on compilation using Makefile.

Resources