Warning LNK4075 when a C++/CLI project references a static lib project with /ZI (Edit And Continue) - visual-studio-2012

I have the following projects in a Visual Studio 2012 solution:
Native (no /clr) static lib project, compiled with /ZI for Edit And Continue.
C++/CLI DLL project, which references the above static lib.
The C++/CLI project builds with the following warning:
warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:LBR' specification
If /OPT:NOLBR is added to the linker options of the C++/CLI project, the warning becomes:
warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
Any attempt to change the incremental linkage setting of the C++/CLI project doesn't change the warning (C++/CLI projects never link incrementally anyway).
I understand that I won't be able to use Edit And Continue in the C++/CLI project, because this is not supported. Indeed, changing /ZI to /Zi (disabling Edit And Continue) in the static lib project eliminates the warning, but I can't do that - other non-CLR consumers of that lib need to use Edit And Continue.
How can I get rid of this warning without disabling Edit And Continue in the static lib (and hopefully without maintaining separate build configuration for native and CLR users of the static lib)? I mean, is there any way to ask the linker to ignore the /EDITANDCONTINUE directive that is embedded in the referenced static lib (much in the same way that /NODEFAULTLIB can ignore /DEFAULTLIB directives)?
I have created a minimal VS solution that reproduces the described issue.

due to '/OPT:LBR' specification
This is a nonsense error message, that linker option is only effective for ARM binaries. This is simply a bug, using /OPT:NOLBR takes the sting out of it and you get the real warning.
Which is accurate enough, although it doesn't win any prizes either, you asked for Edit+Continue support in your static lib project but that is not available for a mixed-mode .NET assembly. The undocumented /IGNORE linker option is available to suppress warning messages but this one is ranked as an "unignorable warning" by Chapell.
You'll have to live with this warning as long as you don't want to change your static lib project. It is completely benign. You won't get it when you recompile it with /Zi.

There is no other way than to
disable "Edit And Continue" in the library
create a separate build configuration for "Edit And Continue (/ZI)" and "Program Database (/Zi)"
Of course: I am not aware that there is a predefined macro to determine between /ZI and /Zi... so you need to define your own preprocessor directive to distinguish between these configurations...

I had the same problem and found the only solution is to delete the .vcxproj and .sln files of the project and create the project again.
But then in an old copy of the same project I found a better solution: I changed in the projectname.vcxproj file the line
Profile true
to
Profile false
and LNK4075 warnings disappeared.
It had been the Visual Studio Profiler who had caused the troubles.

Related

Upgrading to Universal CRT-how can I get rid of a dependency on vcruntime140.dll and msvcp140.dll?

I have a project that I'm trying to get updated to the universal CRT, and I'm still seeing a dependency on vcruntime140.dll and msvcp140.dll, which I think should have been replaced with a ucrtbase.dll, as well as api-ms-win-crt* dlls.
I've already checked out this response here, and this blog post, which explain things pretty well, but still no luck. Here's what I've changed:
Platform Toolset: Visual Studio 2019 (v142)
Windows SDK version: 10.0 (latest installed version)
Additional include directories: added $(UniversalCRT_IncludePath)
Additional library directories: added $(UniversalCRT_LibraryPath_x86)
I also updated my linker dependencies to this set:
ucrt.lib
vcruntime.lib
msvcrt.lib
user32.lib
advapi32.lib
Wsock32.lib
Crypt32.lib
ws2_32.lib
But when I run dumpbin /dependents mydll.dll
File Type: DLL
Image has the following dependencies:
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
VCRUNTIME140.dll
USER32.dll
ADVAPI32.dll
WSOCK32.dll
CRYPT32.dll
WS2_32.dll
MSVCP140.dll
bcrypt.dll
KERNEL32.dll
Summary
E000 .data
66000 .rdata
E000 .reloc
1000 .rsrc
14A000 .text
Is there something else I'm missing to be able to drop the dependency on the specific CRT version?
I've done some more digging, and found this page that says the following:
Starting in Visual Studio 2015, the CRT has been refactored into new
binaries. The Universal CRT (UCRT) contains the functions and globals
exported by the standard C99 CRT library. The UCRT is now a Windows
component, and ships as part of Windows 10.
Great, that's what I expected. Just below though is this:
The vcruntime library contains Visual C++ CRT implementation-specific
code, such as exception handling and debugging support, runtime checks
and type information, implementation details and certain extended
library functions. This library is specific to the version of the
compiler used.
Which implies that there is still a non-universal VC++ dependency that gets linked in by VS. To me, this implies that a dependency-free DLL doesn't really exist (at least not something built with VC++), since you'll always have a vcruntime dependency.
There is always the option of static linking (/MT), but in my case, I'm also looking at a DLL that has /clr, and the two options are mutually exclusive. Application local deployment (just copy vcruntime140.dll with the binaries) also seems to work, and may be the best option for something that I want to be a portable/xcopy deployment.
I'm going to mark this as an answer for now, but if there's a way around this, I'd be interested in seeing it.

