Skip to content

Commit

Permalink
Merge pull request #3308 from dnakamura/cmake_ddr
Browse files Browse the repository at this point in the history
CMake: Add initial support for ddrgen
  • Loading branch information
youngar committed Apr 3, 2019
2 parents ae8ff8c + 169003e commit b4b1008
Show file tree
Hide file tree
Showing 23 changed files with 608 additions and 3 deletions.
12 changes: 12 additions & 0 deletions CMakeLists.txt
Expand Up @@ -108,6 +108,18 @@ endif()
configure_file(./omrcfg.CMakeTemplate.h omrcfg.h)
configure_file(./omrversionstrings.CMakeTemplate.h omrversionstrings.h)


###
### Set up DDR configuration
###
include(OmrDDRSupport)

if(NOT DEFINED OMR_DDR_SET)
set(OMR_DDR_SET "omr")
make_ddr_set(${OMR_DDR_SET})
endif()


###
### Native Tooling
###
Expand Down
109 changes: 109 additions & 0 deletions cmake/modules/OmrDDRSupport.cmake
@@ -0,0 +1,109 @@
###############################################################################
# Copyright (c) 2018, 2019 IBM Corp. and others
#
# This program and the accompanying materials are made available under
# the terms of the Eclipse Public License 2.0 which accompanies this
# distribution and is available at http://eclipse.org/legal/epl-2.0
# or the Apache License, Version 2.0 which accompanies this distribution
# and is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# This Source Code may also be made available under the following Secondary
# Licenses when the conditions for such availability set forth in the
# Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
# version 2 with the GNU Classpath Exception [1] and GNU General Public
# License, version 2 with the OpenJDK Assembly Exception [2].
#
# [1] https://www.gnu.org/software/classpath/license.html
# [2] http://openjdk.java.net/legal/assembly-exception.html
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
#############################################################################

if(_OMR_DDR_SUPPORT)
return()
endif()
set(_OMR_DDR_SUPPORT 1)

include(OmrAssert)
include(OmrUtility)
include(ExternalProject)

set(OMR_MODULES_DIR ${CMAKE_CURRENT_LIST_DIR})

function(make_ddr_set set_name)
# if DDR is not enabled, just skip
# Also skip if we are on windows since it is unsupported at the moment
if((OMR_HOST_OS STREQUAL "win") OR (NOT OMR_DDR))
return()
endif()
set(DDR_TARGET_NAME "${set_name}_ddr")
set(DDR_BIN_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DDR_TARGET_NAME}")
set(DDR_TARGETS_LIST "${DDR_BIN_DIR}/targets.list")
set(DDR_MACRO_INPUTS_FILE "${DDR_BIN_DIR}/macros.list")
set(DDR_TOOLS_EXPORT "${omr_BINARY_DIR}/ddr/tools/DDRTools.cmake")

add_custom_command(
OUTPUT "${DDR_BIN_DIR}/config.stamp"
COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${DDR_BIN_DIR}"
)
add_custom_target(${DDR_TARGET_NAME} DEPENDS "${DDR_BIN_DIR}/config.stamp")
set_property(TARGET "${DDR_TARGET_NAME}" PROPERTY DDR_BIN_DIR "${DDR_BIN_DIR}")

file(READ ${OMR_MODULES_DIR}/ddr/DDRSetStub.cmake.in cmakelist_template)
string(CONFIGURE "${cmakelist_template}" cmakelist_template @ONLY)
file(GENERATE OUTPUT ${DDR_BIN_DIR}/CMakeLists.txt CONTENT "${cmakelist_template}")
endfunction(make_ddr_set)


function(target_enable_ddr tgt ddr_set)
if((OMR_HOST_OS STREQUAL "win") OR (NOT OMR_DDR))
return()
endif()

set(opt_EARLY_SOURCE_EVAL )
set(opt_UNPARSED_ARGUMENTS )
cmake_parse_arguments(opt "EARLY_SOURCE_EVAL" "" "" ${ARGN})
omr_assert(FATAL_ERROR TEST NOT opt_UNPARSED_ARGUMENTS MESSAGE "target_enable_ddr: unrecognized options ${opt_UNPARSED_ARGUMENTS}")


