-
Notifications
You must be signed in to change notification settings - Fork 750
PredefinedMainEntryPointInsideStaticLibrary
Note: extern declarations was skipped by github mediawiki markup parsers, open edit mode to see the full source code
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
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
./Common ./Common/CMakeLists.txt ./Common/Source ./Common/Source/esUtil.cpp ./Common/Source/LinuxX11 ./Common/Source/LinuxX11/esUtil_X11.cpp ./Common/Source/External.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; }
Our foo() implementation which should be called according to logic predefined by main
*/ #include <iostream> void foo(){ std::cout << "hello world!" << std::endl; }
# 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)
$ mkdir build $ cd build/ $ cmake ../Common/
[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
Main was copied in our standalone executable which could be executed as always
$ ./External hello world!
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