Visual Studio 2012 undocumented warning C4447

dllmain.cpp(16): warning C4447: 'main' signature found without threading mode
l. Consider using 'int main(Platform::Array<Platform::String^>^ args)'.
Above is a warning I got from building a Windows Store App DLL project. I didn't change anything in that default dllmain.cpp file except for including my own version of pch.
The documentation for this warning (along with many VS2012 errors/warnings) is nowhere to be found on MSDN and here is the only relevant link I can find:
http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/6daa9587-fe54-4e84-a8b9-0e5c52c2f6e8/
and the op there didn't get an answer.
If anyone knows what it means and how to fix it, it would be great!
As far as I can tell, you can safely ignore the warning. The compiler cribs when it sees a Win32-style DllMain being compiled using the /ZW flag (Consume Windows Runtime Extensions). However, the function gets called as you'd normally expect.
Alternatively, you can work around the warning by compiling dllmain.cpp without /ZW. You might need to adjust the PCH settings for this to properly work. This is the path taken by the DLL (Windows Store apps) C++/CX project template in Visual Studio.
Incidentally, the reason you do not get the warning when you're trying to build a Windows Runtime Component project (which builds everything using /ZW) is that a Windows Runtime Component doesn't declare a DllMain. This is not to say that it can't; it just picks up the dummy DllMain that the CRT defines (which basically turns off per-thread initialization and reports success).

How to fix Visual Studio linker frustration

I am pretty experienced writing my own code, but not in C++. I am used to adding .NET assembly references, and I want to get into using C++.
I downloaded a VC++ 6 project presenting a graph algorithm, opened it in Visual Studio 2010 Ultimate and downloaded the required libraries (LEDA .NET assemblies) however, they came with both DLLs and LIB so I thought I would have no problems with the .NET and C++ connection. Also, the LEDA project comes with C++ style .header files, and static libraries, yet frustration persists.
I put my LEDA header files in a directory visible to the project, since I can "Go to definition" of all the custom LEDA data types and see where they are defined in the LEDA include files.
But, I can not compile/link these data types in. The VS finds their very existence repulsive, and refuses to acknowledge they could possibly be found in leda.lib.
Steps I have already taken:
Added additional /LIBPATH path under Properties ->Linker->General
Added explicit lib references under Properties->Linker->Input
Added all the paths containing LEDA header files and libraries to every path location I can find, like include path, reference path, library path.
Copied the DLLs and LIBs to the release folder as well as the base folder of the project.
Added a #pragma comment( lib, "leda" )
Still no joy.
It's quite bad since none of the custom typedefs are recognised the errors balloon to 646 errors.
If anyone is kind enough to offer assistance, thank you.
I can't guarantee this will work but try the following steps (therefore using it's default predefined paths instead of setting your own ones) :
1) Copy *.dll into Windows/System32 or / and (there is some confusion about x64 and x32 default checking in my head :)) Windows/SysWOW64.
2) Copy *.h files into x:\PathToVC2010\include\
3) Copy *.lib files into x:\PathToVC2010\lib\

VC++ 2010 wants to link boost libararies i didn't even specify