set(DDR_SET_TARGET "${ddr_set}_ddr")
omr_assert(FATAL_ERROR TEST TARGET ${tgt} MESSAGE "target_enable_ddr called on non-existant target ${tgt}")
omr_assert(FATAL_ERROR TEST TARGET "${DDR_SET_TARGET}" MESSAGE "target_enable_ddr called on non-existant ddr_set ${ddr_set}")

get_target_property(target_type "${tgt}" TYPE)
if(target_type MATCHES "INTERFACE_LIBRARY")
message(FATAL_ERROR "Cannot call enable_ddr on interface libraries")
endif()

get_property(DDR_BIN_DIR TARGET "${DDR_SET_TARGET}" PROPERTY DDR_BIN_DIR)

if(opt_EARLY_SOURCE_EVAL)
set(source_property "DDR_EVAL_SOURCE")
get_target_property(sources "${tgt}" "SOURCES")
string(GENEX_STRIP "${sources}" cleaned_sources)
set_target_properties("${tgt}" PROPERTIES ${source_property} "${cleaned_sources}")
else()
set(source_property "SOURCES")
endif()
omr_join("\n" MAGIC_TEMPLATE
"SOURCE_DIR"
"$<TARGET_PROPERTY:${tgt},SOURCE_DIR>"
"INCLUDE_PATH"
"$<JOIN:$<TARGET_PROPERTY:${tgt},INCLUDE_DIRECTORIES>,\n>"
"DEFINES"
"$<JOIN:$<TARGET_PROPERTY:${tgt},COMPILE_DEFINITIONS>,\n>"
"SOURCES"
"$<JOIN:$<TARGET_PROPERTY:${tgt},${source_property}>,\n>"
"HEADERS"
"$<JOIN:$<TARGET_PROPERTY:${tgt},DDR_HEADERS>,\n>"
"PREINCLUDES"
"$<JOIN:$<TARGET_PROPERTY:${tgt},DDR_PREINCLUDES>,\n>"
)
if(target_type MATCHES "EXECUTABLE|SHARED_LIBRARY")
set(MAGIC_TEMPLATE "OUTPUT_FILE\n$<TARGET_FILE:${tgt}>\n${MAGIC_TEMPLATE}")
endif()

file(GENERATE OUTPUT "${DDR_BIN_DIR}/${tgt}.txt" CONTENT "${MAGIC_TEMPLATE}\n")
set_property(TARGET ${DDR_SET_TARGET} APPEND PROPERTY INPUT_TARGETS ${tgt})
endfunction(target_enable_ddr)
9 changes: 8 additions & 1 deletion cmake/modules/OmrUtility.cmake
Expand Up @@ -58,10 +58,17 @@ function(omr_remove_flags variable)
set(${variable} "${result}" PARENT_SCOPE)
endfunction(omr_remove_flags)

# omr_join(<output_variable> <item>...)
# takes given items an joins them with <glue>, places result in output variable
function(omr_join glue output)
string(REGEX REPLACE "(^|[^\\]);" "\\1${glue}" result "${ARGN}")
set(${output} "${result}" PARENT_SCOPE)
endfunction(omr_join)

# omr_stringify(<output_variable> <item>...)
# Convert items to a string of space-separated items.
function(omr_stringify output)
string(REPLACE ";" " " result "${ARGN}")
omr_join(" " result ${ARGN})
set(${output} ${result} PARENT_SCOPE)
endfunction(omr_stringify)

Expand Down
177 changes: 177 additions & 0 deletions cmake/modules/ddr/DDRSetStub.cmake.in
@@ -0,0 +1,177 @@
###############################################################################
# Copyright (c) 2019, 2019 IBM Corp. and others
#
# This program and the accompanying materials are made available under
# the terms of the Eclipse Public License 2.0 which accompanies this
# distribution and is available at http://eclipse.org/legal/epl-2.0
# or the Apache License, Version 2.0 which accompanies this distribution
# and is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# This Source Code may also be made available under the following Secondary
# Licenses when the conditions for such availability set forth in the
# Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
# version 2 with the GNU Classpath Exception [1] and GNU General Public
# License, version 2 with the OpenJDK Assembly Exception [2].
#
# [1] https://www.gnu.org/software/classpath/license.html
# [2] http://openjdk.java.net/legal/assembly-exception.html
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
#############################################################################

