pthreads static linking with MinGW - windows

I would like to statically link "pthreads for Win32" with my application, compiled with MinGW32 so the app won't need pthreadGC2.dll to run.
I'm using the latest release of pthreads - 2.9.1, downloaded from here and lib and include files are copied to MinGW lib and include directories.
When searching the web how to do that I stumbled upon this thread which instructs using the -static-libgcc -static-libstdc++ flags. This doesn't work, meaning the app compiles but it can't run without pthreadGC2.dll present.
They also recommend using -static -static-libgcc -static-libstdc++. This doesn't compile with the following error:
main.o:main.cpp:(.text+0x461): undefined reference to `_imp__pthread_create'
main.o:main.cpp:(.text+0x4be): undefined reference to `_imp__pthread_join'
Does anyone knows how to do that?
By the way - coping pthreadGC2.dll downloaded from 2.9.1 release (inside pthreads-w32-2.9.1-1-mingw32-dll.tar.lzma) to the app's folder is not enough. To run the app I should also copy another dll: libgcc_s_dw2-1.dll. This is really bad for me - I wouldn't want to make my users have these 2 DLLs each time they want to run my app
Here is my code:
#include <stdio.h>
#include <pthread.h>
static void* threadMain(void* param)
{
printf("thread start\n");
for (int i = 0; i < 2; i++)
Sleep(1);
printf("thread end\n");
return NULL;
}
int main(int argc, char* argv[])
{
pthread_t thread;
int err = pthread_create(&thread, NULL, threadMain, NULL);
if (err != 0)
{
printf("Cannot create thread: %s", strerror(err));
return;
}
printf("thread created\n");
Sleep(1);
pthread_join(thread, NULL);
printf("thread joined\n");
}
and my makefile:
all:
g++.exe -DHAVE_STRUCT_TIMESPEC -c -o main.o main.cpp
g++.exe -static-libgcc -static-libstdc++ -o link_pthreads.exe main.o -lpthread
clean:
del main.o
del link_pthreads.exe

With the new updated version of MinGW you can get version 2.10 of pthread-win32 library. Among several changes and bug fixes, you could find the possibility to statically link it.
You only need to include -lpthread in the list of static libraries.
Following is an example mixing static linking with the pthread library and dynamic linking with a Windows library:
mingw32-gcc.exe -o sample.exe sample.c -Wl,-Bstatic -lpthread -Wl,-Bdynamic -lws2_32
With this, you also release the dependency on libgcc_s_dw2-1.dll

Related

How to compile project, that uses gtest with gcc compiler?

I have simple source code, that includes gtest and launches testing. Here are the file tests.c:
#include <gtest/gtest.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
printf(" init GTest ");
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I launched build using compiler gcc:
gcc -o MY_UNIT_TESTS tests.c -I/usr/include /usr/lib/libgtest.a /usr/lib/libgtest_main.a -lpthread
And it is failed with this error:
In file included from tests.c:1:0:
/usr/include/gtest/gtest.h:54:18: fatal error: limits: No such file or directory
compilation terminated.
If I use compiler g++, everything is ok. I need to test library, that was built using gcc compiler, so my test should be also build with gcc.
How can I build this code using gcc compiler ?
Google Test is written in C++ (and your are tests too) and you need to use g++ to compile your tests. You can build your library with gcc and you can call your C code from your C++ tests, but there are some things to be aware of.

undefined reference to `__isoc99_sscanf#GLIBC_2.7'

Hi am trying to compile a src file by linking an external library.
Getting below error
undefined reference to `__isoc99_sscanf#GLIBC_2.7'
make -f GNUmakefile
g++ -m32 -D_POSIX_PTHREAD_SEMANTICS -g -Wl,--version-script=fix.txt -D_GNU_SOURCE -I../include ConnectionAndAuthExample.cpp -o ../Linux/ConnectionAndAuthExample_32 -L../Linux -lsomelib
../Linux/libsomelib.so: undefined reference to `__isoc99_sscanf#GLIBC_2.7'
Contents of fix.txt are
GLIBC_2.7 {
global: *;
local: *;
};
Similar query was answered below here doesnt help. I want to know if anyone else have encountered similar error and resolved it.
My GCC version
-bash-3.2$ g++ --version
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-50)
Finally the link in the question help with slight modification from other answers. Here is my fix.
I created a new cpp file with below contents
#include <iostream>
#include <stdarg.h>
__asm__(".symver __isoc99_sscanf,__isoc99_sscanf#GLIBC_2.7");
#ifdef __cplusplus
extern "C" {
#endif
int __isoc99_sscanf(const char *a, const char *b, va_list args)
{
int i;
va_list ap;
va_copy(ap,args);
i=sscanf(a,b,ap);
va_end(ap);
return i;
}
#ifdef __cplusplus
}
#endif
Compiled it to get the object file and used it along with fix.txt mentioned in the question.
However, I would like to inform that since my third party library was compiled on an higher version. I am getting ELF file OS ABI invalid when I run my binary.
There solution from some other answer which suggests to use patchelf and modify intert section doesnt help as shared files mostly dont have that section.
I also tried to compile glibc2.7 and build my binary using
-Wl,--dynamic-linker
-Wl,--rpath
flags pointing to glibc2.7 . Still in vain.

How to fix undefined reference to `_imp__pthread_create'

