Skip to content

PredefinedMainEntryPointInsideStaticLibrary

alexcham edited this page Jul 28, 2015 · 8 revisions

Note: extern declarations was skipped by github mediawiki markup parsers, open edit mode to see the full source code

Table of Contents

Predefined Main Entry Point Inside Static Library

Static Library

static library or statically-linked library is a set of routines, external functions and variables which are resolved in a caller at compile-time and copied into a target application by a compiler, linker, or binder, producing an object file and a stand-alone executable

Any static library function can call a function or procedure in another static library. The linker and loader handle this the same way as for kinds of other object files. Static library files may be linked at run time by a linking loader (Linker)

https://en.wikipedia.org/wiki/Static_library#Linking_and_loading

External Linkage

If the name has external linkage, the entity that name denotes may be referred to from another translation unit using a distinct declaration for that same name, and from other scopes within the same translation unit using distinct declarations

https://en.wikipedia.org/wiki/Linkage_%28software%29

extern is useful for declaring variables that you want to be visible to all source files that are linked into your project

A declared object can be visible only within a particular function, or within a particular file, or may be visible to an entire set of files by way of including header files and using extern declarations

http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html

Project Layout

 ./Common
 ./Common/CMakeLists.txt
 ./Common/Source
 ./Common/Source/esUtil.cpp
 ./Common/Source/LinuxX11
 ./Common/Source/LinuxX11/esUtil_X11.cpp
 ./Common/Source/External.cpp

esUtil_X11.cpp

One of our example static library translation units where main entry point was predefined

extern void foo(); int main(){ foo(); return 0; }


This is how main & extern are realy defined in gles-book framework

./Common/Source/LinuxX11/esUtil_X11.c

 //      Main entrypoint for application
 //
 int main ( int argc, char *argv[] )
 {
    ESContext esContext;
    
    memset ( &esContext, 0, sizeof( esContext ) );
 
 
    if ( esMain ( &esContext ) != GL_TRUE )
       return 1;   
  
    WinLoop ( &esContext );
 
    if ( esContext.shutdownFunc != NULL )
 	   esContext.shutdownFunc ( &esContext );
 
    if ( esContext.userData != NULL )
 	   free ( esContext.userData );
 
    return 0;
 }

External.cpp

Our foo() implementation which should be called according to logic predefined by main

 */
 #include <iostream>
 
 void foo(){
 	std::cout << "hello world!" << std::endl;
 }
 

CMakeLists.txt

 # Predefine translation units for static library
 set ( common_src Source/esUtil.cpp )
 set( common_platform_src Source/LinuxX11/esUtil_X11.cpp )
 
 # Cause CompilationToolchain to produce static library from predefined translation units
 add_library( Common STATIC ${common_src} ${common_platform_src} )
 
 # Cause Compiler to produce object file from translation unit where external foo() was implemented
 add_executable(External Source/External.cpp)
 
 # Cause Linker to produce executable linked against static library where main was predefined
 target_link_libraries(External Common)

Build Configuration

 $ mkdir build
 $ cd build/
 $ cmake ../Common/

Build Runtime

 [100%] Building CXX object CMakeFiles/External.dir/Source/External.cpp.o
 /usr/bin/c++     -o CMakeFiles/External.dir/Source/External.cpp.o -c /home/alex/dev/eclipse/cdt/workspace/ExternKeyword/Common/Source/External.cpp
 Linking CXX executable External
 ...
 /usr/bin/c++      CMakeFiles/External.dir/Source/External.cpp.o  -o External -rdynamic libCommon.a
 ...
 [100%] Built target External

Execution Time

Main was copied in our standalone executable which could be executed as always

 $ ./External 
 hello world!

Executable Objdump

Here we can see that main entry point was copied to our executable

 External:     file format elf64-x86-64
 External
 architecture: i386:x86-64, flags 0x00000112:
 EXEC_P, HAS_SYMS, D_PAGED
 start address 0x0000000000400930
 
 Program Header:
     PHDR off    0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3
          filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags r-x
   INTERP off    0x0000000000000200 vaddr 0x0000000000400200 paddr 0x0000000000400200 align 2**0
          filesz 0x000000000000001c memsz 0x000000000000001c flags r--
     LOAD off    0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
          filesz 0x0000000000000ce4 memsz 0x0000000000000ce4 flags r-x
     LOAD off    0x0000000000001000 vaddr 0x0000000000601000 paddr 0x0000000000601000 align 2**21
          filesz 0x0000000000000290 memsz 0x00000000000003b8 flags rw-
  DYNAMIC off    0x0000000000001020 vaddr 0x0000000000601020 paddr 0x0000000000601020 align 2**3
          filesz 0x0000000000000200 memsz 0x0000000000000200 flags rw-
     NOTE off    0x000000000000021c vaddr 0x000000000040021c paddr 0x000000000040021c align 2**2
          filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
 EH_FRAME off    0x0000000000000b44 vaddr 0x0000000000400b44 paddr 0x0000000000400b44 align 2**2
          filesz 0x000000000000004c memsz 0x000000000000004c flags r--
    STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
          filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
 
 Dynamic Section:
   NEEDED               libstdc++.so.6
   NEEDED               libm.so.6
   NEEDED               libgcc_s.so.1
   NEEDED               libc.so.6
   INIT                 0x0000000000400880
   FINI                 0x0000000000400b24
   ...
 
 Version References:
   required from libc.so.6:
     0x09691a75 0x00 03 GLIBC_2.2.5
   required from libstdc++.so.6:
     0x08922974 0x00 02 GLIBCXX_3.4
 ...
 SYMBOL TABLE:
 ...
 0000000000400880 l    d  .init	0000000000000000              .init
 ...
 0000000000400b24 l    d  .fini	0000000000000000              .fini
 ...
 0000000000000000 l    df *ABS*	0000000000000000              crtstuff.c
 ...
 0000000000000000 l    df *ABS*	0000000000000000              External.cpp
 ...
 0000000000000000 l    df *ABS*	0000000000000000              esUtil_X11.cpp
 ...
 0000000000400a9a g     F .text	0000000000000010              main
 0000000000400880 g     F .init	0000000000000000              _init