How to eliminate Warning LNK4221?

Viewed 20638

I am working on a project using c++/windows forms (visual studio 2010), we have 4 projects:

  • 1 project containing GUI windows forms {managed code} and this is the exe project
  • other 3 projects {non-managed code} and all are static libraries.
  • in the 4 projects we don`t use precompilied headers stdafx.h , and common language runtime support is the Pure MSIL Common Language Runtime Support (/clr:pure).
  • every project include the other 3 projects as additional include directories , and link library dependencies set to yes.

We have:

Warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library

This warning appeared for the 3 static libraries projects in the same object files (.NETFramework,Version=v4.0.AssemblyAttributes.obj).

We want to eliminate it, but after some search, most topics speak about the precompiled headers to be a reason while we don not use it.

Any new ideas about why this warning exist and how to eliminate it?

6 Answers

This was kind of just my particular problem but if your .cpp doesn't define any new functions or has empty bodies for constructor functions, you will get this warning. I used an initialization list for my constructor so the body was empty.

https://devblogs.microsoft.com/cppblog/linker-warning-lnk4221-and-some-tips-to-avoid-it/

In ” Visual Studio 2008 Command Prompt”, enter the following commands (Note: We use command line here to specify the order of .obj files; Visual Studio 2008 will supply linker with .obj files in alphabetical order)

cl /c a.cpp b.cpp

link /lib /out:test.lib a.obj b.obj

And LNK4221 will be thrown for a.obj as the following.

a.obj : warning LNK4221: no public symbols found; archive member will be inaccessible

For the above case, atlbase.h (shipped with Visual Studio) contains some definitions of symbols, which will be included in both a.obj and b.obj. Additionally, there is a function, func1, defined in b.obj. Linker will process OBJ files in Last In First Out manner, so when it is processing a.obj, it cannot find any new public symbols in it because b.obj provide all the public symbols that a.obj has, LNK4221 will be thrown. If command line 2 is replaced with following

link /lib /out:test.lib b.obj a.obj

Now the warning is gone!

Related