Skip to content

Commit

Permalink
[cdac] link a stub contract descriptor if cdac-build-tool is not avai…
Browse files Browse the repository at this point in the history
…lable (#101297)

* [cdac] link a stub contract descriptor if cdac-build-tool is not available

   Fixes builds that use src/coreclr/build-runtime.sh directly, or bringup scenarios without msbuild

* Use DOTNET_HOST_PATH to run cdac-build-tool

   Related to dotnet/installer#19534 (comment)

   it's only unset by .NET Framework which is not supported by runtime.proj

---------

Co-authored-by: Adeel Mujahid <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Jul 9, 2024
1 parent 4fc2f11 commit 1096192
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 33 deletions.
78 changes: 45 additions & 33 deletions src/coreclr/debug/runtimeinfo/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,45 +38,57 @@ endif()
# publish runtimeinfo lib
install_clr(TARGETS runtimeinfo DESTINATIONS lib COMPONENT runtime)

add_library(cdac_data_descriptor OBJECT datadescriptor.cpp)
# don't build the data descriptor before the VM (and any of its dependencies' generated headers)
add_dependencies(cdac_data_descriptor cee_wks_core)
if(CLR_CMAKE_TARGET_WIN32)
# turn off whole program optimization:
# 1. it creates object files that cdac-build-tool can't read
# 2. we never link cdac_data_descriptor into the final product - it's only job is to be scraped
target_compile_options(cdac_data_descriptor PRIVATE /GL-)
endif()
target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR})
target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR})
target_include_directories(cdac_data_descriptor PRIVATE ${CLR_DIR}/interop/inc)

set(GENERATED_CDAC_DESCRIPTOR_DIR "${CMAKE_CURRENT_BINARY_DIR}/cdac")
set(CONTRACT_DESCRIPTOR_OUTPUT "${GENERATED_CDAC_DESCRIPTOR_DIR}/contract-descriptor.c")
if("${CDAC_BUILD_TOOL_BINARY_PATH}" STREQUAL "" OR NOT EXISTS "${CDAC_BUILD_TOOL_BINARY_PATH}")
message(FATAL_ERROR "No cdac-build-tool set or ${CDAC_BUILD_TOOL_BINARY_PATH} does not exist")
endif()

set(CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc")
# cDAC contract descriptor

if (NOT CDAC_BUILD_TOOL_BINARY_PATH)
# if CDAC_BUILD_TOOL_BINARY_PATH is unspecified (for example for a build without a .NET SDK or msbuild),
# link a stub contract descriptor into the runtime
add_library_clr(cdac_contract_descriptor OBJECT contractdescriptorstub.c)
message(STATUS "Using a stub cDAC contract descriptor")
else()
# generate a contract descriptor using cdac-build-tool from a data descriptor and contract json file

add_library(cdac_data_descriptor OBJECT datadescriptor.cpp)
# don't build the data descriptor before the VM (and any of its dependencies' generated headers)
add_dependencies(cdac_data_descriptor cee_wks_core)
if(CLR_CMAKE_TARGET_WIN32)
# turn off whole program optimization:
# 1. it creates object files that cdac-build-tool can't read
# 2. we never link cdac_data_descriptor into the final product - it's only job is to be scraped
target_compile_options(cdac_data_descriptor PRIVATE /GL-)
endif()
target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR})
target_include_directories(cdac_data_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR})
target_include_directories(cdac_data_descriptor PRIVATE ${CLR_DIR}/interop/inc)

set(GENERATED_CDAC_DESCRIPTOR_DIR "${CMAKE_CURRENT_BINARY_DIR}/cdac")
set(CONTRACT_DESCRIPTOR_OUTPUT "${GENERATED_CDAC_DESCRIPTOR_DIR}/contract-descriptor.c")
if(NOT EXISTS "${CDAC_BUILD_TOOL_BINARY_PATH}")
message(FATAL_ERROR "${CDAC_BUILD_TOOL_BINARY_PATH} does not exist")
endif()

