none
Incremental linking broken with WHOLEARCHIVE

    Question

  • Hi,

    I am using the /WHOLEARCHIVE option when linking a static lib, however with this option changes made to the static lib aren't linked into the final executable unless I rebuild the whole solution. The equivalent option with the GCC toolchain (--whole-archive) works as expected.

    John Chapman.

    • Moved by qing__ Friday, January 06, 2017 5:16 AM related to C++
    Thursday, January 05, 2017 5:19 PM

All replies

  • Hi John Chapman,

    This forum is discussing Visual Studio WPF/SL Designer, Visual Studio Guidance Automation Toolkit, Developer Documentation and Help System, and Visual Studio Editor.

    Your issue is related to c++, I will move this thread to corresponding forum for a professional answer.

    Sincerely,

    Oscar


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, January 06, 2017 5:16 AM
  • Hi john-chapman,

    thanks for posting here.

    >>I am using the /WHOLEARCHIVE option when linking a static lib, however with this option changes made to the static lib aren't linked into the final executable unless I rebuild the whole solution. The equivalent option with the GCC toolchain (--whole-archive) works as expected.

    By default, the linker includes object files in the linked output only if they export symbols referenced by other object files in the executable. The /WHOLEARCHIVE option makes the linker treat all object files archived in a static library as if they were specified individually on the linker command line.

    For more information about this compiler option, please refer to this document below.

    https://msdn.microsoft.com/en-us/library/mt732963.aspx

    Best Regards,

    Sera Yu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, January 06, 2017 8:57 AM
    Moderator
  • Hi - thanks for the response.

    The /WHOLEARCHIVE option makes the linker treat all object files archived in a static library as if they were specified individually on the linker command line.

    Yes, that's exactly what I expect to happen - however my issue is that with /WHOLEARCHIVE enabled, changes to the static lib which affect one object file aren't reflected in the final exe unless I rebuild the whole project.

    John.



    Friday, January 06, 2017 11:35 AM
  • See the discussion at https://blogs.msdn.microsoft.com/vcblog/2013/10/29/the-visual-c-linker-best-practices-developer-iteration/ under the section "Linking .libs".

    It says "The linker’s ability to incrementally link will be significantly hampered if your title links in libraries (.lib files). The most significant impact of using libraries as far as incremental linking is concerned, is that any change made to any library will cause the linker to abandon incremental linking and do a full link. .........Having said that, if you do perform changes to .libs on a constant basis we do provide a way to incrementally link in Visual Studio. This can be done by enabling the ‘Use Library Dependency Inputs’

    • Proposed as answer by RLWA32 Tuesday, January 10, 2017 1:17 PM
    Friday, January 06, 2017 11:54 AM
  • Ok, 'Use Library Dependency Inputs' works, but I think there's still an issue with /WHOLEARCHIVE, given a project setup as follows:

    +StaticLib
       - StatiLib.h
       - StaticLib.cpp   (<- contains a function called by the exe)
      
    +Executable          (<- links StaticLib)
       - main.cpp        (<- calls a function in StaticLib)

    Without /WHOLEARCHIVE, if I make a change in StaticLib.cpp and build the solution the change is visible in the exe.

    With /WHOLEARCHIVE, I make a change in StaticLib.cpp and build the solution, StaticLib.cpp is recompiled but the change is not visible in the exe. 

    From the blog link previously I'd expect that, in the latter case, a full link would happen but it seems that that isn't happening (or is broken), or something is amiss with the librarian - at any rate it has no effect. I increased the MSBuild verbosity level but I don't see anything unusual in the output.

    Of course, 'Use Library Dependency Inputs' works because it's linking the .obj files directly; my concern is that /WHOLEARCHIVE doesn't work in this case as I'd expect.

    Monday, January 09, 2017 5:35 PM
  • So the issue isn't really about Incremental Linking since /WHOLEARCHIVE disables that  feature.

    Using your example above, as a workaround you could have VS re-link the Executable project instead of doing a full rebuild.  But from the description of the issue it sounds like it might be a bug worth reporting.


    • Edited by RLWA32 Tuesday, January 10, 2017 10:37 AM
    Tuesday, January 10, 2017 10:36 AM
  • Yup, my terminology was off.

    Thanks for all the feedback - I'll file a bug report about this behaviour. 'Use Library Dependency Inputs' is a good solution for us as a workaround.

    Thanks again.

    Tuesday, January 10, 2017 1:10 PM
  • You're welcome.  After you file the bug report at https://connect.microsoft.com/VisualStudio/ please post a link to it back here so we can find it.

    Tuesday, January 10, 2017 1:18 PM
  • Bug report filed here (id 3118450).

    Tuesday, January 10, 2017 1:39 PM
  • I noticed something interesting.  I can replicate your observation if at first I omit /WHOLEARCHIVE from the linker options for the executable.  After doing a full build of the executable and the static library I added /WHOLEARCHIVE to the linker options for the executable.  I rebuilt the solution and the executable's linker map included the otherwise unreferenced static library module.  At that point I was able to reproduce the issue.  Upon changing the static library module and rebuilding the solution the executable only relinked (as expected) but the linker map for the executable did not show that the code change had been included in the link.

    Then I cleaned the solution containing the executable and static library projects.  I did a complete rebuild of the solution but this time I started with the /WHOLEARCHIVE option already set.  After the build completed I changed the code in the static library module that was unreferenced but being pulled in by the /WHOLEARCHIVE option.  After making the change I rebuilt the solution.  As expected, the executable only relinked, but this time the change to the static library module was reflected in the executable's linker map.

    Can you reproduce this sequence of events?

    Tuesday, January 10, 2017 10:21 PM