I'm trying to build my application with MSVC 2010 instead of GCC. With GCC everything works fine. My app uses boost_system and boost_thread libraries.
I built boost with VC2010 in "system" layout, that means the libraries are named just libboost_system.lib (and not libboost_system_compiler_threading_version_wtf_snafu.lib)
The libs reside in C:\Boost\lib,
the Makefile specifies
LFLAGS = /NOLOGO /INCREMENTAL:NO /SUBSYSTEM:CONSOLE
LIBS = /LIBPATH:C:/Boost/lib libboost_system.lib libboost_thread.lib Ws2_32.lib
when invoking nmake it compiles, but when trying to link it quits with
LINK : fatal error LNK1104: cannot open file 'libboost_date_time-vc100-mt-1_43.lib
I mean seriously, WTF? I told it to link libboost_systen.lib and libboost_thread.lib how come it tries to link libboost_data_time and why does it assume I built the libs in "tagged" layout??
How can I stop MSVC trying to be smart and guess what I might have wanted to link?
Thanks,
Philipp
This is a feature of the Boost libs with compatible compilers for automatic linking.
(Those convoluted library names cover the myriad of threading and linking options that are available on the platform; there are good reasons to use that convention on Windows...)
More information here:
http://www.boost.org/doc/libs/1_33_1/more/getting_started.html#auto-link
I can't find a page for a more recent version, but I believe the BOOST_ALL_NO_LIB and related options are all still valid in 1.43.
Assuming you are auto-linking (i.e. you've defined BOOST_ALL_DYN_LINK or library specific equivalents).
For layout 'system' you have to define the preprocessor macro:
BOOST_AUTO_LINK_NOMANGLE
to link to the correct library names.
For layout 'tagged' you have to define the preprocessor macro:
BOOST_AUTO_LINK_TAGGED
to link to the correct library names.
I don't know if you could do this override for some libraries and keep the default for others. That would be a very cumbersome setup I'd imagine.

How can I force MSVC++ to ignore CRT dependencies of a static library?

I don't know if it's possible to do this, but I would like the /NODEFAULTLIB to be applied to a static library project.
I have many application projects (A.exe, B.dll, C.dll) that use a common static library D.lib.
This library has a lot of code and also has other .lib dependencies as well. One of them is the openssl library, which seems to have been built for win32 against the Release version of the CRT (i don't have the original project/sources).
So far, to avoid the mixing of the Release/Debug versions of CRT, I have to put the /NODEFAULTLIB:msvcrt.lib linker directive in all leaf projects (A.exe, B.dll). This works but I think it's not the ideal way of dealing with that issue.
I tried to put this property in D.lib project, but it has no effect.
Is there a way to force msvc++ to ignore the msvcrt.lib dependency from the 3rd party library?
A .lib does not have any linker settings because you don't link it, you link to it. A .lib is just an archive of .obj files, sort of like an uncompressed .zip file - that's why you have to put the setting on all projects that link to it.
If you're using VS2005+ you could use property sheets so that you only have to put the setting in one place and then use that property sheet in all projects.
However, OpenSSL is just that - Open Source, so you should be able to get the source for the version you are using and build it again (and add it to your version control system of course). I thought OpenSSL could be built as a DLL or LIB, which would solve your problem as the DLL would not interfere with the linking of your code.
Failing that, you always have the option of slitting your functionality out into a separate DLL so that you only have issues with one project.
To prevent your distributed static link library from depending on a specific MSVC runtime library you need to set this compiler option (in Visual Studio 2010 it looks like):
Configuration Properties -> C/C++ -> Advanced -> Omit Default Library Name = Yes (/ZI)
Now your users can link to your release built static lib from their debug build and not try to link to the incorrect runtime library causing problems, as well as linkers warnings.
Note that may cause link errors if your library actually depends on a specific runtime library or its behavior, and compatible components are not provided in some other way.
My understanding is that if library LIB in linked statically into a DLL, the DLL contains already all relevant code from LIB. Therefore, this coupling cannot be removed. This is just based on my understanding of statical linking, not on experiments.

Resources