# generate the contract descriptor by running cdac-build-tool
# n.b. this just uses `dotnet` from the PATH. InitializeDotNetCli adds the apropropriate directory
add_custom_command(
set(CONTRACT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/contracts.jsonc")

# generate the contract descriptor by running cdac-build-tool
# n.b. this just uses `dotnet` from the PATH. InitializeDotNetCli adds the apropropriate directory
add_custom_command(
OUTPUT "${CONTRACT_DESCRIPTOR_OUTPUT}"
VERBATIM
COMMAND dotnet ${CDAC_BUILD_TOOL_BINARY_PATH} compose -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -c "${CONTRACT_FILE}" $<TARGET_OBJECTS:cdac_data_descriptor>
COMMAND ${CLR_DOTNET_HOST_PATH} ${CDAC_BUILD_TOOL_BINARY_PATH} compose -o "${CONTRACT_DESCRIPTOR_OUTPUT}" -c "${CONTRACT_FILE}" $<TARGET_OBJECTS:cdac_data_descriptor>
DEPENDS cdac_data_descriptor cee_wks_core $<TARGET_OBJECTS:cdac_data_descriptor> "${CONTRACT_FILE}"
USES_TERMINAL
)
)

# It is important that cdac_contract_descriptor is an object library;
# if it was static, linking it into the final dll would not export
# DotNetRuntimeContractDescriptor since it is not referenced anywhere.
add_library_clr(cdac_contract_descriptor OBJECT
# It is important that cdac_contract_descriptor is an object library;
# if it was static, linking it into the final dll would not export
# DotNetRuntimeContractDescriptor since it is not referenced anywhere.
add_library_clr(cdac_contract_descriptor OBJECT
"${CONTRACT_DESCRIPTOR_OUTPUT}"
contractpointerdata.cpp
)
target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR})
target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR})
target_include_directories(cdac_contract_descriptor PRIVATE ${CLR_DIR}/interop/inc)
add_dependencies(cdac_contract_descriptor cdac_data_descriptor cee_wks_core)
)
target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR})
target_include_directories(cdac_contract_descriptor BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR})
target_include_directories(cdac_contract_descriptor PRIVATE ${CLR_DIR}/interop/inc)
add_dependencies(cdac_contract_descriptor cdac_data_descriptor cee_wks_core)
endif()
39 changes: 39 additions & 0 deletions src/coreclr/debug/runtimeinfo/contractdescriptorstub.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include <stdint.h>

#ifdef _MSC_VER
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __attribute__((visibility("default")))
#endif

struct DotNetRuntimeContractDescriptor
{
uint64_t magic;
uint32_t flags;
const uint32_t descriptor_size;
const char *descriptor;
const uint32_t pointer_data_count;
uint32_t pad0;
const uintptr_t *pointer_data;
};

extern const uintptr_t contractDescriptorPointerData[];

// just the placeholder pointer
const uintptr_t contractDescriptorPointerData[] = { (uintptr_t)0 };

DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor;

#define STUB_DESCRIPTOR "{\"version\":0,\"baseline\":\"empty\",\"contracts\":{},\"types\":{},\"globals\":{}}"

DLLEXPORT struct DotNetRuntimeContractDescriptor DotNetRuntimeContractDescriptor = {
.magic = 0x0043414443434e44ull, // "DNCCDAC\0"
.flags = 0x1u & (sizeof(void*) == 4 ? 0x02u : 0x00u),
.descriptor_size = sizeof(STUB_DESCRIPTOR),
.descriptor = STUB_DESCRIPTOR,
.pointer_data_count = 1,
.pointer_data = &contractDescriptorPointerData[0],
};
1 change: 1 addition & 0 deletions src/coreclr/runtime.proj
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<_CoreClrBuildArg Condition="'$(HostCrossOS)' != ''" Include="-hostos $(HostCrossOS)" />
<_CoreClrBuildArg Include="-outputrid $(OutputRID)" />
<_CoreClrBuildArg Condition="'$(BuildSubdirectory)' != ''" Include="-subdir $(BuildSubdirectory)" />
<_CoreClrBuildArg Include="-cmakeargs &quot;-DCLR_DOTNET_HOST_PATH=$(DOTNET_HOST_PATH)&quot;" />
<_CoreClrBuildArg Include="-cmakeargs &quot;-DCDAC_BUILD_TOOL_BINARY_PATH=$(RuntimeBinDir)cdac-build-tool\cdac-build-tool.dll&quot;" />
</ItemGroup>

Expand Down

0 comments on commit 1096192

Please sign in to comment.