views:

645

answers:

4

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
+2  A: 

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.

Tom Leys
I have this set to no already.
Veehmot
+3  A: 

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).

paxdiablo
Nice post. It does sound like a MSVC config issue though.
Tom Leys
Thanks for this, very useful information, but this does not resolve my problem. I want to know a way to avoid the *.obj dependency.
Veehmot
+1  A: 

My mistake:

nsglCore instead of nsglCore.lib

Thanks for your time.

Veehmot
+4  A: 

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.

D.Shawley
20 seconds after I found it out! See my post. But, this is the answer ;)
Veehmot