cmake_minimum_required(VERSION 3.3 FATAL_ERROR)

project(dummy LANGUAGES NONE)

set(OMR_MODULES_DIR @OMR_MODULES_DIR@)
set(DDR_SUPPORT_DIR "@OMR_MODULES_DIR@/ddr")
set(DDR_INPUTS
$<JOIN:$<TARGET_PROPERTY:@DDR_TARGET_NAME@,INPUT_TARGETS>,
>
)

include("@DDR_TOOLS_EXPORT@")


function(get_relative_path output filename base)
get_filename_component(temp "${filename}" ABSOLUTE BASE_DIR "${base}")
file(RELATIVE_PATH temp "${temp}" "${base}")
set("${output}" "${temp}" PARENT_SCOPE)
endfunction()



function(add_filename_extension output filename prefix)
get_filename_component(extension "${filename}" EXT)
string(LENGTH "${extension}" ext_length)
if(ext_length EQUAL 0)
message(SEND_ERROR "No file extension found")
endif()

string(REGEX REPLACE "${extension}$" "${prefix}${extension}" temp "${filename}")
set("${output}" "${temp}" PARENT_SCOPE)
endfunction(add_filename_extension)

function(process_source_files src_files)
set(options )
set(one_value "SOURCE_DIR" "TARGET" "OUTPUT_STUBS" "OUTPUT_ANNOTATED")
set(multi_value "INCLUDE_DIRS" "DEFINES" "INCLUDE_FILES" "PREINCLUDES")

cmake_parse_arguments("OPT" "${options}" "${one_value}" "${multi_value}" ${ARGV})

set(stub_files)
set(annotated_files)

#build up the command line to the preprocessor
set(BASE_ARGS )
foreach(incdir IN LISTS OPT_INCLUDE_DIRS)
list(APPEND BASE_ARGS "-I${incdir}")
endforeach()

foreach(def IN LISTS OPT_DEFINES)
list(APPEND BASE_ARGS "-D${def}")
endforeach()


foreach(source_file IN LISTS OPT_UNPARSED_ARGUMENTS)

get_filename_component(abs_file "${source_file}" ABSOLUTE BASE_DIR "${OPT_SOURCE_DIR}")
file(RELATIVE_PATH output_file "${OPT_SOURCE_DIR}" "${abs_file}")
string(REGEX REPLACE "\\.\\.(/|$)" "__\\1" output_file "${output_file}")
set(output_file "${OPT_TARGET}/${output_file}")
get_filename_component(output_dir "${output_file}" DIRECTORY)
file(MAKE_DIRECTORY "${output_dir}")

add_filename_extension(stub_file "${output_file}" ".stub")
add_filename_extension(annt_file "${output_file}" ".annt")

list(APPEND stub_files "${stub_file}")
list(APPEND annotated_files "${annt_file}")

add_custom_command(
OUTPUT "${stub_file}"
DEPENDS
${abs_file}
${DDR_SUPPORT_DIR}/cmake_ddr.awk
${DDR_SUPPORT_DIR}/GenerateStub.cmake
COMMAND ${CMAKE_COMMAND} -DAWK_SCRIPT=${DDR_SUPPORT_DIR}/cmake_ddr.awk -Dinput_file=${abs_file} -Doutput_file=${stub_file} -P ${DDR_SUPPORT_DIR}/GenerateStub.cmake
)

#TODO don't hardcode command
set(pp_command "gcc")
list(APPEND pp_command ${BASE_ARGS} "-E" "${stub_file}" )
add_custom_command(
OUTPUT "${annt_file}"
DEPENDS "${stub_file}"
COMMAND ${pp_command} | awk "/^\$/{next} /^DDRFILE_BEGIN /,/^DDRFILE_END /{print \"@\" $0}" > ${annt_file}
VERBATIM
)
endforeach()

if(OPT_OUTPUT_STUBS)
set("${OPT_OUTPUT_STUBS}" "${stub_files}" PARENT_SCOPE)
endif()

