Search code examples
c++sconslnk2019libs

Config Libs produced by scons construction tool introducing LNK2019


We are using SCons build our project, including things like producing static libraries and Visual Studio project files (.sln, .vcxproj). In the SConstruct file (written in Python), we specify:

CCFLAGS=['/Od','/Zi','/EHsc','/W3']
env=Environment(ENV=ENV,CPPPATH=include_path,CCFLAGS=CCFLAGS,MSVS_ARCH=arc,TARGET_ARCH=arc)   
lib=env.StaticLibrary(target=lib_file,source=lib_src_files)
proj=env.MSVSProject(target=name+env['MSVSPROJECTSUFFIX'],srcs=lib_src_files,incs=lib_header_files,buildtarget=lib,variant=build_type,auto_build_solution=0)

to produce our VS project files and static libraries. Everything goes ok and we finally get our libraries. But when we use these libraries as Third-Party Libraries in our other custom projects, it produces a lnk2009 error:

error   1   error LNK2019: unresolved external symbol "public: virtual
__thiscall Physika::Vector<double,3>::~Vector<double,3>(void)" (??1?$Vector@N$02@Physika@@UAE@XZ),referenced in function
_tmain()    C:\Users\suitmyself\documents\visual studio 2010\Projects\Physika_config\Physika_config\vector3d_test.obj

error   2   error LNK2019: unresolved external symbol "public: __thiscall Physika::Vector<double,3>::Vector<double,3>(double,double,double)" (??0?$Vector@N$02@Physika@@QAE@NNN@Z),referenced in function 
_tmain()    C:\Users\suitmyself\documents\visual studio 2010\Projects\Physika_config\Physika_config\vector3d_test.obj

Note that the VS projects here are generated manually. We are sure to include the path (head files) and library path, library files are configured with no error, and the library files are found correctly. It seems that the .obj simply can't match the right symbol in the library files, which results in this lnk error.

The strange thing, however, is that if we use SCons to construct our VS project and specify CCFLAGS as above, everything works fine with no lnk error detected and an EXE produced normally.

So why does this error appear?


Solution

  • The question indeed arises from the setting of custom vs proj settings, there are three cases in which the config will pass the linker:

    1: In Release Mode, \MT specified
    2: In Release Mode, \MTd specified, add "ITERATOR_DEBUG_LEVEL=0" in preprocessor definiton.
    3: In Debug Mode, \MTd specified, add "ITERATOR_DEBUG_LEVEL=0" in preprocessor definiton.

    Note that in Debug Mode, specifing a compile option \MT will not pass the linker, the exact reason is still unclear, but it does not work if you do this.(some LNK error 2001 and 2005 occur).

    It seems that ITERATOR_DEBUG_LEVEL is default to 0 by Scons, compared to a default value of 0 in release mode and a default value of 2 in debug mode for default vs setting. Addtionally, I suspect that \MTd is set defaultly by Scons. Any user employing Scons should be with great caution of this.