Skip to content

Commit

Permalink
Adds example project that uses Clava CMake package
Browse files Browse the repository at this point in the history
  • Loading branch information
joaobispo committed Apr 4, 2024
1 parent 4265bdf commit 5746605
Show file tree
Hide file tree
Showing 17 changed files with 1,105 additions and 0 deletions.
28 changes: 28 additions & 0 deletions cmake_example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.5)
project(example)

# If Clava CMake plugin is not installed (e.g., sudo clava-update), the path to the plugin
# can be manually specified by setting the variable Clava_DIR
# The Clava CMake plugin can be found here: https://github.com/specs-feup/clava/tree/master/CMake
set(Clava_DIR ./clava)

set(CMAKE_C_STANDARD 99)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O3 -mcmodel=medium")

set(SOURCE_FILES
example.c
)


add_executable(example ${SOURCE_FILES})

#target_link_libraries(example m)

# Clava section

find_package(Clava REQUIRED)

# Call AutoPar
#clava_weave(example SeparateFunctions.mjs)
clava_weave(example ExtractSymbols.mjs)
48 changes: 48 additions & 0 deletions cmake_example/ExtractSymbols.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
laraImport("weaver.Query");

for (const chain of Query.search("file")
.search("function")
.search("vardecl")
.chain()) {
console.log(
chain["file"].name +
" -> " +
chain["function"].name +
" -> " +
chain["vardecl"].name +
":" +
chain["vardecl"].type.code +
"\n"
);
}

console.log("-------------\n");

for (const chain of Query.search("file")
.search("function")
.search("varref")
.chain()) {
console.log(
chain["file"].name +
" -> " +
chain["function"].name +
" -> " +
chain["varref"].name +
":" +
chain["varref"].type.code
);

console.log("Type jp: " + chain["varref"].type.desugarAll.typeFields + "\n");
}

for (const s of Query.search("struct")) {
console.log("Struct fields:\n");

for (const f of s.fields) {
console.log(f.name + " -> " + f.type.code);
}
}

console.log(Query.root().ast);

console.log(Query.root().dump);
11 changes: 11 additions & 0 deletions cmake_example/SeparateFunctions.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
laraImport("weaver.Query");
laraImport("lara.Io");

const path = "C:/Users/JBispo/Work/Repos/Lab/llm-code-patcher/cmake_example/";

for (const func of Query.search("function")) {
const file = func.ancestor("file");

const filename = file.name + "_" + func.name + ".c";
Io.writeFile(Io.getPath(path, filename), func.code);
}
66 changes: 66 additions & 0 deletions cmake_example/clava/ApplyLARA.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#.rst:
# ApplyLARA
# ---------
#
# This module provides integration with Clava C++ weaver for LARA DSL.
# See: https://web.fe.up.pt/~specs/projects/lara/doku.php?id=lara:documentation
#
# This module defines the following varriables
# ::
# LARA_WORKING_DIR
# Holds all artefacts and logs produced by Clava, relative to the current binary dir.
#
# This module uses FindClava CMake module, see its definition.
#
# Usage:
# 1. Add directory containing this module file to the CMAKE_MODULE_PATH.
# 2. Include the module using ``include(ApplyLARA)``
# 3. Call ``apply_lara_aspect`` function with appropriate parameters

# Removed 'find', this file is automatically included when calling find_package(Clava)
# Find Clava
#find_package(Clava REQUIRED)

set(LARA_WORKING_DIR ${CMAKE_CURRENT_BINARY_DIR}/lara)

# Include the working directory, such that generated headers can be included in the rest of the parent project
# TODO: Disabled, check where this is used
#include_directories(${LARA_WORKING_DIR})

# apply_lara_aspect function
# Used to define custom build step for Clava execution.
#
# Parameters:
# LARA_INPUT_FILES - Path to a folder with source code (sub)tree used as input
# LARA_GENERATED_FILES - List of files generated by Clava by applying the selected LARA Aspect
# LARA_SYSTEM_INCLUDES - List of folders included to Clava clang-based frontend as system headers
# LARA_ASPECT - Path to *.lara file containing aspect to be applied to the code
# LARA_CONFIG - Path to *.clava XML file containing configuration of Clava
# LARA_INCLUDE_DIR - Additional *.js files to be included by LARA interpreter
#
function(apply_lara_aspect LARA_INPUT_FILES LARA_GENERATED_FILES LARA_SYSTEM_INCLUDES LARA_ASPECT LARA_CONFIG LARA_INCLUDE_DIR)

string(REGEX REPLACE "[\n\ ]+" ":" CLAVA_INPUT ${LARA_INPUT_FILES})
message(STATUS "Adding LARA build step")
message(STATUS "Generated files: ${LARA_GENERATED_FILES}")

# Append the input directory
include_directories(${LARA_INPUT_FILES})

