I'm actually running into exactly this problem. I have a mixed solution of C++ and C# projects and I wanted to try to move from .NET Framework 4.8 to .NET 6.0 (or 7.0). I basically used:
set( CMAKE_DOTNET_SDK "Microsoft.NET.Sdk")
set( CMAKE_DOTNET_TARGET_FRAMEWORK "net6.0-windows")
Now I can't even properly load the VS solution aynmore, because all the C++ projects fail to load.
ProjectName.vcxproj : error : Cannot load project: project does not contain requested configuration Debug|Any CPU. Please verify that .sln file is valid and uses only existing project configurations.
I also checked the CMake sourcecode and saw that there is still no workaround for this (because the Any CPU target for .NetSDK projects is hardcoded), but I'm willing to help with an MR.
@brad.king What would the proposed solution with CMAKE_GENERATOR_PLATFORM
look like?
I just wanted to give a small warning that even when correctly setting the ToolExe path that building with ccache doesn't cache anything when using the Visual Studio generator. The first big problem is that that multiple files are passed to cl.exe (which is currently supported by ccache) and then there are also some path and flag issues when building single files. So while it would make things easier to work on ccache (or sccache which basically has identical issues - e.g. it also doesn't support the multiple files ) it will not bring much value until those issues are fixed.
KonanM (12421158) at 15 Sep 10:10
Merge remote-tracking branch 'upstream/master'
... and 1654 more commits
I mean the use case of LIB
-> OBJ
-> OBJ
-> EXE
is probably the least likely - at least in my experience I never encountered the use case of OBJ
-> OBJ
. Basically the patch would be fine for me.
I actually initially also thought that INTERFACE_LINK_LIBRARIES is the culprit (and played around with exactly that line and would have written an MR if that fixed the issue), but when that would be the case then the object file would always get linked in whether the other library also uses a precompiled header or not.
@cristianadam I'm well aware that linking of the BasePCH.dir\Debug\cmake_pch.obj
is needed for the MyObjLib, because of target_precompile_headers(MyObjectLib REUSE_FROM BasePCH)
and that is surely correct.
The issue is that when the MySharedLib
doesn't use any precompiled header then it will (correctly) not link against BasePCH.dir\Debug\cmake_pch.obj
(I mean why should it). When it does use a precompiled header itself (or when it reuses another precompiled header which is not BasePCH) then it will not only link against it own precompiled header object file, but also against the one from the BasePCH (which I think is incorrect).
I have a bigger monorepository where the plan was to define a set of 2-4 precompiled headers and reuse them wherever possible. And where it's not possible projects can have their own PCH, but that's where this workflow currently breaks (because of this problem).
@cristianadam please don't get distracted by the target_compile_options(MySharedLib PRIVATE /MTd)
. I just used that as an example to make the compilation fail. There are more problems when the additional .obj file gets linked which is not visible in this example. I had the problem that the wrong duplicate symbols got linked (which is a lot more annoying and subtle).
Apart from this - why should the usage of target_precompile_headers(MySharedLib PRIVATE <iostream>)
cause the obj file from BasePCH
to get linked into MySharedLib
. Imho this is simply not working as intended...
Here is the test case that is currently causing me trouble:
cmake_minimum_required(VERSION 3.16)
project(CMakePCH VERSION 1.0.0 LANGUAGES CXX)
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/Empty.cpp "\n")
add_library(BasePCH STATIC Empty.cpp)
target_compile_options(BasePCH PRIVATE /permissive-)
target_precompile_headers(BasePCH PRIVATE <windows.h> <vector>)
add_library(MyObjectLib OBJECT Empty.cpp)
target_compile_options(MyObjectLib PRIVATE /permissive-)
target_precompile_headers(MyObjectLib REUSE_FROM BasePCH)
add_library(IntermdiateStatic STATIC Empty.cpp)
target_compile_options(IntermdiateStatic PRIVATE /permissive-)
target_link_libraries(IntermdiateStatic PRIVATE MyObjectLib)
add_library(MySharedLib SHARED Empty.cpp)
target_link_libraries(MySharedLib PRIVATE IntermdiateStatic)
#using /MTd (staticically linking the std library) causes the BasePCH to be incompatible
target_compile_options(MySharedLib PRIVATE /MTd)
#when using target_precompile_headers it results in BasePCH.dir\Debug\cmake_pch.obj getting linked into MySharedLib when it really shouldn't
#commenting target_precompile_headers below fixes the issue
target_precompile_headers(MySharedLib PRIVATE <iostream>)
I'm running into this problem that using target_precompile_headers( ... REUSE_FROM ...)
causes problems when using target_precompile_headers
in other projects. Uncommenting the last line fixes the issue. Basically what happens is that when target_precompile_headers(MySharedLib PRIVATE <iostream>)
is used this causes the .obj (BasePCH.dir\Debug\cmake_pch.obj
) to be included in the linked to objects of MySharedLib (although this two things should not relate to each other).
@cristianadam I investigated a bit more and it seems like the shared PCH usage is simply not implemented with /Zi
or /ZI
, only with /Z7
under MSVC. The article here https://devblogs.microsoft.com/cppblog/shared-pch-usage-sample-in-visual-studio/ describes pretty nicely what additional steps are needed when using /Zi
or /ZI
(basically you have to copy the generated pch and pdb file to each project using it).
I just wanted to say that I'm also affected by this issue with CMake 3.21. It might be an MSVC issue, but I can confirm that it's only happening with /Zi
and not with /Z7
.
I created a MR, but I probably have messed up something when getting the lastest changes from upstream. The correct commit is only !6065 (92da255e) .
KonanM (a9fafbb7) at 30 Apr 05:54
fix cs file link for out of source files in bin dir
KonanM (65b98c0d) at 30 Apr 05:52
fix whitespace issue
Fixes: #22104
Topic-rename: vs-csharp-link
KonanM (b54b0c12) at 30 Apr 05:43
fix cs file link for out of source files in bin dir
KonanM (485bc928) at 30 Apr 05:41
Fix test and only excluse .cs files
KonanM (7901a883) at 29 Apr 14:15
added test for new csharp source link behavior
Hmmm seems like I actually added handling for files in the binary directory again and it wasn't caught by a test. It's easy to fix (delete two lines of code), but I will check if I can add a test to catch this correctly.
KonanM (52260dd3) at 29 Apr 11:35
fix cs file link for out of source files in bin dir