0

I was following this tutorial on how to create a static library and the author defines a function(for the library) in the lib_mylib.c as:

#include <stdio.h> //Although I use <iostream>
void fun(void) 
{ 
  printf("fun() called from a static library"); 
}

He goes ahead and simply compiles this as:

 gcc -c lib_mylib.c -o lib_mylib.o 

Notice that there's no main() defined which would be the default entry point for the programs but he mentions nothing about that, and to me it seems logical because libraries are not exactly stuff we run, but something we include for our programs to run and hence our source code should be the one to have the main() function.

But, the minGW g++ compiler says this:

c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status

and according to this question I am not defining the main and the error does seem to go away once I define the main() function. Can anyone please explain to me what is going under the hood and demistify this confusion.

PS: It'd be really helpful if you mention any resources for such learning. Thanks in advance.

mathmaniage
  • 299
  • 1
  • 14

2 Answers2

4

Answering your question: No, you don't need to define a main entry point for a library.

The key here is the -c option from gcc, which skips the linking stage.

From the gcc manual

-c : Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.

You can consult more gcc options here.

Judging form your error output, you probably forgot to add this option, because you are getting a linker error.

PS: I find that the tutorial your are following has a good introductory explanation on this topic.

EDIT

Your problem is related with the difference between compiling an linking.

C programs are written in human readable source code that is not directly executable by a computer. It takes a three step process to transform the source code into executable code. These three steps are: Preprocessing, compiling and linking

Preprocessing - Processes directives (commands that begin with a # character) which can modify the source code before it is compiled.

Compiling - The modified source code is compiled into binary object code. This code is not yet executable.

Linking - The object code is combined with required supporting code to make an executable program. This step typically involves adding in any libraries that are required.

Here you can find an interesting tutorial on basic C concepts.

jpuriol
  • 362
  • 2
  • 14
  • but the `-o` flag, isn't it also for compiling and linking even for C? – mathmaniage Mar 06 '20 at 07:23
  • I actually hadn't added the `-c` flag but, in the above tut, he also uses the -o flag when the `main()` isn't defined , isn't that also supposed to do the linking and give an error? – mathmaniage Mar 06 '20 at 07:27
  • With `-o` flag you just indicate the name of the output file. If you are building an static library you should postpone the linking stage until you are building the application that actually runs. – jpuriol Mar 06 '20 at 07:34
  • then how do you specifiy explicitly you actually want to link it to an executable? – mathmaniage Mar 06 '20 at 07:40
  • Don't use the `-c` option. In the tutorial you were following when you execute this command: `gcc -o driver driver.o -L. -l_mylib` your al linking it all into one single executable file called `driver`. – jpuriol Mar 06 '20 at 07:47
1

When you want to compile a shared library, you do not need an entry point. An entry point is only needed for executables so that the operating system knows what code to execute when it loads your binary.

In order to compile a library, you need to compile in position independent code.

gcc -c -fpic lib_mylib.c -o lib_mylib.o

This should get you no linking errors. Then creating an actual shared library from this object file, you need to run:

gcc -shared -o lib_mylib.so lib_mylib.o

Please tell me if this does not lead to the expected results.

Victor
  • 13,914
  • 19
  • 78
  • 147
  • if we cannot `link`(i.e. create the executable) without the `main()` function, then why do we add the `-o` flag? `-c` means compile only and `-o` means compile and link, right? – mathmaniage Mar 06 '20 at 07:30
  • No, that is not what the option means. Here is an excerpt of the GCC docs for “-o”: *Place output in file file. This applies regardless to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.* – Victor Mar 06 '20 at 09:27