none
VS2010 Unresolved External Symbol errors on build (but not rebuild)

    Question

  • Hi,

    I am in the process of moving a solution from VC2008 to VC2010, and I almost have everything working, but I've encountered a strange problem:  If I build from scratch (or do a rebuild) everything works fine, and I can run the program.  If, after that, if I make any change (even just adding whitespace) and try to build, I get a number of LNK2019 and LNK2001 errors (they are always the same).

    I've tried to search online for similar problems, and found many discussions of unresolved external symbol errors, but none where it actually will link properly on a full rebuild.  Is this a problem anyone has seen before and could maybe send some links my way?

    To give a bit more information about my specific situation:

    The unresolved symbol errors all come from static libs, but they are allshould all be built as part of the build process (I have many projects as part of the solution, and most of them become libs).  I can add the whitespace in a file that becomes the final exe, so that the libs don't even change, and I still end up with the errors (even though those same libs worked seconds before).

    Thanks in advance,

    John-Paul

    Thursday, September 02, 2010 4:24 AM

Answers

  • Hello,

    It turned out that this was exactly what was causing my problem, but I still am baffled why it worked with a rebuild but then not with an incremental build.  The fact that a rebuild worked made me think that it wasn't a dependency problem, but I've learned a lot in the last few days as I've been tinkering around with Visual Studio.  In case anyone finds this thread later, I'm going to describe some things I've found, even though you can find the same information in other places (in the three links you provided, for example).

    Instead of setting project dependencies using the old familiar "Project Dependencies..." tool, you should set them in the Properties->Common Properties->Framework and References section of each individual property.  Subtlety #1:  Either way will work, but the old way sets the dependencies in the solution file, and the new way sets them in the project file.  Subtlety #2:  If you set dependencies the new way, these will be reflected in the old "Project Dependencies..." tool, _and_ in the related "Project Build Order..." tool, which is really nice, as long as you remember not to change anything in those tools.

    Even if you have your project dependencies and build order set up correctly, though, it's not enough to duplicate the behavior of previous Visual Studio versions.  If you look at Properties->Configuration Properties->Linker->Command Line of one of your projects, you can see all of the static libraries that are being linked in.  In the old days, if you had other project dependencies that became .libs, those would all be included in the final project.  Now, however, only the immediate project dependencies will do that.  In other words, if A depends on B, and B depends on C, what you _want_ is for A to be linked with B and C, but what you'll _get_ is A is only linked with B.  To get around this, you can use the "Link Library Dependencies" options, either in the project itself or in the individual dependencies you set up.  (I find it easier to set in the project itself, especially because I can then use a property sheet to do it "once", but perhaps there are reasons not to?)  This strategy works fine if you only have a straight line of dependencies, but if A depends on B and C, and B depends on C, then you will now get warning messages from the linker about C being used twice.  You can ignore these, if you want, by adding "/ignore:4006,4221" to the linker command line.  (I'm not sure why Visual Studio doesn't figure it out like it used to, but oh well.)

    Finally, I am a little confused about the "Reference Assembly Output" option when you add a Project reference/dependency.  It seems like most sources recommend setting it to false if all you want is a dependency, but from my experience it doesn't seem to make a difference either way.  At the moment I've left it at the default of true, since it adds less to the project files, and they're already hard enough to read.  It says if true that it will add it to the compiler's command line, but I don't see it there.  If someone understands this better and would be willing to clarify, that would be great.

    I think that's about it.  Like I said, most of what I've said above can be found in other places, but I thought I'd write it all up in one place for anyone who cares.  Thank you very much, Yi, for pointing me in the right direction!

    John-Paul

    • Marked as answer by jonpol2 Monday, September 06, 2010 9:53 AM
    Monday, September 06, 2010 9:53 AM

All replies

  • Hi jonpol2,

    Based on the blog article Visual Studio 2010 C++ Project Upgrade Guide, in VS2010, when a C++ application from a previous version of Visual Studio is converted to VS2010, project dependencies defined at the solution level are converted to project to project references. This change ensures that C++ project dependencies are captured in the project file. Therefore, please use project to project reference instead of solution dependencies when setting up new build dependencies in VS2010 in general.  You need to set project level dependency at Project Properties pages -> Common Properties -> Framework and References. You can add a project as the dependency reference.

    There are some thread also discussed this related issue. May be you can get some idea from these thread.

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/c1553a42-7d1e-4c74-9156-95768a72e4df

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/1874228e-74bc-45c2-8db2-13ab29618058

    http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/d69aeb0d-e5fb-41e1-98ad-9b6c7b43a3ca

    Hope this information helps.

    Cheers,

    Yi


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, September 03, 2010 5:51 AM
    Moderator
  • Hello,

    It turned out that this was exactly what was causing my problem, but I still am baffled why it worked with a rebuild but then not with an incremental build.  The fact that a rebuild worked made me think that it wasn't a dependency problem, but I've learned a lot in the last few days as I've been tinkering around with Visual Studio.  In case anyone finds this thread later, I'm going to describe some things I've found, even though you can find the same information in other places (in the three links you provided, for example).

    Instead of setting project dependencies using the old familiar "Project Dependencies..." tool, you should set them in the Properties->Common Properties->Framework and References section of each individual property.  Subtlety #1:  Either way will work, but the old way sets the dependencies in the solution file, and the new way sets them in the project file.  Subtlety #2:  If you set dependencies the new way, these will be reflected in the old "Project Dependencies..." tool, _and_ in the related "Project Build Order..." tool, which is really nice, as long as you remember not to change anything in those tools.

    Even if you have your project dependencies and build order set up correctly, though, it's not enough to duplicate the behavior of previous Visual Studio versions.  If you look at Properties->Configuration Properties->Linker->Command Line of one of your projects, you can see all of the static libraries that are being linked in.  In the old days, if you had other project dependencies that became .libs, those would all be included in the final project.  Now, however, only the immediate project dependencies will do that.  In other words, if A depends on B, and B depends on C, what you _want_ is for A to be linked with B and C, but what you'll _get_ is A is only linked with B.  To get around this, you can use the "Link Library Dependencies" options, either in the project itself or in the individual dependencies you set up.  (I find it easier to set in the project itself, especially because I can then use a property sheet to do it "once", but perhaps there are reasons not to?)  This strategy works fine if you only have a straight line of dependencies, but if A depends on B and C, and B depends on C, then you will now get warning messages from the linker about C being used twice.  You can ignore these, if you want, by adding "/ignore:4006,4221" to the linker command line.  (I'm not sure why Visual Studio doesn't figure it out like it used to, but oh well.)

    Finally, I am a little confused about the "Reference Assembly Output" option when you add a Project reference/dependency.  It seems like most sources recommend setting it to false if all you want is a dependency, but from my experience it doesn't seem to make a difference either way.  At the moment I've left it at the default of true, since it adds less to the project files, and they're already hard enough to read.  It says if true that it will add it to the compiler's command line, but I don't see it there.  If someone understands this better and would be willing to clarify, that would be great.

    I think that's about it.  Like I said, most of what I've said above can be found in other places, but I thought I'd write it all up in one place for anyone who cares.  Thank you very much, Yi, for pointing me in the right direction!

    John-Paul

    • Marked as answer by jonpol2 Monday, September 06, 2010 9:53 AM
    Monday, September 06, 2010 9:53 AM