21

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?

Jaffa
  • 12,442
  • 4
  • 49
  • 101
Mai Saad
  • 249
  • 1
  • 3
  • 10
  • possible duplicate of [Visual C++: How to disable specific linker warnings?](http://stackoverflow.com/questions/661606/visual-c-how-to-disable-specific-linker-warnings) – Cheers and hth. - Alf Dec 31 '13 at 08:39
  • 4
    http://blogs.msdn.com/b/vcblog/archive/2009/07/21/linker-warning-lnk4221-and-some-tips-to-avoid-it.aspx – ManuelH Dec 31 '13 at 08:44
  • Why don't you use precompiled headers? What are object files that are linked with this warnings - please post linker errors. Are stdafx.cpp files compiled and linked? – Alex F Dec 31 '13 at 08:54
  • @ManuelH's link shows the 1st google hit, that explains it very well! – πάντα ῥεῖ Dec 31 '13 at 08:54
  • @ Alex : i didn`t use precompiled headers as it made several errors , about which object files , well this warning appeared for the 3 static libraries projects in the same object files (\.NETFramework,Version=v4.0.AssemblyAttributes.obj), and there is no stdafx files in the project . – Mai Saad Dec 31 '13 at 09:22
  • well i don`t think that ignoring it using ignore command will fix it .. so any ideas ?! – Mai Saad Dec 31 '13 at 09:32

6 Answers6

12

Disclaimer: This solution is indeed terrible, and this code should not be added to production build! It is only useful to "hide" the warning.

A better solution would be to remove the file in question from the compilation, as it is anyway useless.

Original post:

I had a the problem with this warning originating from several dependencies, and I found that it was caused by some translation unit being empty, i.e. empty source files.

These files actually had a content but it was deactivated for visual studio so I just added at the beginning:

__declspec( dllexport ) void getRidOfLNK4221(){}

And now my project compiles without any warning :)

Hope it helps, even if this is a late answer!

Jaffa
  • 12,442
  • 4
  • 49
  • 101
  • 24
    That's terrible. – geometrian Aug 06 '16 at 21:36
  • 1
    why is this terrible? – Shital Shah Oct 15 '17 at 10:17
  • 6
    The code basically makes a function that does nothing, then tells the compiler not to eliminate it and in-fact to expose it as a symbol. It's "terrible" first because you're trying to convince the compiler not to tell you about something dumb it saw you doing—then compounding the issue by polluting your symbol table and library binary with random garbage functions that, by definition, are pointless. A better solution is to fix the warning—in this answer's case, to not compile the useless file at all. Split the implementation into files by platform, and it'll compile faster anyway. – geometrian Nov 19 '17 at 08:07
  • Compiling „useless” file is not dumb and makes a lot of sense – it is useful method to validate related header (which contains only inline or template functions) during library compilation and in isolation. – Mekk Mar 17 '23 at 09:55
11

I had a c++ static library with an empty module in it, linking which in non-optimized mode gave me that LNK4221 warning. (in Visual Studio) I went to Librarian->All Options, and added "/ignore:4221" to Additional Options. So, the warning has disappeared.

Vladimir Shutow
  • 1,028
  • 1
  • 14
  • 22
  • THis doesnt solve the problem. It is just spressing the warning. So essentially the issue is still there but just that not visible – Sisir May 28 '23 at 17:56
8

You get this warning because you use only template classes in cpp file. To get rid of it, insert one simple function with no template.

John Coleman
  • 51,337
  • 7
  • 54
  • 119
Myfero
  • 204
  • 3
  • 7
  • I followed your suggestion. This warning is gone. But a new one LNK4006 showed up for every other file the header is included(: – def Feb 26 '18 at 04:12
  • This was my scenario for a VS2013 static library project. I had a fully templated class in an .h file and a corresponding (empty) .cpp file. I simply excluded the .cpp file from the project. The warning went away and I (surprise to me but it shouldn't have been) had no linking errors when I built the executable using the static lib. – yano Aug 27 '19 at 18:53
1

See this: https://learn.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-warning-lnk4221

In summary, the file exports nothing, so linker does not link, as it thinks it's a waste of effort

0

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.

Kenny Castro
  • 121
  • 11
0

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!

Evandro Coan
  • 8,560
  • 11
  • 83
  • 144