Skip to content

Commit

Permalink
Fix CMake integration of NMODL generation.
Browse files Browse the repository at this point in the history
The code for the code-generator NMODL is itself generated from Jinja
templates. This requires CMake integration to ensure it happens
automatically.

The following has been changed about the integration:

  * The CMake code needs a list of the generated files. This list is
    stored in a CMake file and included. This file must exist before
    running `code_generator.py` to generate the NMODL code, because the
    command to generate the files needs to know which file it will be
    generating. Therefore, we split the script into two phases: one to
    generate the list of generated files, and another to generate the
    files.

  * The list of generated files depends on the build flags. Therefore,
    this file (`code_generator.cmake`) can't be checked into the Git
    repo. The `code_generator.cmake` is created during the configure
    phase, and now lives in the build directory.

  * CMake code was lifted from `src/language/CMakeLists.txt` to the
    top-level `CMakeLists.txt` to avoid any scoping issues for the
    lists of generated files.

  * Removed pattern of yielding tasks while creating a list tasks in
    favour of returning the list of tasks directly.
  • Loading branch information
1uc committed Nov 6, 2024
1 parent 80d7b8f commit d72500b
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 262 deletions.
71 changes: 68 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,75 @@ if(NOT NMODL_AS_SUBPROJECT AND NMODL_ENABLE_TESTS)
endif()

# =============================================================================
# list of autogenerated files
# =============================================================================
include(${PROJECT_SOURCE_DIR}/src/language/code_generator.cmake)
# Generate NMODL code, e.g. ast & visitor base classes.
# -----------------------------------------------------------------------------
# clang-format is handled by the HPC coding conventions scripts, which also handle generating the
# .clang-format configuration file. It's important that we only try to format code if formatting was
# enabled and NMODL's .clang-format exists, otherwise clang-format will search too far up the
# directory tree and find the wrong configuration file. This can break compilation.
if(NMODL_CLANG_FORMAT OR NMODL_FORMATTING)
set(CODE_GENERATOR_OPTS -v --clang-format=${ClangFormat_EXECUTABLE})
foreach(clang_format_opt ${NMODL_ClangFormat_OPTIONS} --style=file)
list(APPEND CODE_GENERATOR_OPTS --clang-format-opts=${clang_format_opt})
endforeach()
endif()

if(NOT NMODL_ENABLE_PYTHON_BINDINGS)
list(APPEND CODE_GENERATOR_OPTS "--disable-pybind")
endif()

# -----------------------------------------------------------------------------
# Part I: generate the list of generated files
# -----------------------------------------------------------------------------
execute_process(
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/src/language/code_generator.py
${CODE_GENERATOR_OPTS} --generate-cmake --base-dir ${PROJECT_BINARY_DIR}/src
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/language)

# Ensure that the above runs again, if its dependencies update.
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/language/code_generator.py")

set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/src/language/templates/code_generator.cmake)

# The list should be up-to-date now.
include(${PROJECT_BINARY_DIR}/src/code_generator.cmake)

# -----------------------------------------------------------------------------
# Part II: generate AST/Visitor classes from language definition
# -----------------------------------------------------------------------------
set_source_files_properties(${NMODL_GENERATED_SOURCES} PROPERTIES GENERATED TRUE)

# Make the codegen options available as a dependency by storing them in a file.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/language/code_generator_opts.in
${CMAKE_CURRENT_BINARY_DIR}/src/language/code_generator_opts)

add_custom_command(
OUTPUT ${NMODL_GENERATED_SOURCES}
COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/src/language/code_generator.py
${CODE_GENERATOR_OPTS} --base-dir ${PROJECT_BINARY_DIR}/src
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/language
DEPENDS ${CODE_GENERATOR_PY_FILES}
DEPENDS ${CODE_GENERATOR_YAML_FILES}
DEPENDS ${CODE_GENERATOR_JINJA_FILES}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/src/language/code_generator_opts
COMMENT "-- NMODL : GENERATING AST CLASSES WITH PYTHON GENERATOR! --")
unset(CODE_GENERATOR_OPTS)

# -----------------------------------------------------------------------------
# Target to propagate dependencies properly to lexer
# -----------------------------------------------------------------------------
add_custom_target(pyastgen DEPENDS ${PROJECT_BINARY_DIR}/src/ast/ast.cpp)

# =============================================================================
# Deal with the hand-written code
# =============================================================================
add_subdirectory(src)

# =============================================================================
Expand Down
3 changes: 2 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
add_compile_options(${NMODL_EXTRA_CXX_FLAGS})
add_link_options(${NMODL_EXTRA_CXX_FLAGS})

add_subdirectory(codegen)
add_subdirectory(language)

add_subdirectory(codegen)
add_subdirectory(lexer)
add_subdirectory(parser)
add_subdirectory(printer)
Expand Down
35 changes: 0 additions & 35 deletions src/language/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,36 +1 @@
# =============================================================================
# Command to generate AST/Visitor classes from language definition
# =============================================================================
set_source_files_properties(${NMODL_GENERATED_SOURCES} PROPERTIES GENERATED TRUE)

# clang-format is handled by the HPC coding conventions scripts, which also handle generating the
# .clang-format configuration file. It's important that we only try to format code if formatting was
# enabled and NMODL's .clang-format exists, otherwise clang-format will search too far up the
# directory tree and find the wrong configuration file. This can break compilation.
if(NMODL_CLANG_FORMAT OR NMODL_FORMATTING)
set(CODE_GENERATOR_OPTS -v --clang-format=${ClangFormat_EXECUTABLE})
foreach(clang_format_opt ${NMODL_ClangFormat_OPTIONS} --style=file)
list(APPEND CODE_GENERATOR_OPTS --clang-format-opts=${clang_format_opt})
endforeach()
endif()

if(NOT NMODL_ENABLE_PYTHON_BINDINGS)
list(APPEND CODE_GENERATOR_OPTS "--disable-pybind")
endif()

add_custom_command(
OUTPUT ${NMODL_GENERATED_SOURCES}
COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/code_generator.py
${CODE_GENERATOR_OPTS} --base-dir ${PROJECT_BINARY_DIR}/src
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${CODE_GENERATOR_PY_FILES}
DEPENDS ${CODE_GENERATOR_YAML_FILES}
DEPENDS ${CODE_GENERATOR_JINJA_FILES}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/templates/code_generator.cmake
COMMENT "-- NMODL : GENERATING AST CLASSES WITH PYTHON GENERATOR! --")
unset(CODE_GENERATOR_OPTS)

# =============================================================================
# Target to propagate dependencies properly to lexer
# =============================================================================
add_custom_target(pyastgen DEPENDS ${PROJECT_BINARY_DIR}/src/ast/ast.cpp)
212 changes: 0 additions & 212 deletions src/language/code_generator.cmake

This file was deleted.

Loading

0 comments on commit d72500b

Please sign in to comment.