if(OPT_OUTPUT_ANNOTATED)
message(STATUS "setting annotated file for ${target} ${annotated_files}")
set("${OPT_OUTPUT_ANNOTATED}" "${annotated_files}" PARENT_SCOPE)
endif()
endfunction(process_source_files)

set(stubannotated_files )
set(target_files )

function(process_target target)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${target}")
file(STRINGS "${CMAKE_SOURCE_DIR}/${target}.txt" target_config)

cmake_parse_arguments("OPT" "" "SOURCE_DIR;OUTPUT_FILE" "INCLUDE_PATH;DEFINES;SOURCES;HEADERS;PREINCLUDES" ${target_config})

if(OPT_OUTPUT_FILE)
set(target_files ${target_files} "${OPT_OUTPUT_FILE}")
endif()


process_source_files(
${OPT_SOURCES}
TARGET "${target}"
SOURCE_DIR "${OPT_SOURCE_DIR}"
OUTPUT_ANNOTATED project_annt_src
INCLUDE_DIRS ${OPT_INCLUDE_PATH}

)
list(APPEND annotated_files ${project_annt_src})

# The only difference between source files and header files, is that header files may need
# other headers pre-included so that preprocessor macros work properly
process_source_files(
${OPT_HEADERS}
TARGET "${target}"
SOURCE_DIR "${OPT_SOURCE_DIR}"
OUTPUT_ANNOTATED project_annt_hdr
#TODO need to add pre-include files
)
list(APPEND annotated_files ${project_annt_hdr})

# Bump changes up to parent scope
set(annotated_files "${annotated_files}" PARENT_SCOPE)

endfunction(process_target)

foreach(target IN LISTS DDR_INPUTS)
process_target("${target}")
endforeach()

add_custom_command(
OUTPUT macroList
DEPENDS ${annotated_files}
COMMAND cat ${annotated_files} > macroList
)

add_custom_command(
OUTPUT blob.dat superset.out
DEPENDS macroList
COMMAND omr_ddrgen ${target_files} -e --macrolist macroList --blob blob.dat --superset superset.out
)

add_custom_target(ddrgen ALL DEPENDS blob.dat)
46 changes: 46 additions & 0 deletions cmake/modules/ddr/GenerateStub.cmake
@@ -0,0 +1,46 @@
###############################################################################
# Copyright (c) 2018, 2019 IBM Corp. and others
#
# This program and the accompanying materials are made available under
# the terms of the Eclipse Public License 2.0 which accompanies this
# distribution and is available at http://eclipse.org/legal/epl-2.0
# or the Apache License, Version 2.0 which accompanies this distribution
# and is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# This Source Code may also be made available under the following Secondary
# Licenses when the conditions for such availability set forth in the
# Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
# version 2 with the GNU Classpath Exception [1] and GNU General Public
# License, version 2 with the OpenJDK Assembly Exception [2].
#
# [1] https://www.gnu.org/software/classpath/license.html
# [2] http://openjdk.java.net/legal/assembly-exception.html
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
#############################################################################

if(NOT input_file)
message(FATAL_ERROR "No input file")
endif()

execute_process(COMMAND grep -lE "@ddr_(namespace|options):" ${input_file} TIMEOUT 2 RESULT_VARIABLE rc)
if(rc)
#input didnt have any ddr directives, so just dump an empty file
file(WRITE ${output_file} "")
else()
file(REMOVE ${output_file})

execute_process(COMMAND awk -f ${AWK_SCRIPT} ${input_file} TIMEOUT 2 OUTPUT_VARIABLE awk_result RESULT_VARIABLE rc )
if(NOT ${rc})
file(WRITE "${output_file}" "/* generated file, DO NOT EDIT*/\n")
if(pre_includes)
foreach(inc_file IN LISTS pre_includes)
file(APPEND ${output_file} "#include \"${inc_file}\"\n ")
endforeach()
endif()
file(APPEND ${output_file} "#include \"${input_file}\"\n")

file(APPEND ${output_file} "${awk_result}")
endif()
endif()
return(${rc})

0 comments on commit b4b1008

Please sign in to comment.