add_custom_command(
PRE_BUILD
OUTPUT ${LARA_GENERATED_FILES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${Java_JAVA_EXECUTABLE} -Djava.awt.headless=true
-jar ${CLAVA_JAR} ${LARA_ASPECT}
-p ${CLAVA_INPUT}
-is ${LARA_SYSTEM_INCLUDES}
-o ${CMAKE_CURRENT_BINARY_DIR}
-i ${LARA_INCLUDE_DIR}
-c ${LARA_CONFIG}
DEPENDS ${LARA_ASPECT} ${LARA_INPUT_FILES} ${LARA_CONFIG}
VERBATIM
COMMENT "Applying LARA aspects"
USES_TERMINAL)

endfunction(apply_lara_aspect)
114 changes: 114 additions & 0 deletions cmake_example/clava/ClavaConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#.rst:
# FindClava
# ---------
#
# Locate or download the Clava C++ weaver for LARA DSL executable.
# See: https://web.fe.up.pt/~specs/projects/lara/doku.php?id=lara:documentation
#
# This module defines the following variables
# ::
# CLAVA_JAR - Absolute path to clava.jar executable
# CLAVA_CMAKE_HOME - Absolute path to the Clava CMake folder
#
# Module parameters:
#
# LOCAL_CLAVA
# If defined, search for Clava in path specified in this parameter
#
#

# Check for Java JRE
find_package(Java COMPONENTS Runtime REQUIRED)

# Save current Clava folder
set(CLAVA_CMAKE_HOME ${CMAKE_CURRENT_LIST_DIR})
message(STATUS "Clava home: ${CLAVA_CMAKE_HOME}")

# Check if installation file with JAR path exists
if(LOCAL_CLAVA)

elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/clava-installation-jar.txt")
file(READ "${CMAKE_CURRENT_LIST_DIR}/clava-installation-jar.txt" CLAVA_JAR_PATH)
message(STATUS "Found Clava: " ${CLAVA_JAR_PATH})
else()
# Set default URL for clava.jar
set(CLAVA_ZIP_URL "http://specs.fe.up.pt/tools/clava.zip")
set(CLAVA_ZIP_PATH "${CMAKE_CURRENT_BINARY_DIR}/clava.zip")
set(CLAVA_JAR_PATH "${CMAKE_CURRENT_BINARY_DIR}/Clava.jar")
set(DOWNLOADED_CLAVA true)
endif()

# Download clava by default
if(DOWNLOADED_CLAVA)

# Check if Clava has been already downloaded
if(EXISTS ${CLAVA_JAR_PATH})
message(STATUS "Found Clava at: " ${CLAVA_JAR_PATH})
else()
message(STATUS "Downloading Clava")
file(DOWNLOAD
${CLAVA_ZIP_URL}
${CLAVA_ZIP_PATH}
INACTIVITY_TIMEOUT 30
STATUS DOWN_STATUS)
list(GET DOWN_STATUS 0 status_code)
list(GET DOWN_STATUS 1 status_string)

if(${status_code} OR 0)
message(SEND_ERROR "Cannot download Clava: ${status_code} - ${status_string}")
endif()

# Unzip Clava
message(STATUS "Unzipping Clava")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLAVA_ZIP_PATH}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

# Delete zip
file(REMOVE ${CLAVA_ZIP_PATH})

if(EXISTS ${CLAVA_JAR_PATH})
message(STATUS "Downloaded Clava to: ${CLAVA_JAR_PATH}")
else()
message(SEND_ERROR "Could not unzip Clava")
endif()

endif()

elseif(LOCAL_CLAVA)
message(STATUS "Using local Clava at: ${LOCAL_CLAVA}")
set(CLAVA_JAR_PATH ${LOCAL_CLAVA})
endif()

if(NOT EXISTS ${CLAVA_JAR_PATH})
message(SEND_ERROR "File ${CLAVA_JAR_PATH} does not exits")
set(CLAVA_JAR_NOTFOUND)
endif()

# Set the result variables
set(CLAVA_JAR ${CLAVA_JAR_PATH})
set(CLAVA_JAR_FOUND)

# Add current folder to the modules path
#set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_LIST_DIR}")

# Add ApplyLARA, to make function apply_lara_aspect available
#include(${CMAKE_CURRENT_LIST_DIR}/ApplyLARA.cmake RESULT_VARIABLE LARA_RESULT)
include(${CMAKE_CURRENT_LIST_DIR}/ApplyLARA.cmake)

# Make utility functions available
include(${CMAKE_CURRENT_LIST_DIR}/ClavaUtils.cmake)

### Base functions

# Add function 'clava_generate'
include(${CMAKE_CURRENT_LIST_DIR}/clava/ClavaGenerate.cmake)

# Add function 'clava_weave'
include(${CMAKE_CURRENT_LIST_DIR}/clava/ClavaWeave.cmake)

### Utility functions

# Add function 'clava_generate_hdf5'
include(${CMAKE_CURRENT_LIST_DIR}/util/ClavaHdf5.cmake)
# Add function 'clava_weave_autopar'
include(${CMAKE_CURRENT_LIST_DIR}/util/ClavaAutopar.cmake)
Loading

0 comments on commit 5746605

Please sign in to comment.