Author Topic: How to build a static lib ?  (Read 17322 times)

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
How to build a static lib ?
« 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 ?




Offline SamT

  • Multiple posting newcomer
  • *
  • Posts: 41
Re: How to build a static lib ?
« Reply #1 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 ?

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
Re: How to build a static lib ?
« Reply #2 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".


« Last Edit: April 12, 2007, 05:33:17 pm by leeya »

Offline TDragon

  • Lives here!
  • ****
  • Posts: 943
    • TDM-GCC
Re: How to build a static lib ?
« Reply #3 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.
https://jmeubank.github.io/tdm-gcc/ - TDM-GCC compiler suite for Windows (GCC 9.2.0 2020-03-08, 32/64-bit, no extra DLLs)

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
Re: How to build a static lib ?
« Reply #4 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 ?

Offline TDragon

  • Lives here!
  • ****
  • Posts: 943
    • TDM-GCC
Re: How to build a static lib ?
« Reply #5 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).
https://jmeubank.github.io/tdm-gcc/ - TDM-GCC compiler suite for Windows (GCC 9.2.0 2020-03-08, 32/64-bit, no extra DLLs)

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
Re: How to build a static lib ?
« Reply #6 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



Offline SamT

  • Multiple posting newcomer
  • *
  • Posts: 41
Re: How to build a static lib ?
« Reply #7 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.

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
Re: How to build a static lib ?
« Reply #8 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.

Offline TDragon

  • Lives here!
  • ****
  • Posts: 943
    • TDM-GCC
Re: How to build a static lib ?
« Reply #9 on: April 14, 2007, 05:13:45 pm »
A Google search for "mingw WinMain in static library" turned up this post, 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.
https://jmeubank.github.io/tdm-gcc/ - TDM-GCC compiler suite for Windows (GCC 9.2.0 2020-03-08, 32/64-bit, no extra DLLs)

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
Re: How to build a static lib ?
« Reply #10 on: April 14, 2007, 05:50:12 pm »
Thanks for your wonderful solution~~~ :D :D
You are the best!

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
Re: How to build a static lib ?
« Reply #11 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 ?

Offline TDragon

  • Lives here!
  • ****
  • Posts: 943
    • TDM-GCC
Re: How to build a static lib ?
« Reply #12 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.
https://jmeubank.github.io/tdm-gcc/ - TDM-GCC compiler suite for Windows (GCC 9.2.0 2020-03-08, 32/64-bit, no extra DLLs)

Offline leeya

  • Multiple posting newcomer
  • *
  • Posts: 16
Re: How to build a static lib ?
« Reply #13 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);
}



Offline TDragon

  • Lives here!
  • ****
  • Posts: 943
    • TDM-GCC
Re: How to build a static lib ?
« Reply #14 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"
https://jmeubank.github.io/tdm-gcc/ - TDM-GCC compiler suite for Windows (GCC 9.2.0 2020-03-08, 32/64-bit, no extra DLLs)