我能否在CMake时获取特定vcproj生成的GUID?

4
前言:我正在尝试将我的C# csproj与我们的C++和C++/CLI代码库cmake构建集成。有人建议我不要这么做,因为CMake在Visual Studio中无法很好地与.NET协作,但经过一些定制,我感觉我离成功很近了。
我的一部分定制是使用configure_file命令在CMake时间编辑csproj文件,根据正在发生的构建类型(例如x86、x64)进行自定义。
问题是我使用了一些ProjectReference标记来引用C++/CLI项目:
<ProjectReference Include="..\..\WrapperProject\WrapperProject.vcproj">
  <Project>{7BD6E175-CDD1-4F8D-A3B2-0AC862E62C03}</Project>
  <Name>WrapperProject</Name>
</ProjectReference>

...而GUID不能保持不变,因为每当重新构建CMake缓存时,项目的GUID会改变(如果我错了请纠正)。

所以,我想在CMake时间找出这些项目计划使用的GUID,并相应地编辑vcproj文件。

谷歌告诉我人们能够使用“set_property”来设置GUID,就像这样:

set_property(CACHE ${target_name}_GUID_CMAKE PROPERTY VALUE ${MY_GUID} )

...但我似乎找不到相应的getter。 我尝试过类似这样的东西:

get_property(WRAPPER_GUID CACHE INTERNAL PROPERTY WrapperTargetName_GUID_CMAKE)

...但没有成功。 希望您能帮忙!


1
由于可以从CMake设置固定的项目GUID,因此您应该也能够编写固定的ProjectReference标签,对吧? - ronkot
3个回答

4

在更多的实践中,我发现了Fraser指出的问题 - 这种方法不总是可行的,因为我不能期望GUID在重新运行CMake时可用。因此,我采用了我在CMake邮件列表上看到的建议路线,即显式设置GUID值。

因此,在每个C++/CLI包装器项目的CMakeLists.txt中,我有以下内容:

# Set a global cache variable for this project GUID
# The TestAppNet csproj needs this GUID to properly reference this project
set_property(GLOBAL PROPERTY Wrapper_GUID "1897F4D1-E929-444E-9343-00F094113772") 
get_property(projectGUID GLOBAL PROPERTY Wrapper_GUID)
MESSAGE( STATUS "Setting project GUID to: ${projectGUID}")
set(Wrapper_GUID_CMAKE "${projectGUID}" CACHE INTERNAL "Project GUID")

在C#项目的CMakeLists.txt中,我有以下内容:
get_property(CMAKE_WRAPPER_GUID GLOBAL PROPERTY Wrapper_GUID)
MESSAGE( STATUS "Setting Wrapper GUID to: ${CMAKE_WRAPPER_GUID}" )

......然后,在configure_file命令期间,CMAKE_WRAPPER_GUID被用作在.csproj文件中的一个变量。

我不确定这是否高效,但看起来很奏效!


1
如果有任何人想知道,此GUID缓存条目用于cmGlobalVisualStudio7Generator :: GetGUID函数中的CMake源代码中。CMake Git提交c85367f408befa419185a4fec4816ea0ee3e1ee6修改了行为,以便CMake不再创建_GUID_CMAKE缓存变量(而是优先使用确定性GUID)。但是,它似乎仍然会接受用户在该变量中提供的GUID。 - James Johnston

2

您的语法略有偏差。您可能是想表达:

get_property(WRAPPER_GUID CACHE WrapperTargetName_GUID_CMAKE PROPERTY VALUE)

然而,这是一种相对复杂的获取值的方式。你可以直接执行以下操作:
set(WRAPPER_GUID ${WrapperTargetName_GUID_CMAKE})

最后,这并不是理想的,因为GUID直到第一次运行CMake之后才可用。因此,在进行全新的构建时,您需要在使用此功能之前运行CMake两次。


谢谢。这很有帮助。最终我用了稍微不同的方法解决了问题,以避免你指出的困境。简而言之,我在每个相应的C++/CLI项目的CMakeLists.txt中明确设置值,然后在C#项目的CMakeLists.txt中检索它们,并使用这些值生成ProjectReference节点。 - Kohanz

0

设置看起来对我不起作用,但可以从你的CMake代码中预测/重新计算:

https://github.com/Kitware/CMake/blob/85dc7c763a12366d49ac2dddc53f65d52d675c00/Source/cmGlobalVisualStudio7Generator.cxx#L636-L656

在你的CMake代码中,你可以使用string(UUID)实现此功能:

function(get_target_uuid VARIABLE TARGET)
  set(
    CMAKE_MSVC_PROJECT_UUID_NAMESPACE
    "ee30c4be-5192-4fb0-b335-722a2dffe760"
  )
  string(
    UUID TARGET_UUID
    NAMESPACE "${CMAKE_MSVC_PROJET_UUID_NAMESPACE}"
    NAME "${CMAKE_BINARY_DIR}|${TARGET}"
    TYPE MD5
    UPPER
  )
  set("${VARIABLE}" "${TARGET_UUID}" PARENT_SCOPE)
endfunction()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接