Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need an *.obj file when statically linking?

I'm not sure why is this. I'm distributing a static *.lib across multiple projects, but this static lib generates many *.obj files. Seems like I need to distribute also those *.obj files with the *.lib. Otherwise, I get this error:

1>LINK : fatal error LNK1181: cannot open input file 'nsglCore.obj'

Why is this? Is there a way to include the data in the *.obj files in the *.lib? Maybe a switch in the compiler?

This is my config for the static library:

C/C++

/Od /GT /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /MD /Yu"stdafx.hpp" /Fp"e:\Development\Projects\nsGameLib\Source\Core\Intermediate\nsglCore-Win32-Release.pch" /Fo"e:\Development\Projects\nsGameLib\Source\Core\Intermediate\\" /Fd"e:\Development\Projects\nsGameLib\Source\Core\Intermediate\vc90-Release.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt

Librarian

/OUT:"e:\Development\Projects\nsGameLib\Source\Core\Output\nsglCore-Win32-Release.lib" /NOLOGO /LTCG

This is my config for the project using the static library:

C/C++

/O2 /Oi /I "E:\Development\Projects\nsGameLib\Samples\\DummyEngine\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /FD /EHsc /MD /Gy /Fo"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\\" /Fd"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\vc90-Release.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt

Linker

/OUT:"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Output\SampleOnlyCore-Win32-Release.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:"E:\Development\Projects\nsGameLib\Samples\..\Deployment\Libraries" /MANIFEST /MANIFESTFILE:"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\SampleOnlyCore-Win32-Release.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\SampleOnlyCore-Win32-Release.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /LTCG /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT nsglCore  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
like image 523
Jorjon Avatar asked May 21 '09 01:05

Jorjon


3 Answers

I believe that your linker line is incorrect. The library should have a .lib suffix on it. So nsglCore should be nsglCore-Win32-Release.lib or maybe nsglCore-$(TargetPlatform)-$(ConfigurationName).lib or whatever the correct macro expansion is.

like image 152
D.Shawley Avatar answered Oct 11 '22 17:10

D.Shawley


Generally, static libs do not generate object files. What you do is create object files and place them in a library, then the linker will search for the object files in those libraries.

I'll explain from a UNIXy command line point of view since that's the simpler to understande (I have no idea what machinations VS does before doing the basic stuff).

A sample command line for creating an executable is:

gcc -c -o prog.o prog.c
gcc -o prog prog.o -L/libdir -lstdc

The first line simply creates an object file from your C file. The second line creates the executable by pulling object files together, generally following a rule set like:

  • All .o file listed explicitly are linked.
  • Once that's done, you search the libraries for other objects which satisfy referenced-but-undefined symbols.

For example, say your prog.c contained the line printf("hello\n");. That will have resulted in your prog.o file containing a reference to printf that is not yet satisfied.

The linker will search your specified libraries until it satisfies that reference. In this case it will search all files of the form /libdir/libstdc.ext where:

  • /libdir is from your -L option (a path to search for libraries in).
  • /lib is a constant.
  • stdc is the name of a library to search (from -l).
  • ext is one or more extensions (.a, .so, .sl, etc).

Once the symbol is found, that object file is linked in to resolve it. This may result in more unsatisfied symbols appearing such as /libdir/libstdc.a(printf.o) having a reference to /libdir/libstdc.a(putch.o).

Your particular problem may be caused by the fact that you're trying to link the object file directly rather than searching the libraries. VS should have project options to specify object files, library search paths and library names (I'm not sure of this for the latest versions but I know earlier versions of MSVC did).

like image 24
paxdiablo Avatar answered Oct 11 '22 16:10

paxdiablo


Ah... Visual studio is being too clever for you

Go to the projects that include the lib, right click for properties

Goto Configuration Properties | Linker

Near the bottom : Use Library Dependancy Inputs - Set to No

This is a Visual Studio option to grab the .obj files directly rather than the .lib file. I imagine it is to avoid the link step and thus speed up the compile.

In general, you should set the project that creates the lib file as a dependancy of the project that uses it (under common properties in that properties window). You then turn on Link Library Dependancies. This works well in most cases.

like image 39
Tom Leys Avatar answered Oct 11 '22 16:10

Tom Leys