How to statically-link a complex program
Most autoconf
generated configure
script will allow you to make a static build:
./configure --enable-static
make
If that doesn't work, you may be able to pass linker flags in via LDFLAGS
, like this:
./configure LDFLAGS=-static
How to static link Linux software that uses ./configure?
Try this:
./configure LDFLAGS="-static"
Linking static libraries to other static libraries
Static libraries do not link with other static libraries. The only way to do this is to use your librarian/archiver tool (for example ar on Linux) to create a single new static library by concatenating the multiple libraries.
Edit: In response to your update, the only way I know to select only the symbols that are required is to manually create the library from the subset of the .o files that contain them. This is difficult, time consuming and error prone. I'm not aware of any tools to help do this (not to say they don't exist), but it would make quite an interesting project to produce one.
How to statically link a Chicken Scheme program that uses extensions?
Assuming your program is in a-program.scm file:
csc -deploy a-program.scm
cd a-program/
chicken-install -deploy -p $PWD http-client
...et voilà!
edit: turns out that the proper answer to the problem posted is solved in this document: http://www.foldling.org/scheme.html#compiling-statically-linked-chicken-scheme-programs-with-extensions
Linking partially static and partially dynamic in GCC
The following worked for me
ln -s `gcc -print-file-name=libc.a`
gcc -static-libgcc -L. -lc test.c
Then ldd a.out
gives:
not a dynamic executable
Edit:
The OP wants to link one library dynamically and another statically. He have the example of linking libc
statically and libm
dynamically. That particular case I have not been able to achieve. However, the opposite is possible i.e. linking libc
dynamically and libm
statically.
ln -s `gcc -print-file-name=libm.a`
gcc test.c -L. -lm
then ldd a.out
gives
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x41960000)
/lib/ld-linux.so.2 (0x4193d000)
Note that the link order matters.e.g gcc -L. -lm test.c
does not work.
This works with other libraries as well. For example gomp
gcc -fopenmp test.c
ldd shows libgomp.so.1
. We can link it statically like this
ln -s `gcc -print-file-name=libgomp.a`
gcc -L. -fopenmp test.c
Now ldd a.out
does not show libgomp.so.1
. But in this case pthreads
is still linked dynamically. To link pthreads statically requires that libc
be linked statically as well.
How to properly statically link C with Delphi?
It depends on the name decoration used by whichever C compiler you are using. For example, the 32 bit bcc32 compiler will decorate Test
as _Test
. So the Delphi code to link to it should be:
function Test(): Integer; cdecl; external name '_Test';
But the decoration does vary between compilers, and you did not say which compiler you are using. If the code above doesn't help, then you should use your C compiler's tools to dump the obj file and inspect the names of the functions within.
Another problem is that you are actually using a C++ compiler rather than a C compiler. That can be discerned from your use of
extern "C"
which is not valid C. You should remove this and switch to a C compiler. Changing the extension from .cpp to .c will usually suffice to persuade the compiler to treat the code as C.
If you start calling functions from the C standard library, such as malloc
and friends, then you will want to add the System.Win.Crtl
unit to your Delphi code's uses clause.
Note also that you need not, and indeed probably should not, implement a main
function in your C code. If you want to compiler your C functions into a separate C program then place the functions in separate source files, apart from the source file that contains the main function. That way you can compile the source files into objects. You can link them into either a C program, or your Delphi code. But you don't need to carry around a main
function in your Delphi program that you don't call.
In C the correct signature for a parameterless main
is
int main(void)
Similarly, your other C function should have this signature:
int __cdecl Test(void)
Of course, the __cdecl
is the default, so we are perfectly at liberty to omit it:
int Test(void)
Let's put it all together:
C
int Test(void)
{
return 12;
}
Important that you compile with a C compiler and do not compile as C++. If your compile is, as you now state in an edit, MSVC, the command line would be:
cl /c source.c
Delphi
{$APPTYPE CONSOLE}
{$L Source.obj}
function Test: Integer; cdecl; external name '_Test';
begin
WriteLn(Test);
end.
Output
12
Related Topics
Backing Up (And Restoring) a Plone Instance
Unable to Pass Wget a Variable with Quotes Inside the Variable
Bash: Best Architecture for Reading from Two Input Streams
Linux Task Schedule to Hour, Minute, Second
Best Way to Set Environment Variables in Calling Shell
Undefined Reference to 'Dlopen'
Qt Creator: Add Qt Module to Project
Segfault with Rip-Relative Addressing on Linux
Why Does Order in Which Input Libraries Are Specified Matter
Should %Rsp Be Aligned to 16-Byte Boundary Before Calling a Function in Nasm
How to Duplicate String in Bash
Android Studio 3.0 Emulator Does Not Start
Cannot Use Wildcard in Kernel Module Makefile
Suppress Notice of Forked Command Being Killed
How to Stop a Running R Command in Linux Other Than with Ctrl + C
After Changing /Etc/Profile, What Do I Have to Do to Reset My Shell