Code::Blocks Forums

User forums => Using Code::Blocks => Topic started by: leeya on April 12, 2007, 04:46:26 pm

Title: How to build a static lib ?
Post by: leeya on April 12, 2007, 04:46:26 pm
I create a project of static lib, and write a basic win32 app.  I want to static lib.
The project structure is following:

│  RSWL2GCC.cbp

├─Win
│      WinMain.h
│      WinMain.cpp

└─obj
    └─Debug
        └─Win

WinMain.h is defined:
#ifndef WINMAIN_H
#define WINMAIN_H

#include <windows.h>

namespace Win
{
   
   int Main (INSTANCE inst, char const * cmdParam, int cmdShow);

}


#endif // WINMAIN_H

WinMain.cpp is defined:
#include <windows.h>
#include <Win/WinMain.h>

int WINAPI WinMain
   (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdParam, int cmdShow)
{
   return Win::Main (hInst, cmdParam, cmdShow);
}


I build the project , get error message :

:: === RSWL2GCC, Debug ===
D:\CodeWorld\RSWL2GCC\Win\WinMain.cpp:2: Win/WinMain.h: No such file or directory
D:\CodeWorld\RSWL2GCC\Win\WinMain.cpp:7: error: `Win' has not been declared
D:\CodeWorld\RSWL2GCC\Win\WinMain.cpp:7: error: `Main' was not declared in this scope
D:\CodeWorld\RSWL2GCC\Win\WinMain.cpp:7: warning: unused variable 'Main'
:: === Build finished: 3 errors, 1 warnings ===

Why I failed ?



Title: Re: How to build a static lib ?
Post by: SamT on April 12, 2007, 04:59:58 pm

D:\CodeWorld\RSWL2GCC\Win\WinMain.cpp:2: Win/WinMain.h: No such file or directory

GCC can't find your WinMain.h. Have you try to add some path information into Project->Build Options->Search Directories->Compiler ?
Title: Re: How to build a static lib ?
Post by: leeya on April 12, 2007, 05:19:49 pm
 :D
You are the best!
Thank You!

I add the search path to project, all is right; I has generated "libRSWL2GCC.a" file successfully.
I have another problem, how to specify the name and path of the generated static lib file name in C::B ?
for instance, i want the .a file under "%working directroy%/lib" and named "RSWL2GCCD.a".


Title: Re: How to build a static lib ?
Post by: TDragon on April 12, 2007, 06:05:11 pm
I have another problem, how to specify the name and path of the generated static lib file name in C::B ?
In the "Build targets" section of the project options (select Properties from the Project menu or the project's right-click context menu), see "Output filename".

Quote
for instance, i want the .a file under "%working directroy%/lib" and named "RSWL2GCCD.a".
GCC and MinGW encourage developers to prefix import libraries with "lib", and I think this is a good thing. Code::Blocks will do this for you automatically, but if you really want to you can disable this by unchecking the "Auto-generate filename prefix" box.
Title: Re: How to build a static lib ?
Post by: leeya on April 13, 2007, 04:09:39 pm
Thanks~~
I have find the configuration of static lib;

I create a new project called "UnitTest", the Main.cpp file defined as following:

#include <Win/WinMain.h>

int Win::Main (HINSTANCE hInst, char const * cmdParam, int cmdShow)
{

   return 0;
}

I want libRSWL2GCC.a to compile with  project "UnitTest", so  could run a basic win32 application.
how can i add libRSWL2GCC.a to my "UnitTest" project?

My file compositon structure was as following:
D:\CODEWORLD\RSWL2GCC
│  WinLibBase.h
│  RSWL2GCC.depend
│  libRSWL2GCC.a
│  RSWL2GCC.cbp
│  RSWL2GCC.layout

├─Win
│      WinMain.cpp
│      WinMain.h

├─obj
│  └─Debug
│      └─Win
│              WinMain.o

└─UnitTest
    │  UnitTest.cbp
    │  UnitTest.layout
    │  UnitTest.depend
    │  Main.cpp
    │
    ├─obj
    │  └─Debug
    │          Main.o
    │
    └─bin
        └─Debug


I configure complier search path to "D:\CODEWORLD\RSWL2GCC",so that compiler find the file;
Build project and get error message:


C:\MinGW\lib\libmingw32.a(main.o):main.c:(.text+0x106):: undefined reference to `WinMain@16'
:: === Build finished: 1 errors, 0 warnings ===

It obviously show that "UnitTest" could not find the program entry point; but i have defined that in libRSWL2GCC.a;

why i failed ?
Title: Re: How to build a static lib ?
Post by: TDragon on April 14, 2007, 12:00:08 am
Is "RSWL2GCC" in your link libraries? Post your build log after enabling full command line logging (Settings->Compiler and debugger->Global compiler settings->Other settings->Compiler logging).
Title: Re: How to build a static lib ?
Post by: leeya on April 14, 2007, 04:07:36 am
Is "RSWL2GCC" in your link libraries? Post your build log after enabling full command line logging (Settings->Compiler and debugger->Global compiler settings->Other settings->Compiler logging).

I enabled the build log by your instruction, I build the RSWL2GCC again, get informtion as following:

-------------- Build: Debug in RSWL2GCC ---------------
mingw32-g++.exe -Wall -g  -ID:\CodeWorld\RSWL2GCC\ -ID:\CodeWorld\RSWL2GCC\Win -IC:\MinGW\include  -c D:\CodeWorld\RSWL2GCC\Win\WinMain.cpp -o obj\Debug\Win\WinMain.o
ar.exe -r -s libRSWL2GCC.a obj\Debug\Win\WinMain.o
Process terminated with status 0 (0 minutes, 1 seconds)
0 errors, 0 warnings

where can i add libRSWL2GCC.a into my UnitTest project ?

I build UnitTest project , the build log show :

-------------- Build: Debug in UnitTest ---------------
mingw32-g++.exe -Wall -g  -ID:\CodeWorld\RSWL2GCC -IC:\MinGW\include  -c D:\CodeWorld\RSWL2GCC\UnitTest\Main.cpp -o obj\Debug\Main.o
mingw32-g++.exe -LC:\MinGW\lib  -o bin\Debug\UnitTest.exe obj\Debug\Main.o   
C:\MinGW\lib/libmingw32.a(main.o):main.c:(.text+0x106): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 1 seconds)
1 errors, 0 warnings

Title: Re: How to build a static lib ?
Post by: SamT on April 14, 2007, 04:41:02 am
undefined reference to `WinMain@16'

the winmain is designed by yourself, you need to link the library when you want to generate exectuive file.

There are two ways to add library in a project.
1. Add path information where can find the library in Project->Build Options->Search Directories->linker
Then add the library name in Project->Build Options->Linker settings->add link libraries

2. set full path, library name directly in Project->Build Options->Linker settings->add link libraries

Benfit of method 1: you can set the path information with "global variable", ex: there is a global variable "wx" = C:\wxWidgets-2.8.3, you can put your path information with $(#wx)/include, $(#wx)/lib... Just need to change the value of wx, you change everything.
Benfit of method 2: easy to use. You can know which library you link exactly since all the path and libary name are put together.

It's your choose to include the link library. Thanks C::B for it's flexibility.
Title: Re: How to build a static lib ?
Post by: leeya on April 14, 2007, 02:14:50 pm
Thanks for your detail instruction!

2. set full path, library name directly in Project->Build Options->Linker settings->add link libraries

I add the libRSWL2GCC.a lib in my project according to your way 2, but after building the project again, i get trapped :

-------------- Build: Debug in UnitTest ---------------
mingw32-g++.exe -LC:\MinGW\lib  -o bin\Debug\UnitTest.exe obj\Debug\Main.o    D:\CodeWorld\RSWL2GCC\libRSWL2GCC.a  
C:\MinGW\lib/libmingw32.a(main.o):main.c:(.text+0x106): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 2 seconds)
1 errors, 0 warnings

Libarary libRSWL2GCC.a  file was found in building process, however, the error message are still the same.
Why? :(

In libRSWL2GCC.a file, the WinMain,the program entry point, was defined.
Title: Re: How to build a static lib ?
Post by: TDragon on April 14, 2007, 05:13:45 pm
A Google search for "mingw WinMain in static library" turned up this post (http://cygwin.com/ml/cygwin/2004-03/msg00194.html), which has the following to say:
Quote
To resolve _WinMain@16 with a symbol from your library, it needs to come *after* the library that needs it (/usr/i686-pc-mingw32/lib/libmingw32.a). Unfortunately (for you), gcc/g++ puts all the default libraries *last* when it calls ld.  You need to override that order.

Since the default library in question is libmingw32.a, all we need to do is make sure it's linked before your library containing the WinMain. The easiest way to do this is add it to your project's Link libraries, before your RSWL2GCC library. Just add "mingw32" and move it above RSWL2GCC, and it should work.
Title: Re: How to build a static lib ?
Post by: leeya on April 14, 2007, 05:50:12 pm
Thanks for your wonderful solution~~~ :D :D
You are the best!
Title: Re: How to build a static lib ?
Post by: leeya on April 23, 2007, 05:38:43 pm
I switch compiler from gcc to vc7.1 in C::B;
I rebuild the project again and get error message, the build log as following:
.......
link.exe /nologo /LIBPATH:D:\CodeWorld\RSWL2VC\lib\Debug /LIBPATH:C:\VCToolkit2003\lib  /out:bin\Debug\UnitTest.exe libRSWL2GCCD.lib  obj\Debug\precompiled.o obj\Debug\Main.o   
LIBC.lib(crt0.obj) : error LNK2019: unresolved external symbol _main referenced in function _mainCRTStartup
bin\Debug\UnitTest.exe : fatal error LNK1120: 1 unresolved externals
Process terminated with status 1120 (0 minutes, 31 seconds)
2 errors, 903 warnings

The error reason was the same as gcc up!
The program entry point was in libRSWL2GCCD.lib, in fact the link could not find the program entry point in libRSWL2GCCD.lib;

can you help me ?
Title: Re: How to build a static lib ?
Post by: TDragon on April 23, 2007, 06:08:41 pm
I'm not at a PC with MSVC installed right now, but I think the reason for that error is that link.exe needs an extra option to let it know to create a Win32 app with WinMain as the entry point rather than a console app with main as the entry point.

I believe this should be fixed by adding "/SUBSYSTEM:WINDOWS" in the "Other linker options" box of your project's Linker settings.
Title: Re: How to build a static lib ?
Post by: leeya on April 24, 2007, 08:38:56 am
It is successful for linking the static lib by adding "/SUBSYSTEM:WINDOWS", but the Win::Main could not run properly in Main.cpp. The file was defined as following:

#include "precompiled.h"
#include <iostream>

int Win::Main (HINSTANCE hInst, char const * cmdParam, int cmdShow)
{

    std::cout << "Hello World!" << std::endl;
    std::cout << "OK!!!!!!!!!!!!!" << std::endl;
    return 0;
}

It could not print the statements "Hello World!" and "OK!!!!!!!!!!!!!" .

The static lib WinMain was defined:
#include <WinLibBase.h>

int WINAPI WinMain
   (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdParam, int cmdShow)
{

   return Win::Main (hInst, cmdParam, cmdShow);
}

Title: Re: How to build a static lib ?
Post by: TDragon on April 24, 2007, 02:46:12 pm
Microsoft's compiler takes the view that if you create a program with WinMain() as the entry point, you want to create a Windows GUI program, without a console for text I/O, and that if you create a program with main() as the entry point, you want to create a console program. This is generally true for the most part; in fact I can't see why you would need to use both WinMain() and std::cout. In other words, if all your program does is print to the console, why not use main()? Or if your program is going to be a GUI program, why not use other methods of displaying output?

Nevertheless, helpful guy that I am, I do know a way to keep a console open when WinMain is the entry point.
 - Change "/SUBSYSTEM:WINDOWS" to "/SUBSYSTEM:CONSOLE"
 - Add, to the same text field, "/ENTRY:WinMainCRTStartup"
Title: Re: How to build a static lib ?
Post by: leeya on April 24, 2007, 03:35:47 pm
Thanks for your detail explaination!
I was newbie to C++ and Win32, so I got a open-source win32 library --RSWL to study from start and improve my skill on C++ and Win32.
I had 'googled' this problem, but still miss the parameter--"/ENTRY:WinMainCRTStartup".

I has a long road to C++ and Win32, thanks for your help sincerely again.
Title: Re: How to build a static lib ?
Post by: leeya on April 24, 2007, 03:54:47 pm
BTW, why i could not download GCC 4.1.2 for MinGW from the link "http://files.filefront.com/gcc_412_i386_pc_mingw327z/;7025990;/fileinfo.html/11/1"

I got the information from your signature.
Title: Re: How to build a static lib ?
Post by: TDragon on April 24, 2007, 04:13:07 pm
BTW, why i could not download GCC 4.1.2 for MinGW from the link "http://files.filefront.com/gcc_412_i386_pc_mingw327z/;7025990;/fileinfo.html/11/1"
I don't know; the download works fine for me.

To quote a reply I made to another person recently who also had problems:
Quote
However, I believe you can also download the binary package at http://farfetch.intrepid.cx/gcc-4.1.2-i386-pc-mingw32.7z, and the source package at http://farfetch.intrepid.cx/gcc-4.1.2-i386-pc-mingw-src.7z. (Warning: That server may not return the proper mime headers; if you get a page of gibberish, try right-clicking the link and selecting Save As.)
Hope that helps.
Title: Re: How to build a static lib ?
Post by: leeya on April 24, 2007, 04:17:19 pm
 :D
You are right!
I should make right-clicking the link and Save as.
Title: Re: How to build a static lib ?
Post by: leeya on May 09, 2007, 03:48:45 pm
I changed my compiler to gcc 4.1.2, then rebuild my project.
However I get error message:

-------------- Build: Debug in UnitTest ---------------
mingw32-g++.exe -Wall -W -g  -ID:\CodeWorld\RSWL2GCC -ID:\CodeWorld\RSWL2GCC\UnitTest\ -IC:\MinGW\include  -c D:\CodeWorld\RSWL2GCC\UnitTest\precompiled.cpp -o obj\Debug\precompiled.o
mingw32-g++.exe -Wall -W -g  -ID:\CodeWorld\RSWL2GCC -ID:\CodeWorld\RSWL2GCC\UnitTest\ -IC:\MinGW\include  -c D:\CodeWorld\RSWL2GCC\UnitTest\Main.cpp -o obj\Debug\Main.o
c:/mingw/bin/../lib/gcc/mingw32/4.1.2/../../../../include/c++/4.1.2/cwctype:89: error: '::iswblank' has not been declared

D:\CodeWorld\RSWL2GCC\UnitTest\Main.cpp:4: warning: unused parameter 'hInst'
D:\CodeWorld\RSWL2GCC\UnitTest\Main.cpp:4: warning: unused parameter 'cmdParam'
D:\CodeWorld\RSWL2GCC\UnitTest\Main.cpp:4: warning: unused parameter 'cmdShow'
Process terminated with status 1 (0 minutes, 3 seconds)
1 errors, 3 warnings

Why ?
Title: Re: How to build a static lib ?
Post by: TDragon on May 11, 2007, 09:15:52 pm
Sorry I took so long getting back to you on this. The long and the short of it is, I don't know a certain answer. I suspect that it has something to do with incomplete wide-char support in GCC/mingw32. To try for a workaround of some sort, I would need more context information.
Title: Re: How to build a static lib ?
Post by: Deschamps on May 13, 2007, 12:09:32 am
Quote from: leeya
(..) cwctype:89: error: '::iswblank' has not been declared (..)

As TDragon has said, it seems that MinGW doesn't support wide-char types for now. I've read somewhere that you could try undefining _GLIBCXX_HAVE_ISWBLANK in your [$MINGW]/include/c++/3.4.2/mingw32/bits/c++config.h, unless you need it for some reason.