I use MinGW on windows7 32bit.
And I can’t compile my source which uses pthread.
My code is below.
#include <stdio.h>
#include <pthread.h>
int main(int argc, char** argv)
{
(void)argv;
printf("######## start \n");
#ifndef pthread_create
return ((int*)(&pthread_create))[argc];
#else
(void)argc;
return 0;
#endif
}
Error happens as I compile it.
gcc -I /usr/local/include -L /usr/local/lib/libpthread.dll.a trylpthread.c
C:\Users\xxx\AppData\Local\Temp\cc9OVt5b.o:trylpthread.c:(.text+0x25): undefined reference to `_imp__pthread_create'
collect2.exe: error: ld returned 1 exit status
I use following pthread library.
pthreads-w32-2.8.0-3-mingw32-dev
And here is libpthread.dll.a in /usr/local/lib
Does anyone know how to fix this problem?
The commandline:
gcc -I /usr/local/include -L /usr/local/lib/libpthread.dll.a trylpthread.c
does not make sense.
-L <dir> is a linker option that directs the linker to search for required libraries
in directory <dir>. Thus you are telling the linker to search for required libraries in
path /usr/local/lib/libpthread.dll.a, which is not a directory, while on the other hand
you are not telling the linker to link any libraries at all. That is why it fails to find any
definition for _imp__pthread_create.
Neither does the program you have posted make sense. The lines:
#ifndef pthread_create
return ((int*)(&pthread_create))[argc];
#else
(void)argc;
return 0;
#endif
say:-
If I have not defined a preprocessor macro pthread_create then compile:
return ((int*)(&pthread_create))[argc];
else compile:
(void)argc;
return 0;
Well if you had defined a preprocessor macro pthread_create, e.g.
#define pthread_create whatever
then the code you would compile would be:
(void)argc;
return 0;
And since you have indeed not defined any such macro, the code you compile is:
return ((int*)(&pthread_create))[argc];
which fails at linkage, as you see. And if that code was compiled with pthread_create so defined,
it would be:
return ((int*)(&whatever))[argc];
Rewrite your program as:
#include <stdio.h>
#include <pthread.h>
int main(int argc, char** argv)
{
(void)argv;
printf("######## start \n");
return ((int*)(&pthread_create))[argc];
}
Compile with:
gcc -Wall -I /usr/local/include -o trylpthread.o -c trylpthread.c
Link with:
gcc -o trylpthread.exe trylpthread.o /usr/local/lib/libpthread.dll.a
Remember that when you get the program compiled and linked, the appropriate pthreadGC??.dll
must be found at runtime in one of the places where the program loader searches for dlls.
Better still, uninstall your MinGW and your pthreads-w32-2.8.0-3-mingw32-dev and
install a more up-to-date Windows port of GCC, e.g. TDM-GCC (simplest) or mingw-w64. Pick the 32-bit version, if your Windows system
is 32-bit. These toolchains come with built in pthread support, as GCC standardly does.
Compile with:
gcc -Wall -o trylpthread.o -c trylpthread.c
Link with:
gcc -o trylpthread.exe trylpthread.o -pthread
(not -lpthread)

How do you compile C++ programs that include LLVM API headers?

I'm trying to use the C++ compiler to compile the following program:
#include <stdio.h>
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/IR/Module.h"
int main( int argc, char* argv[] )
{
if( argc < 2 )
llvm::errs() << "Expected an argument - IR file name\n";
llvm::LLVMContext &context = llvm::getGlobalContext();
llvm::SMDiagnostic err;
llvm::Module* module = llvm::ParseIRFile( argv[1], err, context );
if( !mod )
{
err.print( argv[0], errs() );
return 1;
}
return 0;
}
I'm trying to compile the program using the following command:
clang++ main.cpp -o main
However, when I compile, I'm getting the following compile error:
main.cpp:2:10: fatal error: 'llvm/IR/LLVMContext.h' file not found
#include "llvm/IR/LLVMContext.h"
^
1 error generated.
In this case, I'm not exactly sure how to link the LLVM API headers when compiling main.cpp with Clang.
Any help would be greatly appreciated.
You can use the following command:
g++ -std=c++11 main.cpp `llvm-config --system-libs --cppflags --ldflags --libs core` -o main
Where --libs and --system-libs flags are used for linking and --cppflags takes care of include paths.
Thank You
You need LLVM checked out or installed somewhere on your system. You can download a binary release (with headers and libraries you can build against) as explained here: http://llvm.org/releases/download.html#3.5
You can also check out LLVM from its SVN repository as explained here: http://llvm.org/docs/GettingStarted.html#checkout
Once you do that, I recommend looking at the llvm-clang-samples repository that comes with a Makefiles showing how to build sample programs vs. an up-to-date LLVM.

Shared Library Constructor is not executed

I have the following problem. I write a shared library
#include <stdio.h>
#include <stdlib.h>
static void __attribute__ ((constructor)) test_init(void);
static void __attribute__ ((destructor)) test_clean(void);
/* Initialization */
static void test_init(void){
fprintf(stderr,"initialized\n");
fflush(stderr);
}
/* CleanUp */
static void test_clean(void){
fprintf(stderr,"cleaned up\n");
fflush(stderr);
}
double test (double x){
return 2.0*x;
}
And compile it using
gcc -c -fPIC testlib.c -o testlib.o
ld -shared -o libtest.so testlib.o
Then I include it into a test program
#include <stdio.h>
#include <stdlib.h>
extern double test(double x);
void main(void){
printf("%.10e\n",test(10.0));
}
which I compile and start using
gcc testprog.c -o testprog -L. -ltest
LD_LIBRARY_PATH=. ./testprog
Then the output is given by
2.0000000000e+01
which means that the constructor/destructor are not executed. On the other hand, if I compile
ar rvs testlib.a testlib.o
gcc testprog.c testlib.a -o testprog
the output of the program is given by
testprog
initialized
2.0000000000e+01
cleaned up
Why are the constructors not executed if the library is linked dynamically?
I use the following versions
GNU ld (GNU Binutils; openSUSE 11.3) 2.20.0.20100122-6
gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292] (SUSE Linux)
Thank you in advance for your help!
Edited: 2011-04-13, 11:05
Thank you very much luxifer,
the document helped indirectly! The magic hint was that one should involve the linker through the compiler...
gcc -fPIC testlib.c -shared
-Wl,-soname,libtest.so -o libtest.so
works!!!
Gcc's constructor handling is not the same thing as the ELF constructor handling, rather, it sits on top of it. To work, you need to link in the glue code that is provided in gcc's startup files.
The easiest way to do that is to link using gcc:
gcc -shared -o testlib.so testlib.o
This text is meant for reference, but I'm coming over to your office for convenience :)
I'm not an expert on that field but a quick Google search gave me this. Reading just the beginning of the document and if I get it right the problem is this:
Linked statically your program is self-contained at execution time... it has the whole library in it and it's completely loaded into memory when you run it.
Linked dynamically when the library function is called from your program at execution time the linker tries to resolve all unresolved references on functions by looking if it has an implementation in some library. If so it loads this implementation, i.e. just the functions code.
So if I get this right and the dynamic linker just loads portions of libraries, i.e. needed functions, and not the whole library then this would explain why your constructor isn't called when your library is linked dynamically.

Resources