diff options
author | Jeremy Koritzinsky <jekoritz@microsoft.com> | 2019-05-10 16:24:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-10 16:24:42 -0700 |
commit | e985b20260631c98a09f08cb67e93d690a6ffd0b (patch) | |
tree | f78350febda1071e413382c879726f111bd62c36 /src | |
parent | 0dd7c86c8573f257cfd3b4b6374b7415fd3a9131 (diff) | |
download | coreclr-e985b20260631c98a09f08cb67e93d690a6ffd0b.tar.gz coreclr-e985b20260631c98a09f08cb67e93d690a6ffd0b.tar.bz2 coreclr-e985b20260631c98a09f08cb67e93d690a6ffd0b.zip |
Move EventProvider native layout to be driven by CMake configure (#24478)
* Generate eventpipe implementation as part of CMake configure.
* Generate Etw provider as part of CMake configure.
* First pass porting over lttng provider to cmake.
* Fix up CMake Lttng provider generation.
* Move Lttng provider into CMake tree.
* Move dummy event provider to CMake
* Move genEventing into the CMake tree.
* Remove extraneous logging and unused python locator.
* Clean up build.sh
* Clean up genEventingTests.py
* Add dependencies to enable more incremental builds (providers not fully incremental).
* Convert to custom command and targets instead of at configure time.
* Get each eventing target to incrementally build.
* Fix incremental builds
* Add missing dependencies on eventing headers.
* PR Feedback. Mark all generated files as generated
* Clean up eventprovider test CMakeLists
Diffstat (limited to 'src')
40 files changed, 702 insertions, 601 deletions
diff --git a/src/binder/v3binder/CMakeLists.txt b/src/binder/v3binder/CMakeLists.txt index e0fb28f37b..70a66eb654 100644 --- a/src/binder/v3binder/CMakeLists.txt +++ b/src/binder/v3binder/CMakeLists.txt @@ -2,3 +2,5 @@ add_library_clr(v3binder STATIC ${BINDER_SOURCES} ) + +add_dependencies(v3binder eventing_headers) diff --git a/src/binder/v3binder_crossgen/CMakeLists.txt b/src/binder/v3binder_crossgen/CMakeLists.txt index cf8040291e..06dd0d886a 100644 --- a/src/binder/v3binder_crossgen/CMakeLists.txt +++ b/src/binder/v3binder_crossgen/CMakeLists.txt @@ -4,3 +4,5 @@ add_library_clr(v3binder_crossgen STATIC ${BINDER_CROSSGEN_SOURCES} ) + +add_dependencies(v3binder_crossgen eventing_headers) diff --git a/src/classlibnative/bcltype/CMakeLists.txt b/src/classlibnative/bcltype/CMakeLists.txt index 2913f9d7a5..843d7e8b68 100644 --- a/src/classlibnative/bcltype/CMakeLists.txt +++ b/src/classlibnative/bcltype/CMakeLists.txt @@ -20,3 +20,4 @@ add_library_clr(bcltype ${BCLTYPE_SOURCES} ) +add_dependencies(bcltype eventing_headers) diff --git a/src/classlibnative/float/CMakeLists.txt b/src/classlibnative/float/CMakeLists.txt index 7cb7dedff3..bf173fe658 100644 --- a/src/classlibnative/float/CMakeLists.txt +++ b/src/classlibnative/float/CMakeLists.txt @@ -15,3 +15,5 @@ add_library_clr(comfloat_wks STATIC ${FLOAT_SOURCES} ) + +add_dependencies(comfloat_wks eventing_headers) diff --git a/src/debug/daccess/CMakeLists.txt b/src/debug/daccess/CMakeLists.txt index aab3f81ac6..0e8ccfe67f 100644 --- a/src/debug/daccess/CMakeLists.txt +++ b/src/debug/daccess/CMakeLists.txt @@ -43,6 +43,8 @@ add_precompiled_header(stdafx.h stdafx.cpp DACCESS_SOURCES) add_library_clr(daccess ${DACCESS_SOURCES}) +add_dependencies(daccess eventing_headers) + if(CLR_CMAKE_PLATFORM_UNIX) add_custom_command( OUTPUT ${GENERATED_INCLUDE_DIR}/dactablerva.h diff --git a/src/debug/di/CMakeLists.txt b/src/debug/di/CMakeLists.txt index de6ea238ba..8b37c247f9 100644 --- a/src/debug/di/CMakeLists.txt +++ b/src/debug/di/CMakeLists.txt @@ -109,3 +109,4 @@ endif (WIN32) list(APPEND CORDBDI_SOURCES ${CORDBDI_SOURCES_ASM_FILE}) add_library_clr(cordbdi STATIC ${CORDBDI_SOURCES}) +add_dependencies(cordbdi eventing_headers) diff --git a/src/debug/ee/dac/CMakeLists.txt b/src/debug/ee/dac/CMakeLists.txt index 3bdfd317d1..ceae5c9faa 100644 --- a/src/debug/ee/dac/CMakeLists.txt +++ b/src/debug/ee/dac/CMakeLists.txt @@ -8,3 +8,4 @@ if (WIN32) endif (WIN32) add_library_clr(cordbee_dac ${CORDBEE_SOURCES_DAC}) +add_dependencies(cordbee_dac eventing_headers) diff --git a/src/debug/ee/wks/CMakeLists.txt b/src/debug/ee/wks/CMakeLists.txt index 66a73b3b59..c6a4bccb08 100644 --- a/src/debug/ee/wks/CMakeLists.txt +++ b/src/debug/ee/wks/CMakeLists.txt @@ -63,3 +63,5 @@ else () endif() endif (WIN32) + +add_dependencies(cordbee_wks eventing_headers) diff --git a/src/gc/CMakeLists.txt b/src/gc/CMakeLists.txt index 1e59ebaa26..e3e171ebf1 100644 --- a/src/gc/CMakeLists.txt +++ b/src/gc/CMakeLists.txt @@ -95,6 +95,7 @@ list(APPEND GC_SOURCES ${GC_HEADERS}) convert_to_absolute_path(GC_SOURCES ${GC_SOURCES}) add_library_clr(clrgc SHARED ${GC_SOURCES}) +add_dependencies(clrgc eventing_headers) target_link_libraries(clrgc ${GC_LINK_LIBRARIES}) install_clr(clrgc) diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt index 829638b693..b65d3b93b6 100644 --- a/src/pal/src/CMakeLists.txt +++ b/src/pal/src/CMakeLists.txt @@ -410,8 +410,9 @@ endif(CMAKE_SYSTEM_NAME STREQUAL NetBSD) add_subdirectory(examples) if(FEATURE_EVENT_TRACE) - add_subdirectory(${GENERATED_EVENTING_DIR}/eventprovider ${CMAKE_CURRENT_BINARY_DIR}/eventprovider) + add_subdirectory(eventprovider) endif(FEATURE_EVENT_TRACE) + # Install the static PAL library for VS _install (TARGETS coreclrpal DESTINATION lib) diff --git a/src/pal/src/eventprovider/CMakeLists.txt b/src/pal/src/eventprovider/CMakeLists.txt new file mode 100644 index 0000000000..bd820a8164 --- /dev/null +++ b/src/pal/src/eventprovider/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.8.12) + +set(EVENT_MANIFEST ${VM_DIR}/ClrEtwAll.man) + +if(CLR_CMAKE_PLATFORM_LINUX OR CLR_CMAKE_PLATFORM_FREEBSD) + add_subdirectory(lttngprovider) +else() + add_subdirectory(dummyprovider) +endif() diff --git a/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt b/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt new file mode 100644 index 0000000000..684aadd175 --- /dev/null +++ b/src/pal/src/eventprovider/dummyprovider/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 2.8.12) + +include(FindPythonInterp) + +set (GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genDummyProvider.py) + +set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR}) + +execute_process( + COMMAND ${GENERATE_COMMAND} --dry-run + RESULT_VARIABLE GEN_DUMMY_RESULT + OUTPUT_VARIABLE DUMMY_PROVIDER_OUTPUT + ERROR_VARIABLE GEN_DUMMY_ERRORS +) + +if (NOT GEN_DUMMY_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to generate dummy event provider: ${GEN_DUMMY_ERRORS}") +endif() + +string(REPLACE "\n" ";" DUMMY_PROVIDER_OUTPUT ${DUMMY_PROVIDER_OUTPUT}) # turn the outputted list of files into a CMake list + +set (DUMMY_PROVIDER_SOURCES "") +set (TRACEPOINT_PROVIDER_SOURCES "") +foreach(DUMMY_PROVIDER_FILE ${DUMMY_PROVIDER_OUTPUT}) + file(TO_CMAKE_PATH ${DUMMY_PROVIDER_FILE} DUMMY_PROVIDER_FILE) + list(APPEND DUMMY_PROVIDER_SOURCES ${DUMMY_PROVIDER_FILE}) +endforeach() + +add_definitions(-DPAL_STDCPP_COMPAT=1) +include_directories(${COREPAL_SOURCE_DIR}/inc/rt) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/dummy) + +add_custom_command(OUTPUT ${DUMMY_PROVIDER_SOURCES} + COMMAND ${GENERATE_COMMAND} + DEPENDS ${EVENT_MANIFEST} ${GENERATE_SCRIPT}) + +add_library(eventprovider + STATIC + ${DUMMY_PROVIDER_SOURCES} +) + +set_target_properties(eventprovider PROPERTIES LINKER_LANGUAGE CXX) + +# Install the static eventprovider library +install(TARGETS eventprovider DESTINATION lib) +
\ No newline at end of file diff --git a/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt b/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt new file mode 100644 index 0000000000..b5bf8e8551 --- /dev/null +++ b/src/pal/src/eventprovider/lttngprovider/CMakeLists.txt @@ -0,0 +1,67 @@ +cmake_minimum_required(VERSION 2.8.12) + +include(FindPythonInterp) +set (GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genLttngProvider.py) + +set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --intermediate ${CMAKE_CURRENT_BINARY_DIR}) + +execute_process( + COMMAND ${GENERATE_COMMAND} --dry-run + RESULT_VARIABLE GEN_LTTNG_RESULT + OUTPUT_VARIABLE LTTNG_PROVIDER_OUTPUT + ERROR_VARIABLE GEN_LTTNG_ERRORS +) + +if (NOT GEN_LTTNG_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to generate Lttng provider: ${GEN_LTTNG_ERRORS}") +endif() + +string(REPLACE "\n" ";" LTTNG_PROVIDER_OUTPUT ${LTTNG_PROVIDER_OUTPUT}) # turn the outputted list of files into a CMake list + +set (LTTNG_PROVIDER_SOURCES "") +set (TRACEPOINT_PROVIDER_SOURCES "") +set (LTTNG_HEADERS "") +foreach(LTTNG_PROVIDER_FILE ${LTTNG_PROVIDER_OUTPUT}) + file(TO_CMAKE_PATH ${LTTNG_PROVIDER_FILE} LTTNG_PROVIDER_FILE) + if ("${LTTNG_PROVIDER_FILE}" MATCHES "/lttng/traceptprov[a-z]+.cpp$") + list(APPEND TRACEPOINT_PROVIDER_SOURCES ${LTTNG_PROVIDER_FILE}) + elseif("${LTTNG_PROVIDER_FILE}" MATCHES "/lttng/eventprov[a-z]+.cpp$") + list(APPEND LTTNG_PROVIDER_SOURCES ${LTTNG_PROVIDER_FILE}) + else() + list(APPEND LTTNG_HEADERS ${LTTNG_PROVIDER_FILE}) + endif() +endforeach() + +add_definitions(-DPAL_STDCPP_COMPAT=1) +include_directories(${COREPAL_SOURCE_DIR}/inc/rt) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/lttng) + +add_custom_command(OUTPUT ${LTTNG_PROVIDER_SOURCES} ${TRACEPOINT_PROVIDER_SOURCES} ${LTTNG_HEADERS} + COMMAND ${GENERATE_COMMAND} + DEPENDS ${EVENT_MANIFEST} ${GENERATE_SCRIPT}) + +add_library(eventprovider + STATIC + ${LTTNG_PROVIDER_SOURCES} + eventproviderhelpers.cpp +) + +add_compile_options(-fPIC) + +add_library(coreclrtraceptprovider + SHARED + ${TRACEPOINT_PROVIDER_SOURCES} +) + +find_library(LTTNG NAMES lttng-ust) + +target_link_libraries(coreclrtraceptprovider + ${LTTNG} +) + +set_target_properties(coreclrtraceptprovider PROPERTIES LINKER_LANGUAGE CXX) + +# Install the static eventprovider library +_install(TARGETS eventprovider DESTINATION lib) +# Install the static coreclrtraceptprovider library +install_clr(coreclrtraceptprovider) diff --git a/src/pal/src/eventprovider/lttngprovider/eventproviderhelpers.cpp b/src/pal/src/eventprovider/lttngprovider/eventproviderhelpers.cpp new file mode 100644 index 0000000000..47e67506f7 --- /dev/null +++ b/src/pal/src/eventprovider/lttngprovider/eventproviderhelpers.cpp @@ -0,0 +1,81 @@ +#include "palrt.h" +#include "pal.h" +#include "stdlib.h" +#include "pal_mstypes.h" +#include "pal_error.h" +#include <new> +#include <memory.h> + +#define wcslen PAL_wcslen + +bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer) +{ + newSize = (size_t)(newSize * 1.5); + _ASSERTE(newSize > size); // check for overflow + + if (newSize < 32) + newSize = 32; + + // We can't use coreclr includes here so we use std::nothrow + // rather than the coreclr version + char *newBuffer = new (std::nothrow) char[newSize]; + + if (newBuffer == NULL) + return false; + + memcpy(newBuffer, buffer, currLen); + + if (!fixedBuffer) + delete[] buffer; + + buffer = newBuffer; + size = newSize; + fixedBuffer = false; + + return true; +} + +bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +{ + if(!src) return true; + if (offset + len > size) + { + if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) + return false; + } + + memcpy(buffer + offset, src, len); + offset += len; + return true; +} + +bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +{ + if(!str) return true; + size_t byteCount = (wcslen(str) + 1) * sizeof(*str); + + if (offset + byteCount > size) + { + if (!ResizeBuffer(buffer, size, offset, size + byteCount, fixedBuffer)) + return false; + } + + memcpy(buffer + offset, str, byteCount); + offset += byteCount; + return true; +} + +bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +{ + if(!str) return true; + size_t len = strlen(str) + 1; + if (offset + len > size) + { + if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) + return false; + } + + memcpy(buffer + offset, str, len); + offset += len; + return true; +} diff --git a/src/pal/tests/palsuite/CMakeLists.txt b/src/pal/tests/palsuite/CMakeLists.txt index 38b8ed0459..6726165caf 100644 --- a/src/pal/tests/palsuite/CMakeLists.txt +++ b/src/pal/tests/palsuite/CMakeLists.txt @@ -40,5 +40,5 @@ add_subdirectory(samples) add_subdirectory(threading) if(FEATURE_EVENT_TRACE) - add_subdirectory(${GENERATED_EVENTING_DIR}/eventprovider/tests ${CMAKE_CURRENT_BINARY_DIR}/eventprovider) + add_subdirectory(eventprovider) endif(FEATURE_EVENT_TRACE) diff --git a/src/pal/tests/palsuite/eventprovider/CMakeLists.txt b/src/pal/tests/palsuite/eventprovider/CMakeLists.txt new file mode 100644 index 0000000000..f74fc9b604 --- /dev/null +++ b/src/pal/tests/palsuite/eventprovider/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +set(SOURCES + ${CMAKE_CURRENT_BINARY_DIR}/clralltestevents.cpp +) + +set(EVENT_MANIFEST ${VM_DIR}/ClrEtwAll.man) +set(TEST_GENERATOR ${CLR_DIR}/src/scripts/genEventingTests.py) + +include(FindPythonInterp) + +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/clralltestevents.cpp + COMMAND ${PYTHON_EXECUTABLE} ${TEST_GENERATOR} --testdir "${CMAKE_CURRENT_BINARY_DIR}" --man "${EVENT_MANIFEST}" + DEPENDS ${EVENT_MANIFEST} ${TEST_GENERATOR} + COMMENT "Updating clralltestevents.cpp" +) + +include_directories(${GENERATED_INCLUDE_DIR}) + +if(FEATURE_PAL) + include_directories(${COREPAL_SOURCE_DIR}/inc/rt) +endif(FEATURE_PAL) + +add_executable(eventprovidertest + ${SOURCES} + ) +set(EVENT_PROVIDER_DEPENDENCIES "") +if(FEATURE_EVENT_TRACE) + add_definitions(-DFEATURE_EVENT_TRACE=1) + list(APPEND EVENT_PROVIDER_DEPENDENCIES + eventprovider + ) + if(CLR_CMAKE_PLATFORM_LINUX) + list(APPEND EVENT_PROVIDER_DEPENDENCIES + coreclrtraceptprovider + ) + endif(CLR_CMAKE_PLATFORM_LINUX) +endif(FEATURE_EVENT_TRACE) + +target_link_libraries(eventprovidertest ${EVENT_PROVIDER_DEPENDENCIES} coreclrpal) +add_dependencies(eventprovidertest eventing_headers) diff --git a/src/scripts/genDummyProvider.py b/src/scripts/genDummyProvider.py index 0704554263..5fb44e8397 100644 --- a/src/scripts/genDummyProvider.py +++ b/src/scripts/genDummyProvider.py @@ -25,16 +25,6 @@ This file is generated using the logic from <root>/src/scripts/genDummyProvider. ******************************************************************/ """ -stdprolog_cmake=""" -# -# -#****************************************************************** - -#DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genDummyProvider.py - -#****************************************************************** -""" def trimProvName(name): name = name.replace("Windows-",'') @@ -105,7 +95,7 @@ def generateDummyProvider(providerName, eventNodes, allTemplates, extern): return ''.join(impl) -def generateDummyFiles(etwmanifest, out_dirname, extern): +def generateDummyFiles(etwmanifest, out_dirname, extern, dryRun): tree = DOM.parse(etwmanifest) #keep these relative @@ -118,40 +108,6 @@ def generateDummyFiles(etwmanifest, out_dirname, extern): if not os.path.exists(os.path.join(out_dirname, dummy_directory)): os.makedirs(os.path.join(out_dirname, dummy_directory)) - # Cmake - with open_for_update(os.path.join(out_dirname, "CMakeLists.txt")) as cmake: - cmake.write(stdprolog_cmake + "\n") - cmake.write("\ncmake_minimum_required(VERSION 2.8.12.2)\n") - if extern: cmake.write("\nproject(eventprovider)\n") - cmake.write(""" - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -if(FEATURE_PAL) - add_definitions(-DPAL_STDCPP_COMPAT=1) - include_directories(${COREPAL_SOURCE_DIR}/inc/rt) -endif(FEATURE_PAL) -include_directories(dummy) - -""") - if extern: cmake.write("add_library") - else: cmake.write("add_library_clr") - cmake.write("""(eventprovider - STATIC\n""") - - for providerNode in tree.getElementsByTagName('provider'): - providerName = trimProvName(providerNode.getAttribute('name')) - providerName_File = escapeProvFilename(providerName) - - cmake.write(' "%s%s.cpp"\n' % (dummyevntprovPre, providerName_File)) - - cmake.write(")") - if extern: cmake.write(""" - -# Install the static eventprovider library -install(TARGETS eventprovider DESTINATION lib) -""") - # Dummy Instrumentation for providerNode in tree.getElementsByTagName('provider'): providerName = trimProvName(providerNode.getAttribute('name')) @@ -159,10 +115,13 @@ install(TARGETS eventprovider DESTINATION lib) dummyevntprov = os.path.join(out_dirname, dummyevntprovPre + providerName_File + ".cpp") - with open_for_update(dummyevntprov) as impl: - impl.write(stdprolog_cpp + "\n") + if dryRun: + print(dummyevntprov) + else: + with open_for_update(dummyevntprov) as impl: + impl.write(stdprolog_cpp + "\n") - impl.write(""" + impl.write(""" #ifdef PLATFORM_UNIX #include "pal_mstypes.h" #include "pal_error.h" @@ -175,13 +134,13 @@ install(TARGETS eventprovider DESTINATION lib) """) - templateNodes = providerNode.getElementsByTagName('template') - eventNodes = providerNode.getElementsByTagName('event') + templateNodes = providerNode.getElementsByTagName('template') + eventNodes = providerNode.getElementsByTagName('event') - allTemplates = parseTemplateNodes(templateNodes) + allTemplates = parseTemplateNodes(templateNodes) - #create the implementation of eventing functions : dummyeventprov*.cp - impl.write(generateDummyProvider(providerName, eventNodes, allTemplates, extern) + "\n") + #create the implementation of eventing functions : dummyeventprov*.cp + impl.write(generateDummyProvider(providerName, eventNodes, allTemplates, extern) + "\n") def main(argv): @@ -195,6 +154,8 @@ def main(argv): help='full path to eventprovider intermediate directory') required.add_argument('--nonextern', action='store_true', help='if specified, will generate files to be compiled into the CLR rather than externaly' ) + required.add_argument('--dry-run', action='store_true', + help='if specified, will output the names of the generated files instead of generating the files' ) args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) @@ -203,9 +164,10 @@ def main(argv): sClrEtwAllMan = args.man intermediate = args.intermediate extern = not args.nonextern + dryRun = args.dry_run - generateDummyFiles(sClrEtwAllMan, intermediate, extern) + generateDummyFiles(sClrEtwAllMan, intermediate, extern, dryRun) if __name__ == '__main__': return_code = main(sys.argv[1:]) - sys.exit(return_code)
\ No newline at end of file + sys.exit(return_code) diff --git a/src/scripts/genEtwProvider.py b/src/scripts/genEtwProvider.py index 89d3119cf4..adc91bac0c 100644 --- a/src/scripts/genEtwProvider.py +++ b/src/scripts/genEtwProvider.py @@ -37,16 +37,6 @@ This file is generated using the logic from <root>/src/scripts/genEtwProvider.py ******************************************************************/ """ -stdprolog_cmake=""" -# -# -#****************************************************************** - -#DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genEtwProvider.py - -#****************************************************************** -""" def genProviderInterface(manifest, intermediate): provider_dirname = os.path.join(intermediate, etw_dirname + "_temp") @@ -67,29 +57,6 @@ def genProviderInterface(manifest, intermediate): with open(path.join(provider_dirname, mcheader_filename), 'w') as mcheader_file: mcheader_file.write(header_text) -def genCmake(intermediate): - # Top level Cmake - - with open_for_update(os.path.join(intermediate, "CMakeLists.txt")) as cmake_file: - cmake_file.write(stdprolog_cmake) - cmake_file.write(""" -project(eventprovider) - -cmake_minimum_required(VERSION 2.8.12.2) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -include_directories({0}) - -add_library_clr(eventprovider - STATIC - "{0}/{1}" - "{0}/{2}" -) - -#set_target_properties(eventprovider PROPERTIES LINKER_LANGUAGE Hxx) -""".format(etw_dirname, macroheader_filename, "ClrEtwAll.cpp")) - def genXplatHeader(intermediate): with open_for_update(path.join(intermediate, clrxplat_filename)) as header_file: header_file.write(""" diff --git a/src/scripts/genEventPipe.py b/src/scripts/genEventPipe.py index f66b54ea28..3cdbdff089 100644 --- a/src/scripts/genEventPipe.py +++ b/src/scripts/genEventPipe.py @@ -242,41 +242,14 @@ def generateEventKeywords(eventKeywords): return mask - -def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory, extern): - tree = DOM.parse(etwmanifest) - - with open_for_update(os.path.join(eventpipe_directory, "CMakeLists.txt")) as cmake_file: - cmake_file.write(stdprolog_cmake) - cmake_file.write("cmake_minimum_required(VERSION 2.8.12.2)\n") - if extern: cmake_file.write("\nproject(eventpipe)\n") - cmake_file.write(""" - -set(CMAKE_INCLUDE_CURRENT_DIR ON) -include_directories(${CLR_DIR}/src/vm) - -add_library_clr(eventpipe STATIC -""") - for providerNode in tree.getElementsByTagName('provider'): - providerName = providerNode.getAttribute('name') - providerName = providerName.replace("Windows-", '') - providerName = providerName.replace("Microsoft-", '') - - providerName_File = providerName.replace('-', '') - providerName_File = providerName_File.lower() - - cmake_file.write(' "%s/%s.cpp"\n' % (eventpipe_dirname, providerName_File)) - cmake_file.write(' "%s/eventpipehelpers.cpp"\n)' % (eventpipe_dirname,)) - if extern: cmake_file.write(""" - -# Install the static eventpipe library -_install(TARGETS eventpipe DESTINATION lib) -""") - -def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern): - with open_for_update(os.path.join(eventpipe_directory, "eventpipehelpers.cpp")) as helper: - helper.write(stdprolog_cpp) - helper.write(""" +def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern, dryRun): + eventpipehelpersPath = os.path.join(eventpipe_directory, "eventpipehelpers.cpp") + if dryRun: + print(eventpipehelpersPath) + else: + with open_for_update(eventpipehelpersPath) as helper: + helper.write(stdprolog_cpp) + helper.write(""" #include "common.h" #include <stdlib.h> #include <string.h> @@ -360,37 +333,37 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, """) - tree = DOM.parse(etwmanifest) + tree = DOM.parse(etwmanifest) + + for providerNode in tree.getElementsByTagName('provider'): + providerName = providerNode.getAttribute('name') + providerPrettyName = providerName.replace("Windows-", '') + providerPrettyName = providerPrettyName.replace("Microsoft-", '') + providerPrettyName = providerPrettyName.replace('-', '_') + if extern: helper.write( + 'extern "C" ' + ) + helper.write( + "void Init" + + providerPrettyName + + "();\n\n") - for providerNode in tree.getElementsByTagName('provider'): - providerName = providerNode.getAttribute('name') - providerPrettyName = providerName.replace("Windows-", '') - providerPrettyName = providerPrettyName.replace("Microsoft-", '') - providerPrettyName = providerPrettyName.replace('-', '_') if extern: helper.write( 'extern "C" ' ) - helper.write( - "void Init" + - providerPrettyName + - "();\n\n") - - if extern: helper.write( - 'extern "C" ' - ) - helper.write("void InitProvidersAndEvents()\n{\n") - for providerNode in tree.getElementsByTagName('provider'): - providerName = providerNode.getAttribute('name') - providerPrettyName = providerName.replace("Windows-", '') - providerPrettyName = providerPrettyName.replace("Microsoft-", '') - providerPrettyName = providerPrettyName.replace('-', '_') - helper.write(" Init" + providerPrettyName + "();\n") - helper.write("}") - - helper.close() + helper.write("void InitProvidersAndEvents()\n{\n") + for providerNode in tree.getElementsByTagName('provider'): + providerName = providerNode.getAttribute('name') + providerPrettyName = providerName.replace("Windows-", '') + providerPrettyName = providerPrettyName.replace("Microsoft-", '') + providerPrettyName = providerPrettyName.replace('-', '_') + helper.write(" Init" + providerPrettyName + "();\n") + helper.write("}") + + helper.close() def generateEventPipeImplFiles( - etwmanifest, eventpipe_directory, extern, exclusionList): + etwmanifest, eventpipe_directory, extern, exclusionList, dryRun): tree = DOM.parse(etwmanifest) # Find the src directory starting with the assumption that @@ -412,10 +385,13 @@ def generateEventPipeImplFiles( providerName_File = providerName_File.lower() providerPrettyName = providerPrettyName.replace('-', '_') eventpipefile = os.path.join(eventpipe_directory, providerName_File + ".cpp") - with open_for_update(eventpipefile) as eventpipeImpl: - eventpipeImpl.write(stdprolog_cpp) + if dryRun: + print(eventpipefile) + else: + with open_for_update(eventpipefile) as eventpipeImpl: + eventpipeImpl.write(stdprolog_cpp) - header = """ + header = """ #include "{root:s}/vm/common.h" #include "{root:s}/vm/eventpipeprovider.h" #include "{root:s}/vm/eventpipeevent.h" @@ -446,43 +422,39 @@ bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size, """.format(root=src_dirname.replace('\\', '/')) - eventpipeImpl.write(header) - eventpipeImpl.write( - "const WCHAR* %sName = W(\"%s\");\n" % ( - providerPrettyName, - providerName + eventpipeImpl.write(header) + eventpipeImpl.write( + "const WCHAR* %sName = W(\"%s\");\n" % ( + providerPrettyName, + providerName + ) ) - ) - eventpipeImpl.write( - "EventPipeProvider *EventPipeProvider%s = nullptr;\n" % ( - providerPrettyName, + eventpipeImpl.write( + "EventPipeProvider *EventPipeProvider%s = nullptr;\n" % ( + providerPrettyName, + ) ) - ) - templateNodes = providerNode.getElementsByTagName('template') - allTemplates = parseTemplateNodes(templateNodes) - eventNodes = providerNode.getElementsByTagName('event') - eventpipeImpl.write( - generateClrEventPipeWriteEventsImpl( - providerName, - eventNodes, - allTemplates, - extern, - exclusionList) + "\n") - + templateNodes = providerNode.getElementsByTagName('template') + allTemplates = parseTemplateNodes(templateNodes) + eventNodes = providerNode.getElementsByTagName('event') + eventpipeImpl.write( + generateClrEventPipeWriteEventsImpl( + providerName, + eventNodes, + allTemplates, + extern, + exclusionList) + "\n") def generateEventPipeFiles( - etwmanifest, intermediate, extern, exclusionList): + etwmanifest, intermediate, extern, exclusionList, dryRun): eventpipe_directory = os.path.join(intermediate, eventpipe_dirname) tree = DOM.parse(etwmanifest) if not os.path.exists(eventpipe_directory): os.makedirs(eventpipe_directory) - # generate CMake file - generateEventPipeCmakeFile(etwmanifest, intermediate, extern) - # generate helper file - generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern) + generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern, dryRun) # generate all keywords for keywordNode in tree.getElementsByTagName('keyword'): @@ -495,7 +467,8 @@ def generateEventPipeFiles( etwmanifest, eventpipe_directory, extern, - exclusionList + exclusionList, + dryRun ) import argparse @@ -516,6 +489,8 @@ def main(argv): help='full path to eventprovider intermediate directory') required.add_argument('--nonextern', action='store_true', help='if specified, will generate files to be compiled into the CLR rather than extern' ) + required.add_argument('--dry-run', action='store_true', + help='if specified, will output the names of the generated files instead of generating the files' ) args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) @@ -525,8 +500,9 @@ def main(argv): exclusion_filename = args.exc intermediate = args.intermediate extern = not args.nonextern + dryRun = args.dry_run - generateEventPipeFiles(sClrEtwAllMan, intermediate, extern, parseExclusionList(exclusion_filename)) + generateEventPipeFiles(sClrEtwAllMan, intermediate, extern, parseExclusionList(exclusion_filename), dryRun) if __name__ == '__main__': return_code = main(sys.argv[1:]) diff --git a/src/scripts/genEventing.py b/src/scripts/genEventing.py index 8079bec262..f3c9ad1ce9 100644 --- a/src/scripts/genEventing.py +++ b/src/scripts/genEventing.py @@ -29,17 +29,6 @@ This file is generated using the logic from <root>/src/scripts/genEventing.py ******************************************************************/ """ -stdprolog_cmake=""" -# -# -#****************************************************************** - -#DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genEventing.py - -#****************************************************************** -""" - lindent = " "; palDataTypeMapping ={ #constructed types @@ -492,219 +481,11 @@ def generateclrEtwDummy(eventNodes,allTemplates): return ''.join(clretmEvents) -def generateClralltestEvents(sClrEtwAllMan): - tree = DOM.parse(sClrEtwAllMan) - - clrtestEvents = [] - for providerNode in tree.getElementsByTagName('provider'): - templateNodes = providerNode.getElementsByTagName('template') - allTemplates = parseTemplateNodes(templateNodes) - eventNodes = providerNode.getElementsByTagName('event') - for eventNode in eventNodes: - eventName = eventNode.getAttribute('symbol') - templateName = eventNode.getAttribute('template') - clrtestEvents.append(" EventXplatEnabled" + eventName + "();\n") - clrtestEvents.append("Error |= FireEtXplat" + eventName + "(\n") - - line =[] - if templateName: - template = allTemplates[templateName] - fnSig = template.signature - - for params in fnSig.paramlist: - if params in template.structs: - line.append("sizeof(Struct1),\n") - - argline ='' - fnparam = fnSig.getParam(params) - if fnparam.name.lower() == 'count': - argline = '2' - else: - if fnparam.winType == "win:Binary": - argline = 'win_Binary' - elif fnparam.winType == "win:Pointer" and fnparam.count == "win:count": - argline = "(const void**)&var11" - elif fnparam.winType == "win:Pointer" : - argline = "(const void*)var11" - elif fnparam.winType =="win:AnsiString": - argline = '" Testing AniString "' - elif fnparam.winType =="win:UnicodeString": - argline = 'W(" Testing UnicodeString ")' - else: - if fnparam.count == "win:count": - line.append("&") - - argline = fnparam.winType.replace(":","_") - - line.append(argline) - line.append(",\n") - - #remove trailing commas - if len(line) > 0: - del line[-1] - line.append("\n") - line.append(");\n") - clrtestEvents.extend(line) - - return ''.join(clrtestEvents) - -def generateSanityTest(sClrEtwAllMan,testDir): - - if not testDir: - return - print('Generating Event Logging Tests') - - if not os.path.exists(testDir): - os.makedirs(testDir) - - cmake_file = testDir + "/CMakeLists.txt" - test_cpp = "clralltestevents.cpp" - testinfo = testDir + "/testinfo.dat" - - #CMake File: - with open_for_update(cmake_file) as Cmake_file: - Cmake_file.write(stdprolog_cmake) - Cmake_file.write(""" -cmake_minimum_required(VERSION 2.8.12.2) -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(SOURCES -""") - Cmake_file.write(test_cpp) - Cmake_file.write(""" - ) -include_directories(${GENERATED_INCLUDE_DIR}) - -if(FEATURE_PAL) - include_directories(${COREPAL_SOURCE_DIR}/inc/rt) -endif(FEATURE_PAL) - -add_executable(eventprovidertest - ${SOURCES} - ) -set(EVENT_PROVIDER_DEPENDENCIES "") -set(EVENT_PROVIDER_LINKER_OTPTIONS "") -if(FEATURE_EVENT_TRACE) - add_definitions(-DFEATURE_EVENT_TRACE=1) - list(APPEND EVENT_PROVIDER_DEPENDENCIES - eventprovider - ) - if(CLR_CMAKE_PLATFORM_LINUX) - list(APPEND EVENT_PROVIDER_DEPENDENCIES - coreclrtraceptprovider - ) - endif(CLR_CMAKE_PLATFORM_LINUX) - list(APPEND EVENT_PROVIDER_LINKER_OTPTIONS - ${EVENT_PROVIDER_DEPENDENCIES} - ) -endif(FEATURE_EVENT_TRACE) - -add_dependencies(eventprovidertest ${EVENT_PROVIDER_DEPENDENCIES} coreclrpal) -target_link_libraries(eventprovidertest - coreclrpal - ${EVENT_PROVIDER_LINKER_OTPTIONS} - ) -""") - - - with open_for_update(testinfo) as Testinfo: - Testinfo.write(""" -Copyright (c) Microsoft Corporation. All rights reserved. -# - -Version = 1.0 -Section = EventProvider -Function = EventProvider -Name = PAL test for FireEtW* and EventEnabled* functions -TYPE = DEFAULT -EXE1 = eventprovidertest -Description = This is a sanity test to check that there are no crashes in Xplat eventing -""") - - #Test.cpp - with open_for_update(testDir + "/" + test_cpp) as Test_cpp: - Test_cpp.write(stdprolog) - Test_cpp.write(""" -/*===================================================================== -** -** Source: clralltestevents.cpp -** -** Purpose: Ensure Correctness of Eventing code -** -** -**===================================================================*/ -#if FEATURE_PAL -#include <palsuite.h> -#endif //FEATURE_PAL -#include <clrxplatevents.h> - -typedef struct _Struct1 { - ULONG Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} Struct1; - -Struct1 var21[2] = { { 245, 13, 14, "deadbea" }, { 542, 0, 14, "deadflu" } }; - -Struct1* var11 = var21; -Struct1* win_Struct = var21; - -GUID win_GUID ={ 245, 13, 14, "deadbea" }; -double win_Double =34.04; -ULONG win_ULong = 34; -BOOL win_Boolean = FALSE; -unsigned __int64 win_UInt64 = 114; -unsigned int win_UInt32 = 4; -unsigned short win_UInt16 = 12; -unsigned char win_UInt8 = 9; -int win_Int32 = 12; -BYTE* win_Binary =(BYTE*)var21 ; -int __cdecl main(int argc, char **argv) -{ -#if defined(FEATURE_PAL) - /* Initialize the PAL. - */ - - if(0 != PAL_Initialize(argc, argv)) - { - return FAIL; - } -#endif - - ULONG Error = ERROR_SUCCESS; -#if defined(FEATURE_EVENT_TRACE) - Trace("\\n Starting functional eventing APIs tests \\n"); -""") - - Test_cpp.write(generateClralltestEvents(sClrEtwAllMan)) - Test_cpp.write(""" - - if (Error != ERROR_SUCCESS) - { - Fail("One or more eventing Apis failed\\n "); - return FAIL; - } - Trace("\\n All eventing APIs were fired succesfully \\n"); -#endif //defined(FEATURE_EVENT_TRACE) -#if defined(FEATURE_PAL) - -/* Shutdown the PAL. -*/ - - PAL_Terminate(); -#endif - return PASS; - } - -""") - Testinfo.close() - def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy): if not clretwdummy: return - print(' Generating Dummy Event Headers') tree = DOM.parse(sClrEtwAllMan) incDir = os.path.dirname(os.path.realpath(clretwdummy)) @@ -729,7 +510,6 @@ def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern if not incDir: return - print(' Generating Event Headers') if not os.path.exists(incDir): os.makedirs(incDir) @@ -792,8 +572,6 @@ def main(argv): help='full path to directory where the header files will be generated') required.add_argument('--dummy', type=str,default=None, help='full path to file that will have dummy definitions of FireEtw functions') - required.add_argument('--testdir', type=str, default=None, - help='full path to directory where the test assets will be deployed' ) required.add_argument('--nonextern', action='store_true', help='if specified, will not generated extern function stub headers' ) required.add_argument('--noxplatheader', action='store_true', @@ -806,12 +584,10 @@ def main(argv): sClrEtwAllMan = args.man incdir = args.inc etmDummyFile = args.dummy - testDir = args.testdir extern = not args.nonextern write_xplatheader = not args.noxplatheader generatePlatformIndependentFiles(sClrEtwAllMan, incdir, etmDummyFile, extern, write_xplatheader) - generateSanityTest(sClrEtwAllMan, testDir) if __name__ == '__main__': return_code = main(sys.argv[1:]) diff --git a/src/scripts/genEventingTests.py b/src/scripts/genEventingTests.py new file mode 100644 index 0000000000..8039e557bc --- /dev/null +++ b/src/scripts/genEventingTests.py @@ -0,0 +1,206 @@ +# Python 2 compatibility +from __future__ import print_function + +import os +import xml.dom.minidom as DOM +from genEventing import parseTemplateNodes +from utilities import open_for_update + +stdprolog=""" +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************** + +DO NOT MODIFY. AUTOGENERATED FILE. +This file is generated using the logic from <root>/src/scripts/genEventing.py + +******************************************************************/ +""" + + +def generateClralltestEvents(sClrEtwAllMan): + tree = DOM.parse(sClrEtwAllMan) + + clrtestEvents = [] + for providerNode in tree.getElementsByTagName('provider'): + templateNodes = providerNode.getElementsByTagName('template') + allTemplates = parseTemplateNodes(templateNodes) + eventNodes = providerNode.getElementsByTagName('event') + for eventNode in eventNodes: + eventName = eventNode.getAttribute('symbol') + templateName = eventNode.getAttribute('template') + clrtestEvents.append(" EventXplatEnabled" + eventName + "();\n") + clrtestEvents.append("Error |= FireEtXplat" + eventName + "(\n") + + line =[] + if templateName: + template = allTemplates[templateName] + fnSig = template.signature + + for params in fnSig.paramlist: + if params in template.structs: + line.append("sizeof(Struct1),\n") + + argline ='' + fnparam = fnSig.getParam(params) + if fnparam.name.lower() == 'count': + argline = '2' + else: + if fnparam.winType == "win:Binary": + argline = 'win_Binary' + elif fnparam.winType == "win:Pointer" and fnparam.count == "win:count": + argline = "(const void**)&var11" + elif fnparam.winType == "win:Pointer" : + argline = "(const void*)var11" + elif fnparam.winType =="win:AnsiString": + argline = '" Testing AniString "' + elif fnparam.winType =="win:UnicodeString": + argline = 'W(" Testing UnicodeString ")' + else: + if fnparam.count == "win:count": + line.append("&") + + argline = fnparam.winType.replace(":","_") + + line.append(argline) + line.append(",\n") + + #remove trailing commas + if len(line) > 0: + del line[-1] + line.append("\n") + line.append(");\n") + clrtestEvents.extend(line) + + return ''.join(clrtestEvents) + +def generateSanityTest(sClrEtwAllMan,testDir): + + if not os.path.exists(testDir): + os.makedirs(testDir) + + test_cpp = testDir + "/clralltestevents.cpp" + testinfo = testDir + "/testinfo.dat" + + with open_for_update(testinfo) as Testinfo: + Testinfo.write(""" +Copyright (c) Microsoft Corporation. All rights reserved. +# + +Version = 1.0 +Section = EventProvider +Function = EventProvider +Name = PAL test for FireEtW* and EventEnabled* functions +TYPE = DEFAULT +EXE1 = eventprovidertest +Description = This is a sanity test to check that there are no crashes in Xplat eventing +""") + + #Test.cpp + with open_for_update(test_cpp) as Test_cpp: + Test_cpp.write(stdprolog) + Test_cpp.write(""" +/*===================================================================== +** +** Source: clralltestevents.cpp +** +** Purpose: Ensure Correctness of Eventing code +** +** +**===================================================================*/ +#if FEATURE_PAL +#include <palsuite.h> +#endif //FEATURE_PAL +#include <clrxplatevents.h> + +typedef struct _Struct1 { + ULONG Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[8]; +} Struct1; + +Struct1 var21[2] = { { 245, 13, 14, "deadbea" }, { 542, 0, 14, "deadflu" } }; + +Struct1* var11 = var21; +Struct1* win_Struct = var21; + +GUID win_GUID ={ 245, 13, 14, "deadbea" }; +double win_Double =34.04; +ULONG win_ULong = 34; +BOOL win_Boolean = FALSE; +unsigned __int64 win_UInt64 = 114; +unsigned int win_UInt32 = 4; +unsigned short win_UInt16 = 12; +unsigned char win_UInt8 = 9; +int win_Int32 = 12; +BYTE* win_Binary =(BYTE*)var21 ; +int __cdecl main(int argc, char **argv) +{ +#if defined(FEATURE_PAL) + /* Initialize the PAL. + */ + + if(0 != PAL_Initialize(argc, argv)) + { + return FAIL; + } +#endif + + ULONG Error = ERROR_SUCCESS; +#if defined(FEATURE_EVENT_TRACE) + Trace("\\n Starting functional eventing APIs tests \\n"); +""") + + Test_cpp.write(generateClralltestEvents(sClrEtwAllMan)) + Test_cpp.write(""" + + if (Error != ERROR_SUCCESS) + { + Fail("One or more eventing Apis failed\\n "); + return FAIL; + } + Trace("\\n All eventing APIs were fired succesfully \\n"); +#endif //defined(FEATURE_EVENT_TRACE) +#if defined(FEATURE_PAL) + +/* Shutdown the PAL. +*/ + + PAL_Terminate(); +#endif + return PASS; + } + +""") + Testinfo.close() + + +import argparse +import sys + +def main(argv): + + #parse the command line + parser = argparse.ArgumentParser(description="Generates the Code required to instrument LTTtng logging mechanism") + + required = parser.add_argument_group('required arguments') + required.add_argument('--man', type=str, required=True, + help='full path to manifest containig the description of events') + required.add_argument('--testdir', type=str, required=True, + help='full path to directory where the test assets will be deployed' ) + args, unknown = parser.parse_known_args(argv) + if unknown: + print('Unknown argument(s): ', ', '.join(unknown)) + return 1 + + sClrEtwAllMan = args.man + testDir = args.testdir + + generateSanityTest(sClrEtwAllMan, testDir) + +if __name__ == '__main__': + return_code = main(sys.argv[1:]) + sys.exit(return_code) diff --git a/src/scripts/genLttngProvider.py b/src/scripts/genLttngProvider.py index dfbd68d516..cf938f6b6d 100644 --- a/src/scripts/genLttngProvider.py +++ b/src/scripts/genLttngProvider.py @@ -65,16 +65,6 @@ This file is generated using the logic from <root>/src/scripts/genLttngProvider. ******************************************************************/ """ -stdprolog_cmake=""" -# -# -#****************************************************************** - -#DO NOT MODIFY. AUTOGENERATED FILE. -#This file is generated using the logic from <root>/src/scripts/genLttngProvider.py - -#****************************************************************** -""" specialCaseSizes = { "BulkType" : { "Values" : "Values_ElementSize" }, "GCBulkRootCCW" : { "Values" : "Values_ElementSize" }, "GCBulkRCW" : { "Values" : "Values_ElementSize" }, "GCBulkRootStaticVar" : { "Values" : "Values_ElementSize" } } @@ -468,7 +458,7 @@ def generateLttngTpProvider(providerName, eventNodes, allTemplates): -def generateLttngFiles(etwmanifest,eventprovider_directory): +def generateLttngFiles(etwmanifest,eventprovider_directory, dryRun): eventprovider_directory = eventprovider_directory + "/" tree = DOM.parse(etwmanifest) @@ -489,168 +479,6 @@ def generateLttngFiles(etwmanifest,eventprovider_directory): if not os.path.exists(eventprovider_directory + tracepointprovider_directory): os.makedirs(eventprovider_directory + tracepointprovider_directory) -#Top level Cmake - with open_for_update(eventprovider_directory + "CMakeLists.txt") as topCmake: - topCmake.write(stdprolog_cmake + "\n") - topCmake.write("""cmake_minimum_required(VERSION 2.8.12.2) - - project(eventprovider) - - set(CMAKE_INCLUDE_CURRENT_DIR ON) - - add_definitions(-DPAL_STDCPP_COMPAT=1) - include_directories(${COREPAL_SOURCE_DIR}/inc/rt) - include_directories(lttng) - - add_library(eventprovider - STATIC - """) - - for providerNode in tree.getElementsByTagName('provider'): - providerName = providerNode.getAttribute('name') - providerName = providerName.replace("Windows-",'') - providerName = providerName.replace("Microsoft-",'') - - providerName_File = providerName.replace('-','') - providerName_File = providerName_File.lower() - - topCmake.write(' "%s%s.cpp"\n' % (lttngevntprovPre, providerName_File)) - - topCmake.write(' "%shelpers.cpp"\n' % (lttngevntprovPre,)) - topCmake.write(""") - add_subdirectory(tracepointprovider) - - # Install the static eventprovider library - _install(TARGETS eventprovider DESTINATION lib) - """) - -#TracepointProvider Cmake - - with open_for_update(eventprovider_directory + tracepointprovider_directory + "/CMakeLists.txt") as tracepointprovider_Cmake: - tracepointprovider_Cmake.write(stdprolog_cmake + "\n") - tracepointprovider_Cmake.write("""cmake_minimum_required(VERSION 2.8.12.2) - - project(coreclrtraceptprovider) - - set(CMAKE_INCLUDE_CURRENT_DIR ON) - - add_definitions(-DPAL_STDCPP_COMPAT=1) - include_directories(${COREPAL_SOURCE_DIR}/inc/rt) - include_directories(../lttng/) - add_compile_options(-fPIC) - - add_library(coreclrtraceptprovider - SHARED - """) - - for providerNode in tree.getElementsByTagName('provider'): - providerName = providerNode.getAttribute('name') - providerName = providerName.replace("Windows-",'') - providerName = providerName.replace("Microsoft-",'') - - providerName_File = providerName.replace('-','') - providerName_File = providerName_File.lower() - - tracepointprovider_Cmake.write(' "../'+ lttngevntprovTpPre + providerName_File +".cpp" + '"\n') - - tracepointprovider_Cmake.write(""" ) - - find_library(LTTNG NAMES lttng-ust) - - target_link_libraries(coreclrtraceptprovider - ${LTTNG} - ) - - # Install the static coreclrtraceptprovider library - install_clr(coreclrtraceptprovider) - """) - - with open_for_update(eventprovider_directory + lttng_directory + "/eventprovhelpers.cpp") as helper: - helper.write(""" -#include "palrt.h" -#include "pal.h" -#include "stdlib.h" -#include "pal_mstypes.h" -#include "pal_error.h" -#include <new> -#include <memory.h> - -#define wcslen PAL_wcslen - -bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer) -{ - newSize = (size_t)(newSize * 1.5); - _ASSERTE(newSize > size); // check for overflow - - if (newSize < 32) - newSize = 32; - - // We can't use coreclr includes here so we use std::nothrow - // rather than the coreclr version - char *newBuffer = new (std::nothrow) char[newSize]; - - if (newBuffer == NULL) - return false; - - memcpy(newBuffer, buffer, currLen); - - if (!fixedBuffer) - delete[] buffer; - - buffer = newBuffer; - size = newSize; - fixedBuffer = false; - - return true; -} - -bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) -{ - if(!src) return true; - if (offset + len > size) - { - if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) - return false; - } - - memcpy(buffer + offset, src, len); - offset += len; - return true; -} - -bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) -{ - if(!str) return true; - size_t byteCount = (wcslen(str) + 1) * sizeof(*str); - - if (offset + byteCount > size) - { - if (!ResizeBuffer(buffer, size, offset, size + byteCount, fixedBuffer)) - return false; - } - - memcpy(buffer + offset, str, byteCount); - offset += byteCount; - return true; -} - -bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) -{ - if(!str) return true; - size_t len = strlen(str) + 1; - if (offset + len > size) - { - if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) - return false; - } - - memcpy(buffer + offset, str, len); - offset += len; - return true; -} - -""") - # Generate Lttng specific instrumentation for providerNode in tree.getElementsByTagName('provider'): @@ -671,10 +499,14 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, eventNodes = providerNode.getElementsByTagName('event') allTemplates = parseTemplateNodes(templateNodes) - - with open_for_update(lttngevntheader) as lttnghdr_file: - lttnghdr_file.write(stdprolog + "\n") - lttnghdr_file.write(""" + if dryRun: + print(lttngevntheader) + print(lttngevntprov) + print(lttngevntprovTp) + else: + with open_for_update(lttngevntheader) as lttnghdr_file: + lttnghdr_file.write(stdprolog + "\n") + lttnghdr_file.write(""" #include "palrt.h" #include "pal.h" @@ -682,24 +514,24 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, """) - lttnghdr_file.write("#define TRACEPOINT_PROVIDER " + providerName + "\n") - lttnghdr_file.write(""" + lttnghdr_file.write("#define TRACEPOINT_PROVIDER " + providerName + "\n") + lttnghdr_file.write(""" #undef TRACEPOINT_INCLUDE """) - lttnghdr_file.write("#define TRACEPOINT_INCLUDE \"./" + lttngevntheadershortname + "\"\n\n") + lttnghdr_file.write("#define TRACEPOINT_INCLUDE \"./" + lttngevntheadershortname + "\"\n\n") - lttnghdr_file.write("#if !defined(LTTNG_CORECLR_H" + providerName + ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n\n") - lttnghdr_file.write("#define LTTNG_CORECLR_H" + providerName + "\n") + lttnghdr_file.write("#if !defined(LTTNG_CORECLR_H" + providerName + ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n\n") + lttnghdr_file.write("#define LTTNG_CORECLR_H" + providerName + "\n") - lttnghdr_file.write("\n#include <lttng/tracepoint.h>\n\n") + lttnghdr_file.write("\n#include <lttng/tracepoint.h>\n\n") - lttnghdr_file.write(generateLttngHeader(providerName,allTemplates,eventNodes) + "\n") + lttnghdr_file.write(generateLttngHeader(providerName,allTemplates,eventNodes) + "\n") - with open_for_update(lttngevntprov) as lttngimpl_file: - lttngimpl_file.write(stdprolog + "\n") - lttngimpl_file.write(""" + with open_for_update(lttngevntprov) as lttngimpl_file: + lttngimpl_file.write(stdprolog + "\n") + lttngimpl_file.write(""" #define TRACEPOINT_DEFINE #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE @@ -711,9 +543,9 @@ bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, #define PAL_realloc realloc #include "pal/stackstring.hpp" """) - lttngimpl_file.write("#include \"" + lttngevntheadershortname + "\"\n\n") + lttngimpl_file.write("#include \"" + lttngevntheadershortname + "\"\n\n") - lttngimpl_file.write("""#ifndef tracepoint_enabled + lttngimpl_file.write("""#ifndef tracepoint_enabled #define tracepoint_enabled(provider, name) TRUE #define do_tracepoint tracepoint #endif @@ -740,14 +572,14 @@ bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size, } """) - lttngimpl_file.write(generateLttngTpProvider(providerName,eventNodes,allTemplates) + "\n") + lttngimpl_file.write(generateLttngTpProvider(providerName,eventNodes,allTemplates) + "\n") - with open_for_update(lttngevntprovTp) as tpimpl_file: - tpimpl_file.write(stdprolog + "\n") + with open_for_update(lttngevntprovTp) as tpimpl_file: + tpimpl_file.write(stdprolog + "\n") - tpimpl_file.write("\n#define TRACEPOINT_CREATE_PROBES\n") + tpimpl_file.write("\n#define TRACEPOINT_CREATE_PROBES\n") - tpimpl_file.write("#include \"./"+lttngevntheadershortname + "\"\n") + tpimpl_file.write("#include \"./"+lttngevntheadershortname + "\"\n") import argparse import sys @@ -762,6 +594,8 @@ def main(argv): help='full path to manifest containig the description of events') required.add_argument('--intermediate', type=str, required=True, help='full path to eventprovider intermediate directory') + required.add_argument('--dry-run', action='store_true', + help='if specified, will output the names of the generated files instead of generating the files' ) args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) @@ -769,8 +603,9 @@ def main(argv): sClrEtwAllMan = args.man intermediate = args.intermediate + dryRun = args.dry_run - generateLttngFiles(sClrEtwAllMan,intermediate) + generateLttngFiles(sClrEtwAllMan,intermediate, dryRun) if __name__ == '__main__': return_code = main(sys.argv[1:]) diff --git a/src/strongname/api/crossgen/CMakeLists.txt b/src/strongname/api/crossgen/CMakeLists.txt index 2db453648a..5632c0321b 100644 --- a/src/strongname/api/crossgen/CMakeLists.txt +++ b/src/strongname/api/crossgen/CMakeLists.txt @@ -1,3 +1,4 @@ include(${CLR_DIR}/crossgen.cmake) add_library_clr(strongname_crossgen ${STRONGNAME_SOURCES}) +add_dependencies(strongname_crossgen eventing_headers) diff --git a/src/strongname/api/dac/CMakeLists.txt b/src/strongname/api/dac/CMakeLists.txt index 877125963b..ee4fc2fb51 100644 --- a/src/strongname/api/dac/CMakeLists.txt +++ b/src/strongname/api/dac/CMakeLists.txt @@ -2,3 +2,4 @@ include(${CLR_DIR}/dac.cmake) add_library_clr(strongname_dac ${STRONGNAME_SOURCES}) +add_dependencies(strongname_dac eventing_headers) diff --git a/src/strongname/api/wks/CMakeLists.txt b/src/strongname/api/wks/CMakeLists.txt index 09c9f4c19d..fcd6f8af07 100644 --- a/src/strongname/api/wks/CMakeLists.txt +++ b/src/strongname/api/wks/CMakeLists.txt @@ -1 +1,2 @@ add_library_clr(strongname_wks ${STRONGNAME_SOURCES}) +add_dependencies(strongname_wks eventing_headers) diff --git a/src/unwinder/dac/CMakeLists.txt b/src/unwinder/dac/CMakeLists.txt index ff7bd73114..7a670e815f 100644 --- a/src/unwinder/dac/CMakeLists.txt +++ b/src/unwinder/dac/CMakeLists.txt @@ -3,3 +3,4 @@ include(${CLR_DIR}/dac.cmake) add_definitions(-DFEATURE_NO_HOST) add_library_clr(unwinder_dac ${UNWINDER_SOURCES}) +add_dependencies(unwinder_dac eventing_headers) diff --git a/src/unwinder/wks/CMakeLists.txt b/src/unwinder/wks/CMakeLists.txt index 728cc10db1..b23cb79648 100644 --- a/src/unwinder/wks/CMakeLists.txt +++ b/src/unwinder/wks/CMakeLists.txt @@ -1 +1,2 @@ add_library_clr(unwinder_wks ${UNWINDER_SOURCES}) +add_dependencies(unwinder_wks eventing_headers) diff --git a/src/utilcode/CMakeLists.txt b/src/utilcode/CMakeLists.txt index fa9abb73c8..4e5f73faf1 100644 --- a/src/utilcode/CMakeLists.txt +++ b/src/utilcode/CMakeLists.txt @@ -101,6 +101,8 @@ set(UTILCODE_STATICNOHOST_SOURCES hostimpl.cpp ) +set (UTILCODE_DEPENDENCIES eventing_headers) + convert_to_absolute_path(UTILCODE_SOURCES ${UTILCODE_SOURCES}) convert_to_absolute_path(UTILCODE_DAC_SOURCES ${UTILCODE_DAC_SOURCES}) convert_to_absolute_path(UTILCODE_CROSSGEN_SOURCES ${UTILCODE_CROSSGEN_SOURCES}) diff --git a/src/utilcode/crossgen/CMakeLists.txt b/src/utilcode/crossgen/CMakeLists.txt index cfa3370c1a..41dd6d2306 100644 --- a/src/utilcode/crossgen/CMakeLists.txt +++ b/src/utilcode/crossgen/CMakeLists.txt @@ -5,3 +5,5 @@ add_library_clr(utilcode_crossgen STATIC ${UTILCODE_CROSSGEN_SOURCES}) if(CLR_CMAKE_PLATFORM_UNIX) target_link_libraries(utilcode_crossgen nativeresourcestring) endif(CLR_CMAKE_PLATFORM_UNIX) + +add_dependencies(utilcode_crossgen ${UTILCODE_DEPENDENCIES}) diff --git a/src/utilcode/dac/CMakeLists.txt b/src/utilcode/dac/CMakeLists.txt index 9199fcce65..07d3e1b422 100644 --- a/src/utilcode/dac/CMakeLists.txt +++ b/src/utilcode/dac/CMakeLists.txt @@ -10,3 +10,5 @@ else() add_precompiled_header(stdafx.h ../stdafx.cpp UTILCODE_DAC_SOURCES) add_library_clr(utilcode_dac STATIC ${UTILCODE_DAC_SOURCES}) endif(CLR_CMAKE_PLATFORM_UNIX) + +add_dependencies(utilcode_dac ${UTILCODE_DEPENDENCIES}) diff --git a/src/utilcode/dyncrt/CMakeLists.txt b/src/utilcode/dyncrt/CMakeLists.txt index 1de80fcfb5..752e32b9e9 100644 --- a/src/utilcode/dyncrt/CMakeLists.txt +++ b/src/utilcode/dyncrt/CMakeLists.txt @@ -7,3 +7,5 @@ else() add_precompiled_header(stdafx.h ../stdafx.cpp UTILCODE_SOURCES) add_library_clr(utilcode STATIC ${UTILCODE_SOURCES}) endif(CLR_CMAKE_PLATFORM_UNIX) + +add_dependencies(utilcode ${UTILCODE_DEPENDENCIES}) diff --git a/src/utilcode/staticnohost/CMakeLists.txt b/src/utilcode/staticnohost/CMakeLists.txt index eea4d60785..5947718d89 100644 --- a/src/utilcode/staticnohost/CMakeLists.txt +++ b/src/utilcode/staticnohost/CMakeLists.txt @@ -10,3 +10,5 @@ add_library_clr(utilcodestaticnohost STATIC ${UTILCODE_STATICNOHOST_SOURCES}) if(CLR_CMAKE_PLATFORM_UNIX) target_link_libraries(utilcodestaticnohost nativeresourcestring) endif(CLR_CMAKE_PLATFORM_UNIX) + +add_dependencies(utilcodestaticnohost ${UTILCODE_DEPENDENCIES}) diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index df83214b77..b4c635924c 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -917,5 +917,5 @@ add_subdirectory(dac) add_subdirectory(wks) if(FEATURE_PERFTRACING) - add_subdirectory(${GENERATED_EVENTING_DIR}/eventpipe ${CMAKE_CURRENT_BINARY_DIR}/eventpipe) + add_subdirectory(eventing) endif(FEATURE_PERFTRACING) diff --git a/src/vm/crossgen/CMakeLists.txt b/src/vm/crossgen/CMakeLists.txt index 6b56893835..ab22869a26 100644 --- a/src/vm/crossgen/CMakeLists.txt +++ b/src/vm/crossgen/CMakeLists.txt @@ -267,3 +267,4 @@ if (CLR_CMAKE_PLATFORM_LINUX) endif (CLR_CMAKE_PLATFORM_LINUX) add_library_clr(cee_crossgen ${VM_CROSSGEN_SOURCES}) +add_dependencies(cee_crossgen eventing_headers) diff --git a/src/vm/crossgen_mscorlib/CMakeLists.txt b/src/vm/crossgen_mscorlib/CMakeLists.txt index c67c567a71..38756ecac2 100644 --- a/src/vm/crossgen_mscorlib/CMakeLists.txt +++ b/src/vm/crossgen_mscorlib/CMakeLists.txt @@ -11,3 +11,4 @@ add_definitions( add_definitions(-DCROSSGEN_MSCORLIB) add_library_clr(mscorlib_crossgen ../mscorlib.cpp) +add_dependencies(cee_crossgen eventing_headers) diff --git a/src/vm/dac/CMakeLists.txt b/src/vm/dac/CMakeLists.txt index bb7ad60ba7..f001f2ec51 100644 --- a/src/vm/dac/CMakeLists.txt +++ b/src/vm/dac/CMakeLists.txt @@ -3,3 +3,4 @@ include(${CLR_DIR}/dac.cmake) add_precompiled_header(common.h ../common.cpp VM_SOURCES_DAC) add_library_clr(cee_dac ${VM_SOURCES_DAC}) +add_dependencies(cee_dac eventing_headers) diff --git a/src/vm/eventing/CMakeLists.txt b/src/vm/eventing/CMakeLists.txt new file mode 100644 index 0000000000..9d3c98802c --- /dev/null +++ b/src/vm/eventing/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 2.8.12) + +set(EVENT_MANIFEST ${VM_DIR}/ClrEtwAll.man) +set(EVENT_EXCLUSIONS ${VM_DIR}/ClrEtwAllMeta.lst) + +if (WIN32) + set(NONEXTERN_ARG "--nonextern") + set(NOXPLATHEADER_ARG "--noxplatheader") +else() + set(NEED_XPLAT_HEADER ON) +endif() + +include(FindPythonInterp) + +set (EventingHeaders + ${GENERATED_INCLUDE_DIR}/etmdummy.h + ${GENERATED_INCLUDE_DIR}/clretwallmain.h + ${GENERATED_INCLUDE_DIR}/clreventpipewriteevents.h +) + +if (NEED_XPLAT_HEADER) + list(APPEND EventingHeaders + ${GENERATED_INCLUDE_DIR}/clrxplatevents.h) +endif() + +set(GENEVENTING_SCRIPT ${CLR_DIR}/src/scripts/genEventing.py) + +add_custom_target(eventing_headers + ${PYTHON_EXECUTABLE} ${GENEVENTING_SCRIPT} --man ${EVENT_MANIFEST} --inc ${GENERATED_INCLUDE_DIR} --dummy ${GENERATED_INCLUDE_DIR}/etmdummy.h ${NONEXTERN_ARG} ${NOXPLATHEADER_ARG} + DEPENDS ${EVENT_MANIFEST} ${GENEVENTING_SCRIPT} + VERBATIM +) + +set_source_files_properties(${EventingHeaders} PROPERTIES GENERATED TRUE) + +add_dependencies(eventing_headers eventprovider) + +add_subdirectory(eventpipe) + +if(WIN32) + add_subdirectory(EtwProvider) +endif() diff --git a/src/vm/eventing/EtwProvider/CMakeLists.txt b/src/vm/eventing/EtwProvider/CMakeLists.txt new file mode 100644 index 0000000000..fe78082846 --- /dev/null +++ b/src/vm/eventing/EtwProvider/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8.12) + +include(FindPythonInterp) + +set(ETW_PROVIDER_SCRIPT ${CLR_DIR}/src/scripts/genEtwProvider.py) + +set (ETW_PROVIDER_OUTPUTS + ${GENERATED_INCLUDE_DIR}/etw/ClrEtwAll.h + ${GENERATED_INCLUDE_DIR}/etw/ClrEtwAll.rc + ${GENERATED_INCLUDE_DIR}/etw/etwmacros.h + ${GENERATED_INCLUDE_DIR}/etw/ClrEtwAll_MSG00001.bin + ${GENERATED_INCLUDE_DIR}/etw/ClrEtwAllTEMP.bin + ${GENERATED_INCLUDE_DIR}/clrxplatevents.h +) + +set_source_files_properties(${ETW_PROVIDER_OUTPUTS} PROPERTIES GENERATED TRUE) + +add_custom_target(eventprovider + ${PYTHON_EXECUTABLE} ${ETW_PROVIDER_SCRIPT} --man ${EVENT_MANIFEST} --exc ${EVENT_EXCLUSIONS} --intermediate ${GENERATED_INCLUDE_DIR} + DEPENDS ${EVENT_MANIFEST} ${EVENT_EXCLUSIONS} ${ETW_PROVIDER_SCRIPT}) diff --git a/src/vm/eventing/eventpipe/CMakeLists.txt b/src/vm/eventing/eventpipe/CMakeLists.txt new file mode 100644 index 0000000000..065906e22b --- /dev/null +++ b/src/vm/eventing/eventpipe/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 2.8.12.2) + +include(FindPythonInterp) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(GENERATE_SCRIPT ${CLR_DIR}/src/scripts/genEventPipe.py) +set(GENERATE_COMMAND ${PYTHON_EXECUTABLE} ${GENERATE_SCRIPT} --man ${EVENT_MANIFEST} --exc ${EVENT_EXCLUSIONS} --intermediate ${CMAKE_CURRENT_BINARY_DIR} ${NONEXTERN_ARG}) + +execute_process( + COMMAND ${GENERATE_COMMAND} --dry-run + RESULT_VARIABLE GEN_EVENTPIPE_RESULT + OUTPUT_VARIABLE EVENTPIPE_SOURCE_PATHS + ERROR_VARIABLE GEN_EVENTPIPE_ERRORS +) + +if (NOT GEN_EVENTPIPE_RESULT EQUAL 0) + message(FATAL_ERROR "Failed to generate EventPipe: ${GEN_EVENTPIPE_ERRORS}") +endif() + +string(REPLACE "\n" ";" EVENTPIPE_SOURCE_PATHS ${EVENTPIPE_SOURCE_PATHS}) # turn the outputted list of files into a CMake list + +set (EVENTPIPE_SOURCES "") +foreach(EVENTPIPE_SOURCE_PATH ${EVENTPIPE_SOURCE_PATHS}) + file(TO_CMAKE_PATH ${EVENTPIPE_SOURCE_PATH} EVENTPIPE_SOURCE) + list(APPEND EVENTPIPE_SOURCES ${EVENTPIPE_SOURCE}) +endforeach() + +add_custom_command(OUTPUT ${EVENTPIPE_SOURCES} + COMMAND ${GENERATE_COMMAND} + DEPENDS ${GENERATE_SCRIPT} ${EVENT_MANIFEST} ${EVENT_EXCLUSIONS}) + +add_library_clr(eventpipe STATIC ${EVENTPIPE_SOURCES}) +set_target_properties(eventpipe PROPERTIES LINKER_LANGUAGE CXX) +add_dependencies(eventpipe eventing_headers) + +if (NOT WIN32) + _install(TARGETS eventpipe DESTINATION lib) +endif() diff --git a/src/vm/wks/CMakeLists.txt b/src/vm/wks/CMakeLists.txt index 2c0deaa9bb..db33f4b490 100644 --- a/src/vm/wks/CMakeLists.txt +++ b/src/vm/wks/CMakeLists.txt @@ -46,6 +46,7 @@ if (WIN32) endif (WIN32) add_library_clr(cee_wks ${VM_SOURCES_WKS} ${VM_SOURCES_WKS_ARCH_ASM}) +add_dependencies(cee_wks eventing_headers) if (WIN32) |