How are C "spec" files like this created? - c

How do I create foo.spec files like this one from a C header file?
i.e. I'm looking for an automated way to convert all of a header file's declarations into something simple like:
stdcall CreateFileW(wstr long long ptr long long long)
which I can easily use to perform operations later.
I realize it might not be possible for some types, but it should be possible in a large number of cases.
How do I do this?

Ok, there is the tool likely used in wine project: http://www.winehq.org/docs/winedump
Intro:
winedump is a Wine tool which aims to help:
A: Reimplementing a Win32 DLL for use within Wine, or
B: Compiling a Win32 application with Winelib that uses x86 DLLs
For both tasks in order to be able to link to the Win functions some
glue code is needed. This 'glue' comes in the form of a .spec file.
The .spec file, along with some dummy code, is used to create a
Wine .so corresponding to the Windows DLL. The winebuild program
can then resolve calls made to DLL functions.
Creating a .spec file is a labour intensive task during which it is
easy to make a mistake. The idea of winedump is to automate this task
and create the majority of the support code needed for your DLL. In
addition you can have winedump create code to help you re-implement a
DLL
Spec generation mode:
Spec mode:
<dll> Use dll for input file and generate implementation code.
....
Files output in spec mode for foo.dll:
foo.spec
This is the .spec file.
foo_dll.h
foo_main.c
These are the source code files containing the minimum set
of code to build a stub DLL. The C file contains one
function, FOO_Init, which does nothing (but must be
present).
Makefile.in
This is a template for 'configure' to produce a makefile. It
is designed for a DLL that will be inserted into the Wine
source tree.
So, winedump will dump DLL interface to SPEC file. The Spec file can be additionaly edited by hand.
And the spec describes real DLL interface, not a high-level language interface (like it is encoded in .h headers). So, you can compile your code (.h and .c and maybe something like .def to fix DLL function numbers) on win32 to DLL as usual and then dump the spec from DLL.

Related

Importing Modules — customized Modules in C

I am currently learning the C programming language and I'm having some issues with importing modules I created.
I created a small module to read with fgets and flush the buffer from stdin perfectly and I don't want to keep writing the code every single time. I just want to import this small module like I used to do in Python. I didn't knew how because I'm not using an IDE. I'm just compiling with gcc in terminal and using a text editor. I tried to search with Google,but in vain.
You should create a header for your module that declares the functions in the module – and any other information that a consumer of the module needs. You might call that header weekly.h, a pun on your name, but you can choose any name you like within reason.
You should create a library (shared or static — that's up to you) that contains the functions (and any global variables, if you're so gauche as to have any) defined by your module. You might call it libweekly.so or libweekly.a — or using the extensions appropriate to your machine (.dylib and .a on macOS, for example). The source files might or might not be weekly.c — if there's more than one function, you'll probably have multiple source files, so they won't all be weekly.c. You should put this code (the header and the source files and their makefile) into a separate source directory.
You should install the header(s) and the library in a well-known location (e.g. $HOME/include for headers and $HOME/lib for the library — or maybe in the corresponding directories under /usr/local), and then ensure that the right options are used when compiling (-I$HOME/include for the headers) or linking (-L$HOME/lib and -lweekly).
Your source code using the module would contain:
#include "weekly.h"
and your code would be available. With shared libraries in $HOME/lib, you would have to ensure that the runtime system knows where to find the library. If you install it in /usr/local, that is done for you already. If you install it in $HOME/lib, you have to investigate things like /etc/ld.so.conf or the LD_LIBRARY_PATH or DYLIB_LIBRARY_PATH environment variables, etc.
You need to create a header file (.h) with your function declarations types and extern variables. Then in the program where you want to use those functions include this .h file and and add the compiled .o file (with your functions) to the object file list. And you are done.

Compile and link .h header files which many .c source programs use

I work for a group in which our test bucket has hundreds of .c source programs. The .c programs are fairly small and they all include the same 10 .h header files. These .h files are fairly large.
Each time we get a new library file to link our test programs to test, we run a script to recompile and run our test bucket against. The problem is that the compiling takes fairly long, especially if the environment is virtual.
Is there a way to compile the .h header files once, put in a separate object file and have those many .c source files link to said object file? I think this will speed up compiling time. I am willing to change/remove all the #include in the .c source programs.
Any suggestions to speeding up compile time is greatly appreciated.
Also, I should say that a script executes a makefile PER .c source test program! The makefile is not told to compile all programs in the current directory. Each test program is compiled into its own executable.
You could use precompiled header feature. See http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
You've asked further suggestions to speed up your compilation.
One way can be using ccache. Basically, ccache keeps a cache of the object files compiled so far and returns them (instead of re-compiling again over and over) when it recognises that the same source file is being compiled again.
Using it should be as simple as
Install ccache
Prefix your gcc/cc/g++ command with ccache
Rewrite your headers. Strip off all definition and leave in header. Strip off all implementation and put in new .c. Compile as library. Link with solution. Distribute library on runtime system.
If I understand correctly, the way libraries typically work is by using precompiled code in object files ( .so on Linux systems? ), while providing header files ( .h ) for use in projects.
What happens is when you compile, the #include <library.h> directive finds that header and pastes its contents in the source file being compiled. Then, once the source file is compiled, it is linked to the precompiled object file. That way, the library can be included in a huge number of projects without it needing to be compiled from source each time. The only part that must be recompiled when linking to a library is the ( relatively ) small amount of code in the headers, which essentially makes library functions and variables accessible to the source code.
All this means is that to drastically speed up compilation, your best bet is to take all of the functions out of the 10 .h files, and instead leave only the function prototypes in the headers. Once you have all of the functions in separate .c source files, you can compile them into an object file ( typically -c flag ). Then, whenever you need to compile a new program against the 10 headers you typically use, you can instead include your stripped down version of the headers, and link to the precompiled object. Since only the new code in the .c file has to be compiled, instead of all of the code in the headers, the process should be much faster.

How to stop file names/paths from appearing in compiled C binary

This may be compiler specific, in which case I am using the IAR EWARM 5.50 compiler (firmware development for the STM32 chip).
Our project consists of a bunch of C-code libraries that we compile first, and then the main application which compiles its C-code and then links in those libraries (pretty standard stuff).
However, if I use a hex editor and open up any of the library object files produced or the final application binary, I find a whole bunch of plain text references inside the output binary to the file paths of the C files that were compiled. (eg. I see "C:\Development\trunk\Common\Encryption\SHA_1.c")
Two issues with this:
we don't really want the file paths being easily readable as that indicates our design some what
the size of the binary grows if you have your C-files located in a long subdirectory (the binary contains the full path, not just the name)...this is especially important when we're dealing with firmware that has a limited amount of code space (256KB).
Any thoughts on this? I've tried all the switches in the compiler I can think of to "remove debug information", etc., but those paths are still in there.
"The command-line option --no_path_in_file_macros has been added. It removes the path leaving only the filename for the symbols FILE and BASE_FILE."
It is defined in the release notes if IAR.
http://supp.iar.com/FilesPublic/UPDINFO/005832/arm/doc/infocenter/iccarm_history.ENU.html
Or you can look for FILE and BASE_FILE macros and remove it you do not want to use the flag.

Using DLLs in C

This seems like a noob question, but all my searches return stuff about C++ or C# so I'm going to ask it here.
I have a DLL, SDL.dll, in the directory with my .c file. I want to import it to use.
using is not supported, #import doesn't work.
No directive in the source will help you, you can either
link to the DLL, use a so-called lib file for this. (This is a statically dynamic linking)
use LoadLibrary/FreeLibrary and GetProcAddress to map the addresses of functions to function pointers (true dynamic linking)
In the first case you also need an appropriate header file which matches the platform and version of the DLL used.
The second solution will work if you drop-in a newer version of the DLL as long as the prototypes of the functions used match.
This assumes you are under Windows, which is probably the case if you have a *.dll and not an *.so (shared object) file. (For Linux systems, you can include dlfcn.h and use dlopen/dlclose/dlsym instead of LoadLibrary/FreeLibrary/GetProcAddress with a slightly different syntax, check the doc)
this is quite possible assuming your DLL is in the correct form (the same standards as Windows API DLLs for example)
you need to declare you functions - perhaps in a header file, like this:
typedef void (CALLBACK *functionnameptr)(char *, int),
Then you use LoadLibrary to load the DLL, and provide a Handle to it:
handle = LoadLibrary("SDL.DLL");
Then you use GetProcAddress(handle,"real function name in DLL")
like this:
functionnameptr lptrfunction;
lptrfunction = GetProcAddress(handle,"real function name in DLL");
Now you can use the lptrfunction as you would normally use a function in C
Assuming you're using Visual Studio.
1.) Download http://www.libsdl.org/release/SDL-1.2.15.zip
2.) unzip and install to for example C:\SDL-1.2.15
3.) In Visual Studio open the properties of the project goto C++ general and add C:\SDL-1.2.15\include to "Additional include directories".
4.) Goto the "Linker" tab and add C:\SDL-1.2.15\lib\x86 to "Additional library directories".
5.) Now go to "Input" under the Linker tab and add SDL.lib; SDLmain.lib to "Additional dependencies"
6.) Go to the "Build Events" tab and "Post build event" and add copy /y C:\SDL-1.2.15\lib\x86\SDL.dll "$(OutDir)
That should do get your SDL working for Visual Studio in 32bit
On Linux if SDL is already installed just type "g++ -02 -o foo foo.cpp -lSDL"

Appending data to an executable (Windows, Unix)

I have a program which compiles and runs scripts.
To create a standalone version of the script, I reserve a large static buffer to hold the compiled script. The compiled script is copied into a copy of the program and it can then be run from that copy.
This works fine. It has some disadvantages however:
the buffer is static and takes up space if there's no compiled
program in it.
if the script to be included exceeds the buffer's size, I need to build a new version with a larger buffer.
I'd like to add the compiled script to the end of the program, but naively doing so doesn't work as the exe loader chokes on the new file size.
Is there a way to manipulate the exe so it would be acceptable for the loaders (mind this is a cross platform program)?
would be acceptable for the loaders (mind this is a cross platform program)?
I would think that this is unlikely to be possible without being platform specific. Time for a common interface with different implementations (so the code that saves/loads the script is common, but the executable manipulation is specific).
On Windows you'll hit the problem that a running executable file is locked against modification. By working on copies this can be worked around (but the only way to rename back in a completely deterministic way it is perform the move on boot, but scheduling a job might be acceptable).
On Windows the easiest way to add data to an image (executable or dll) is using resources. Define a custom resource type and add into the image (UpdateResource function) and later retrieve with LoadResource.
You said "script", so I suppose you have a separate file containing the script (a text file?). You could write a simple program that reads the script file and convert it in a compilable form (e.g. a C source containing the initialization of an array of byte). There are also tools you can use to convert an arbitrary file into a linkable object (.o or .obj). In the past I have used the command "objcopy" from GNU bimutils. In particular, on linux:
objcopy -I binary -O elf32-i386 mydata mydata.o
This command creates an object and three public symbols you can use to find the start, the end and the size of your data block:
_binary_mydata_start
_binary_mydata_end
_binary_mydata_size
Something similar may work also on Windows, provided that you install a Windows version of GNU binutils (e.g. cygwin).

Resources