1. Can't get DLL to Build [SOLVED]

Hi all,

I've been wanting to make a wrapper for this library, but haven't been able to build the DLL for it.

[https://github.com/JettMonstersGoBoom/tigr] TIGR LIBRARY

CFLAGS += -I../.. -Os -s -DTIGR_SHARED 
ifeq ($(OS),Windows_NT) 
	LDFLAGS += -s -lopengl32 -lgdi32 
	DLL = dll 
	EXT = exe 
else 
	UNAME_S := $(shell uname -s) 
	DLL = so 
	EXT =  
	ifeq ($(UNAME_S),Darwin) 
		LDFLAGS += -framework OpenGL -framework Cocoa 
	else ifeq ($(UNAME_S),Linux) 
		LDFLAGS += -s -lGLU -lGL -lX11 
	endif 
endif 
 
 
hello.$(EXT) : hello.c tigr.$(DLL)  
	gcc $^ -Os -o $@ $(CFLAGS) $(LDFLAGS) 
 
tigr.$(DLL): 
	gcc ../../tigr.c -DTIGR_BUILDSHARED -shared $(CFLAGS) $(LDFLAGS) -o tigr.$(DLL) 
 
clean: 
	rm hello.$(ext) 

When I try to build with Mingw32 it gives these errors:

undefined reference to `__mingw_winmain_hInstance' 
undefined reference to `__mingw_winmain_lpCmdLine' 
undefined reference to `__mingw_winmain_nShowCmd' 

Strangley it builds fine using GCC

gcc -c tigr.c 
 
no errors and it builds fine 

new topic     » topic index » view message » categorize

2. Re: Can't get DLL to Build

Icy_Viking said...

I've been wanting to make a wrapper for this library, but haven't been able to build the DLL for it.

[https://github.com/JettMonstersGoBoom/tigr] TIGR LIBRARY

CFLAGS += -I../.. -Os -s -DTIGR_SHARED 
ifeq ($(OS),Windows_NT) 
	LDFLAGS += -s -lopengl32 -lgdi32 
	DLL = dll 
	EXT = exe 
else 
	UNAME_S := $(shell uname -s) 
	DLL = so 
	EXT =  
	ifeq ($(UNAME_S),Darwin) 
		LDFLAGS += -framework OpenGL -framework Cocoa 
	else ifeq ($(UNAME_S),Linux) 
		LDFLAGS += -s -lGLU -lGL -lX11 
	endif 
endif 
 
 
hello.$(EXT) : hello.c tigr.$(DLL)  
	gcc $^ -Os -o $@ $(CFLAGS) $(LDFLAGS) 
 
tigr.$(DLL): 
	gcc ../../tigr.c -DTIGR_BUILDSHARED -shared $(CFLAGS) $(LDFLAGS) -o tigr.$(DLL) 
 
clean: 
	rm hello.$(ext) 

That's a weird looking Makefile. I guess it's not wrong per se, but on a non-Windows platform you'd end up with an executable named "hello." with a trailing dot. Strange.

Icy_Viking said...

When I try to build with Mingw32 it gives these errors:

undefined reference to `__mingw_winmain_hInstance' 
undefined reference to `__mingw_winmain_lpCmdLine' 
undefined reference to `__mingw_winmain_nShowCmd' 

That's because the original tigr.c defines its own WinMain() function here, which assumes you're building an executable and not a shared library. You can't have a main() (or WinMain()) function in a shared library.

Icy_Viking said...

Strangley it builds fine using GCC

gcc -c tigr.c 

no errors and it builds fine

That's because you're only compiling the source file, so the linker isn't yet looking for WinMain(). In order to build this correctly you'll need to add an #ifdef guard to tigr.c that blocks out WinMain().

2699	#ifndef TIGR_BUILDSHARED // ADD THIS LINE 
2700	// We supply our own WinMain and just chain through to the user's 
2701	// real entry point. 
2702	#ifdef UNICODE 
2703	int CALLBACK wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 
2704	#else 
2705	int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
2706	#endif 
2707	{ 
2708	    int n, argc; 
2709	    LPWSTR* wargv = CommandLineToArgvW(GetCommandLineW(), &argc); 
2710	    char** argv = (char**)calloc(argc + 1, sizeof(int)); 
2711	 
2712	    (void)hInstance; 
2713	    (void)hPrevInstance; 
2714	    (void)lpCmdLine; 
2715	    (void)nCmdShow; 
2716	 
2717	    for (n = 0; n < argc; n++) { 
2718	        int len = WideCharToMultiByte(CP_UTF8, 0, wargv[n], -1, 0, 0, NULL, NULL); 
2719	        argv[n] = (char*)malloc(len); 
2720	        WideCharToMultiByte(CP_UTF8, 0, wargv[n], -1, argv[n], len, NULL, NULL); 
2721	    } 
2722	    return main(argc, argv); 
2723	} 
2724	#endif // ADD THIS LINE 
2725	#endif 

(Note that there will now be two #endif lines after the WinMain() function. The original #endif is from #ifdef _WIN32 up at line 1947.)

Here is a Makefile you can use to build a shared library. Place this in the root of the project directory next to tigr.c and tigr.h.

CFLAGS += -Os -s 
LDFLAGS += -shared 
ifeq ($(OS),Windows_NT) 
	CFLAGS += -DTIGR_SHARED 
	LDLIBS += -lopengl32 -lgdi32 
	LIBEXT := .dll 
else 
	CFLAGS += -fPIC 
	LIBPRE := lib 
	UNAME_S := $(shell uname -s) 
	ifeq ($(UNAME_S),Darwin) 
		LDLIBS += -framework OpenGL -framework Cocoa 
		LIBEXT := .dylib 
	else 
		LDLIBS += -lGLU -lGL -lX11 
		LIBEXT := .so 
	endif 
endif 
 
$(LIBPRE)tigr$(LIBEXT): tigr.c 
	gcc $(CFLAGS) -DTIGR_BUILDSHARED $(LDFLAGS) -o $@ $< $(LDLIBS) 

If you're just building on Windows you can use this simplified version:

tigr.dll: tigr.c 
	gcc -Os -s -DTIGR_SHARED -DTIGR_BUILDSHARED -shared -o $@ $< -lopengl32 -lgdi32 

-Greg

new topic     » goto parent     » topic index » view message » categorize

3. Re: Can't get DLL to Build

Thanks Greg!

I knew the error was coming from the WinMain function, I just couldn't figure out how to fix it. All the searches came up as adding your own WinMain Function. Now I know you don't need a WinMain or main function when building a DLL.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu