diff --git a/CMakeLists.txt b/CMakeLists.txt index 9945bde..544f287 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,13 @@ cmake_minimum_required(VERSION 3.22 FATAL_ERROR) +# Nix dependencies +file(GLOB NIX_STORE_LIB LIST_DIRECTORIES true "/nix/store/*/lib/cmake/*") +message(DEBUG NIX_STORE_LIB=${NIX_STORE_LIB}) +list(APPEND CMAKE_PREFIX_PATH ${NIX_STORE_LIB}) +file(GLOB NIX_STORE_BIN LIST_DIRECTORIES true "/nix/store/*/bin/") +message(DEBUG NIX_STORE_BIN=${NIX_STORE_BIN}) +list(APPEND CMAKE_PROGRAM_PATH ${NIX_STORE_BIN}) + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_CXX_STANDARD 17) @@ -17,6 +25,8 @@ project( include(FetchContent) cmake_policy(SET CMP0135 NEW) +include(commands) + # _.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-. # Library @@ -34,24 +44,20 @@ else () endif () ## Cxxopts -FetchContent_Declare( - cxxopts - GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git - GIT_TAG 3bf268481da8208d171d8908e6491459de3651d7 #v3.2.0 -) -FetchContent_MakeAvailable(cxxopts) -message(DEBUG cxxopts="${cxxopts_SOURCE_DIR}/include") +find_package(cxxopts 3.2.0 REQUIRED CONFIG) +message(STATUS "Found cxxopts ${cxxopts_PACKAGE_VERSION}") +message(STATUS "Located in: ${cxxopts_DIR}") +get_target_property(cxxopts_INCLUDE_DIR cxxopts::cxxopts INTERFACE_INCLUDE_DIRECTORIES) +message(STATUS "Included from: ${cxxopts_INCLUDE_DIR}") ## Antlr4 -add_definitions(-DANTLR4CPP_STATIC) -set(ANTLR4_WITH_STATIC_CRT OFF) -set(ANTLR4_TAG 4.13.2) -set(ANTLR4_ZIP_REPOSITORY https://github.com/antlr/antlr4/archive/refs/tags/${ANTLR4_TAG}.zip) -set(ANTLR_EXECUTABLE ${PROJECT_SOURCE_DIR}/tools/antlr-${ANTLR4_TAG}-complete.jar) +find_package(antlr4-runtime 4.13.0 REQUIRED CONFIG) +message(STATUS "Found antlr ${ANTLR_VERSION}") +message(STATUS "Located in: ${antlr4-runtime_DIR}") +message(STATUS "Included from: ${ANTLR4_INCLUDE_DIR}") -include(ExternalAntlr4Cpp) -include_directories(${ANTLR4_INCLUDE_DIRS}) -find_package(ANTLR REQUIRED) +find_program(ANTLR_EXECUTABLE antlr REQUIRED) +message(STATUS "Found antlr: ${ANTLR_EXECUTABLE}") antlr_target(Lexer ${PROJECT_SOURCE_DIR}/src/grammar/FilLexer.g4 LEXER PACKAGE filc) @@ -61,10 +67,9 @@ antlr_target(Parser ${PROJECT_SOURCE_DIR}/src/grammar/FilParser.g4 PARSER COMPILE_FLAGS -lib ${ANTLR_Lexer_OUTPUT_DIR}) ## LLVM -find_package(LLVM REQUIRED CONFIG) - +find_package(LLVM 18.1.8 REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") -message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") +message(STATUS "Located in: ${LLVM_DIR}") include_directories(${LLVM_INCLUDE_DIRS}) separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS}) @@ -77,7 +82,7 @@ foreach(target ${LLVM_TARGETS_TO_BUILD}) endforeach() ## filc lib -file(GLOB_RECURSE SRC_FILES +file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS filc_lib "${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/src/**/*.cpp" ) @@ -88,8 +93,8 @@ target_link_libraries(filc_lib PRIVATE additional_config cxxopts::cxxopts antlr4 target_include_directories(filc_lib PUBLIC "${PROJECT_SOURCE_DIR}/include" - "${cxxopts_SOURCE_DIR}/include" - ${ANTLR4_INCLUDE_DIRS} + ${cxxopts_INCLUDE_DIR} + ${ANTLR4_INCLUDE_DIR} ${ANTLR_Lexer_OUTPUT_DIR} ${ANTLR_Parser_OUTPUT_DIR} ${LLVM_INCLUDE_DIRS}) diff --git a/cmake/ExternalAntlr4Cpp.cmake b/cmake/ExternalAntlr4Cpp.cmake deleted file mode 100644 index b1c94e6..0000000 --- a/cmake/ExternalAntlr4Cpp.cmake +++ /dev/null @@ -1,177 +0,0 @@ -cmake_minimum_required(VERSION 3.7) - -if(POLICY CMP0114) - cmake_policy(SET CMP0114 NEW) -endif() - -include(ExternalProject) - -set(ANTLR4_ROOT ${CMAKE_CURRENT_BINARY_DIR}/antlr4_runtime/src/antlr4_runtime) -set(ANTLR4_INCLUDE_DIRS ${ANTLR4_ROOT}/runtime/Cpp/runtime/src) -set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git) -if(NOT DEFINED ANTLR4_TAG) - # Set to branch name to keep library updated at the cost of needing to rebuild after 'clean' - # Set to commit hash to keep the build stable and does not need to rebuild after 'clean' - set(ANTLR4_TAG master) -endif() - -# Ensure that the include dir already exists at configure time (to avoid cmake erroring -# on non-existent include dirs) -file(MAKE_DIRECTORY "${ANTLR4_INCLUDE_DIRS}") - -if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") - set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(Configuration)) -elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*") - set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime/$(CONFIGURATION)) -else() - set(ANTLR4_OUTPUT_DIR ${ANTLR4_ROOT}/runtime/Cpp/runtime) -endif() - -if(MSVC) - set(ANTLR4_STATIC_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/antlr4-runtime-static.lib) - set(ANTLR4_SHARED_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.lib) - set(ANTLR4_RUNTIME_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/antlr4-runtime.dll) -else() - set(ANTLR4_STATIC_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.a) - if(MINGW) - set(ANTLR4_SHARED_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a) - set(ANTLR4_RUNTIME_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll) - elseif(CYGWIN) - set(ANTLR4_SHARED_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dll.a) - set(ANTLR4_RUNTIME_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/cygantlr4-runtime-4.13.2.dll) - elseif(APPLE) - set(ANTLR4_RUNTIME_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.dylib) - else() - set(ANTLR4_RUNTIME_LIBRARIES - ${ANTLR4_OUTPUT_DIR}/libantlr4-runtime.so) - endif() -endif() - -if(${CMAKE_GENERATOR} MATCHES ".* Makefiles") - # This avoids - # 'warning: jobserver unavailable: using -j1. Add '+' to parent make rule.' - set(ANTLR4_BUILD_COMMAND $(MAKE)) -elseif(${CMAKE_GENERATOR} MATCHES "Visual Studio.*") - set(ANTLR4_BUILD_COMMAND - ${CMAKE_COMMAND} - --build . - --config $(Configuration) - --target) -elseif(${CMAKE_GENERATOR} MATCHES "Xcode.*") - set(ANTLR4_BUILD_COMMAND - ${CMAKE_COMMAND} - --build . - --config $(CONFIGURATION) - --target) -else() - set(ANTLR4_BUILD_COMMAND - ${CMAKE_COMMAND} - --build . - --target) -endif() - -if(NOT DEFINED ANTLR4_WITH_STATIC_CRT) - set(ANTLR4_WITH_STATIC_CRT ON) -endif() - -if(ANTLR4_ZIP_REPOSITORY) - ExternalProject_Add( - antlr4_runtime - PREFIX antlr4_runtime - URL ${ANTLR4_ZIP_REPOSITORY} - DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} - BUILD_COMMAND "" - BUILD_IN_SOURCE 1 - SOURCE_DIR ${ANTLR4_ROOT} - SOURCE_SUBDIR runtime/Cpp - CMAKE_CACHE_ARGS - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT} - -DDISABLE_WARNINGS:BOOL=ON - # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard - # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project - INSTALL_COMMAND "" - EXCLUDE_FROM_ALL 1) -else() - ExternalProject_Add( - antlr4_runtime - PREFIX antlr4_runtime - GIT_REPOSITORY ${ANTLR4_GIT_REPOSITORY} - GIT_TAG ${ANTLR4_TAG} - DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} - BUILD_COMMAND "" - BUILD_IN_SOURCE 1 - SOURCE_DIR ${ANTLR4_ROOT} - SOURCE_SUBDIR runtime/Cpp - CMAKE_CACHE_ARGS - -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} - -DWITH_STATIC_CRT:BOOL=${ANTLR4_WITH_STATIC_CRT} - -DDISABLE_WARNINGS:BOOL=ON - # -DCMAKE_CXX_STANDARD:STRING=17 # if desired, compile the runtime with a different C++ standard - # -DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD} # alternatively, compile the runtime with the same C++ standard as the outer project - INSTALL_COMMAND "" - EXCLUDE_FROM_ALL 1) -endif() - -# Separate build step as rarely people want both -set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT}) -if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0") - # CMake 3.14 builds in above's SOURCE_SUBDIR when BUILD_IN_SOURCE is true - set(ANTLR4_BUILD_DIR ${ANTLR4_ROOT}/runtime/Cpp) -endif() - -ExternalProject_Add_Step( - antlr4_runtime - build_static - COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_static - # Depend on target instead of step (a custom command) - # to avoid running dependent steps concurrently - DEPENDS antlr4_runtime - BYPRODUCTS ${ANTLR4_STATIC_LIBRARIES} - EXCLUDE_FROM_MAIN 1 - WORKING_DIRECTORY ${ANTLR4_BUILD_DIR}) -ExternalProject_Add_StepTargets(antlr4_runtime build_static) - -add_library(antlr4_static STATIC IMPORTED) -add_dependencies(antlr4_static antlr4_runtime-build_static) -set_target_properties(antlr4_static PROPERTIES - IMPORTED_LOCATION ${ANTLR4_STATIC_LIBRARIES}) -target_include_directories(antlr4_static - INTERFACE - ${ANTLR4_INCLUDE_DIRS} -) - -ExternalProject_Add_Step( - antlr4_runtime - build_shared - COMMAND ${ANTLR4_BUILD_COMMAND} antlr4_shared - # Depend on target instead of step (a custom command) - # to avoid running dependent steps concurrently - DEPENDS antlr4_runtime - BYPRODUCTS ${ANTLR4_SHARED_LIBRARIES} ${ANTLR4_RUNTIME_LIBRARIES} - EXCLUDE_FROM_MAIN 1 - WORKING_DIRECTORY ${ANTLR4_BUILD_DIR}) -ExternalProject_Add_StepTargets(antlr4_runtime build_shared) - -add_library(antlr4_shared SHARED IMPORTED) -add_dependencies(antlr4_shared antlr4_runtime-build_shared) -set_target_properties(antlr4_shared PROPERTIES - IMPORTED_LOCATION ${ANTLR4_RUNTIME_LIBRARIES}) -target_include_directories(antlr4_shared - INTERFACE - ${ANTLR4_INCLUDE_DIRS} -) - -if(ANTLR4_SHARED_LIBRARIES) - set_target_properties(antlr4_shared PROPERTIES - IMPORTED_IMPLIB ${ANTLR4_SHARED_LIBRARIES}) -endif() diff --git a/cmake/FindANTLR.cmake b/cmake/FindANTLR.cmake deleted file mode 100644 index 5267d53..0000000 --- a/cmake/FindANTLR.cmake +++ /dev/null @@ -1,124 +0,0 @@ -find_package(Java QUIET COMPONENTS Runtime) - -if(NOT ANTLR_EXECUTABLE) - find_program(ANTLR_EXECUTABLE - NAMES antlr.jar antlr4.jar antlr-4.jar antlr-4.13.2-complete.jar) -endif() - -if(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE) - execute_process( - COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE} - OUTPUT_VARIABLE ANTLR_COMMAND_OUTPUT - ERROR_VARIABLE ANTLR_COMMAND_ERROR - RESULT_VARIABLE ANTLR_COMMAND_RESULT - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if(ANTLR_COMMAND_RESULT EQUAL 0) - string(REGEX MATCH "Version [0-9]+(\\.[0-9]+)*" ANTLR_VERSION ${ANTLR_COMMAND_OUTPUT}) - string(REPLACE "Version " "" ANTLR_VERSION ${ANTLR_VERSION}) - else() - message( - SEND_ERROR - "Command '${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE}' " - "failed with the output '${ANTLR_COMMAND_ERROR}'") - endif() - - macro(ANTLR_TARGET Name InputFile) - set(ANTLR_OPTIONS LEXER PARSER LISTENER VISITOR) - set(ANTLR_ONE_VALUE_ARGS PACKAGE OUTPUT_DIRECTORY DEPENDS_ANTLR) - set(ANTLR_MULTI_VALUE_ARGS COMPILE_FLAGS DEPENDS) - cmake_parse_arguments(ANTLR_TARGET - "${ANTLR_OPTIONS}" - "${ANTLR_ONE_VALUE_ARGS}" - "${ANTLR_MULTI_VALUE_ARGS}" - ${ARGN}) - - set(ANTLR_${Name}_INPUT ${InputFile}) - - get_filename_component(ANTLR_INPUT ${InputFile} NAME_WE) - - if(ANTLR_TARGET_OUTPUT_DIRECTORY) - set(ANTLR_${Name}_OUTPUT_DIR ${ANTLR_TARGET_OUTPUT_DIRECTORY}) - else() - set(ANTLR_${Name}_OUTPUT_DIR - ${CMAKE_CURRENT_BINARY_DIR}/antlr4cpp_generated_src/${ANTLR_INPUT}) - endif() - - unset(ANTLR_${Name}_CXX_OUTPUTS) - - if((ANTLR_TARGET_LEXER AND NOT ANTLR_TARGET_PARSER) OR - (ANTLR_TARGET_PARSER AND NOT ANTLR_TARGET_LEXER)) - list(APPEND ANTLR_${Name}_CXX_OUTPUTS - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.h - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.cpp) - set(ANTLR_${Name}_OUTPUTS - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.interp - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.tokens) - else() - list(APPEND ANTLR_${Name}_CXX_OUTPUTS - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.h - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.cpp - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.h - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.cpp) - list(APPEND ANTLR_${Name}_OUTPUTS - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.interp - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.tokens) - endif() - - if(ANTLR_TARGET_LISTENER) - list(APPEND ANTLR_${Name}_CXX_OUTPUTS - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.h - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.cpp - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.h - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.cpp) - list(APPEND ANTLR_TARGET_COMPILE_FLAGS -listener) - endif() - - if(ANTLR_TARGET_VISITOR) - list(APPEND ANTLR_${Name}_CXX_OUTPUTS - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.h - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.cpp - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.h - ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.cpp) - list(APPEND ANTLR_TARGET_COMPILE_FLAGS -visitor) - endif() - - if(ANTLR_TARGET_PACKAGE) - list(APPEND ANTLR_TARGET_COMPILE_FLAGS -package ${ANTLR_TARGET_PACKAGE}) - endif() - - list(APPEND ANTLR_${Name}_OUTPUTS ${ANTLR_${Name}_CXX_OUTPUTS}) - - if(ANTLR_TARGET_DEPENDS_ANTLR) - if(ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT) - list(APPEND ANTLR_TARGET_DEPENDS - ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT}) - list(APPEND ANTLR_TARGET_DEPENDS - ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_OUTPUTS}) - else() - message(SEND_ERROR - "ANTLR target '${ANTLR_TARGET_DEPENDS_ANTLR}' not found") - endif() - endif() - - add_custom_command( - OUTPUT ${ANTLR_${Name}_OUTPUTS} - COMMAND ${Java_JAVA_EXECUTABLE} -jar ${ANTLR_EXECUTABLE} - ${InputFile} - -o ${ANTLR_${Name}_OUTPUT_DIR} - -no-listener - -Dlanguage=Cpp - ${ANTLR_TARGET_COMPILE_FLAGS} - DEPENDS ${InputFile} - ${ANTLR_TARGET_DEPENDS} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMENT "Building ${Name} with ANTLR ${ANTLR_VERSION}") - endmacro(ANTLR_TARGET) - -endif(ANTLR_EXECUTABLE AND Java_JAVA_EXECUTABLE) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - ANTLR - REQUIRED_VARS ANTLR_EXECUTABLE Java_JAVA_EXECUTABLE - VERSION_VAR ANTLR_VERSION) diff --git a/cmake/antlr4-generator.cmake.in b/cmake/antlr4-generator.cmake.in deleted file mode 100644 index 6399651..0000000 --- a/cmake/antlr4-generator.cmake.in +++ /dev/null @@ -1,181 +0,0 @@ -set(ANTLR_VERSION @ANTLR_VERSION@) - -@PACKAGE_INIT@ - -if (NOT ANTLR4_CPP_GENERATED_SRC_DIR) - set(ANTLR4_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4_generated_src) -endif() - -FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED) - -# -# The ANTLR generator will output the following files given the input file f.g4 -# -# Input -> f.g4 -# Output -> f.h -# -> f.cpp -# -# the following files will only be produced if there is a parser contained -# Flag -visitor active -# Output -> BaseVisitor.h -# -> BaseVisitor.cpp -# -> Visitor.h -# -> Visitor.cpp -# -# Flag -listener active -# Output -> BaseListener.h -# -> BaseListener.cpp -# -> Listener.h -# -> Listener.cpp -# -# See documentation in markup -# -function(antlr4_generate - Antlr4_ProjectTarget - Antlr4_InputFile - Antlr4_GeneratorType - ) - - set( Antlr4_GeneratedSrcDir ${ANTLR4_GENERATED_SRC_DIR}/${Antlr4_ProjectTarget} ) - - get_filename_component(Antlr4_InputFileBaseName ${Antlr4_InputFile} NAME_WE ) - - list( APPEND Antlr4_GeneratorStatusMessage "Common Include-, Source- and Tokenfiles" ) - - if ( ${Antlr4_GeneratorType} STREQUAL "LEXER") - set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}") - set(Antlr4_ParserBaseName "") - else() - if ( ${Antlr4_GeneratorType} STREQUAL "PARSER") - set(Antlr4_LexerBaseName "") - set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}") - else() - if ( ${Antlr4_GeneratorType} STREQUAL "BOTH") - set(Antlr4_LexerBaseName "${Antlr4_InputFileBaseName}Lexer") - set(Antlr4_ParserBaseName "${Antlr4_InputFileBaseName}Parser") - else() - message(FATAL_ERROR "The third parameter must be LEXER, PARSER or BOTH") - endif () - endif () - endif () - - # Prepare list of generated targets - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.interp" ) - list( APPEND DependentTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.tokens" ) - - if ( NOT ${Antlr4_LexerBaseName} STREQUAL "" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.h" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_LexerBaseName}.cpp" ) - endif () - - if ( NOT ${Antlr4_ParserBaseName} STREQUAL "" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.h" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_ParserBaseName}.cpp" ) - endif () - - # process optional arguments ... - - if ( ( ARGC GREATER_EQUAL 4 ) AND ARGV3 ) - set(Antlr4_BuildListenerOption "-listener") - - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.h" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseListener.cpp" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.h" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Listener.cpp" ) - - list( APPEND Antlr4_GeneratorStatusMessage ", Listener Include- and Sourcefiles" ) - else() - set(Antlr4_BuildListenerOption "-no-listener") - endif () - - if ( ( ARGC GREATER_EQUAL 5 ) AND ARGV4 ) - set(Antlr4_BuildVisitorOption "-visitor") - - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.h" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}BaseVisitor.cpp" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.h" ) - list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}Visitor.cpp" ) - - list( APPEND Antlr4_GeneratorStatusMessage ", Visitor Include- and Sourcefiles" ) - else() - set(Antlr4_BuildVisitorOption "-no-visitor") - endif () - - if ( (ARGC GREATER_EQUAL 6 ) AND (NOT ${ARGV5} STREQUAL "") ) - set(Antlr4_NamespaceOption "-package;${ARGV5}") - - list( APPEND Antlr4_GeneratorStatusMessage " in Namespace ${ARGV5}" ) - else() - set(Antlr4_NamespaceOption "") - endif () - - if ( (ARGC GREATER_EQUAL 7 ) AND (NOT ${ARGV6} STREQUAL "") ) - set(Antlr4_AdditionalDependencies ${ARGV6}) - else() - set(Antlr4_AdditionalDependencies "") - endif () - - if ( (ARGC GREATER_EQUAL 8 ) AND (NOT ${ARGV7} STREQUAL "") ) - set(Antlr4_LibOption "-lib;${ARGV7}") - - list( APPEND Antlr4_GeneratorStatusMessage " using Library ${ARGV7}" ) - else() - set(Antlr4_LibOption "") - endif () - - if(NOT Java_FOUND) - message(FATAL_ERROR "Java is required to process grammar or lexer files! - Use 'FIND_PACKAGE(Java COMPONENTS Runtime REQUIRED)'") - endif() - - if(NOT EXISTS "${ANTLR4_JAR_LOCATION}") - message(FATAL_ERROR "Unable to find antlr tool. ANTLR4_JAR_LOCATION:${ANTLR4_JAR_LOCATION}") - endif() - - # The call to generate the files - add_custom_command( - OUTPUT ${Antlr4_GeneratedTargets} - # Remove target directory - COMMAND - ${CMAKE_COMMAND} -E remove_directory ${Antlr4_GeneratedSrcDir} - # Create target directory - COMMAND - ${CMAKE_COMMAND} -E make_directory ${Antlr4_GeneratedSrcDir} - COMMAND - # Generate files - "${Java_JAVA_EXECUTABLE}" -jar "${ANTLR4_JAR_LOCATION}" -Werror -Dlanguage=Cpp ${Antlr4_BuildListenerOption} ${Antlr4_BuildVisitorOption} ${Antlr4_LibOption} ${ANTLR4_GENERATED_OPTIONS} -o "${Antlr4_GeneratedSrcDir}" ${Antlr4_NamespaceOption} "${Antlr4_InputFile}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - MAIN_DEPENDENCY "${Antlr4_InputFile}" - DEPENDS ${Antlr4_AdditionalDependencies} - ) - - # set output variables in parent scope - set( ANTLR4_INCLUDE_DIR_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE) - set( ANTLR4_SRC_FILES_${Antlr4_ProjectTarget} ${Antlr4_GeneratedTargets} PARENT_SCOPE) - set( ANTLR4_TOKEN_FILES_${Antlr4_ProjectTarget} ${DependentTargets} PARENT_SCOPE) - set( ANTLR4_TOKEN_DIRECTORY_${Antlr4_ProjectTarget} ${Antlr4_GeneratedSrcDir} PARENT_SCOPE) - - # export generated cpp files into list - foreach(generated_file ${Antlr4_GeneratedTargets}) - - if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set_source_files_properties( - ${generated_file} - PROPERTIES - COMPILE_FLAGS -Wno-overloaded-virtual - ) - endif () - - if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set_source_files_properties( - ${generated_file} - PROPERTIES - COMPILE_FLAGS -wd4251 - ) - endif () - - endforeach(generated_file) - -message(STATUS "Antlr4 ${Antlr4_ProjectTarget} - Building " ${Antlr4_GeneratorStatusMessage} ) - -endfunction() diff --git a/cmake/antlr4-runtime.cmake.in b/cmake/antlr4-runtime.cmake.in deleted file mode 100644 index 697b36c..0000000 --- a/cmake/antlr4-runtime.cmake.in +++ /dev/null @@ -1,13 +0,0 @@ -set(ANTLR_VERSION @ANTLR_VERSION@) - -@PACKAGE_INIT@ - -set_and_check(ANTLR4_INCLUDE_DIR "@PACKAGE_ANTLR4_INCLUDE_DIR@") -set_and_check(ANTLR4_LIB_DIR "@PACKAGE_ANTLR4_LIB_DIR@") - -include(CMakeFindDependencyMacro) -find_dependency(Threads) - -include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake) - -check_required_components(antlr) diff --git a/cmake/commands.cmake b/cmake/commands.cmake new file mode 100644 index 0000000..6e0a7ae --- /dev/null +++ b/cmake/commands.cmake @@ -0,0 +1,115 @@ +# MIT License +# +# Copyright (c) 2024 Kevin Traini +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +include_guard() + +# From https://github.com/antlr/antlr4/blob/67228355c5bfd1ed5ebb89e726992ec43dda7b53/runtime/Cpp/cmake/FindANTLR.cmake#L26 +macro(ANTLR_TARGET Name InputFile) + set(ANTLR_OPTIONS LEXER PARSER LISTENER VISITOR) + set(ANTLR_ONE_VALUE_ARGS PACKAGE OUTPUT_DIRECTORY DEPENDS_ANTLR) + set(ANTLR_MULTI_VALUE_ARGS COMPILE_FLAGS DEPENDS) + cmake_parse_arguments(ANTLR_TARGET + "${ANTLR_OPTIONS}" + "${ANTLR_ONE_VALUE_ARGS}" + "${ANTLR_MULTI_VALUE_ARGS}" + ${ARGN}) + + set(ANTLR_${Name}_INPUT ${InputFile}) + + get_filename_component(ANTLR_INPUT ${InputFile} NAME_WE) + + if (ANTLR_TARGET_OUTPUT_DIRECTORY) + set(ANTLR_${Name}_OUTPUT_DIR ${ANTLR_TARGET_OUTPUT_DIRECTORY}) + else () + set(ANTLR_${Name}_OUTPUT_DIR + ${CMAKE_CURRENT_BINARY_DIR}/antlr4cpp_generated_src/${ANTLR_INPUT}) + endif () + + unset(ANTLR_${Name}_CXX_OUTPUTS) + + if ((ANTLR_TARGET_LEXER AND NOT ANTLR_TARGET_PARSER) OR + (ANTLR_TARGET_PARSER AND NOT ANTLR_TARGET_LEXER)) + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.cpp) + set(ANTLR_${Name}_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.interp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}.tokens) + else () + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.cpp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Parser.cpp) + list(APPEND ANTLR_${Name}_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.interp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Lexer.tokens) + endif () + + if (ANTLR_TARGET_LISTENER) + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseListener.cpp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Listener.cpp) + list(APPEND ANTLR_TARGET_COMPILE_FLAGS -listener) + endif () + + if (ANTLR_TARGET_VISITOR) + list(APPEND ANTLR_${Name}_CXX_OUTPUTS + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}BaseVisitor.cpp + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.h + ${ANTLR_${Name}_OUTPUT_DIR}/${ANTLR_INPUT}Visitor.cpp) + list(APPEND ANTLR_TARGET_COMPILE_FLAGS -visitor) + endif () + + if (ANTLR_TARGET_PACKAGE) + list(APPEND ANTLR_TARGET_COMPILE_FLAGS -package ${ANTLR_TARGET_PACKAGE}) + endif () + + list(APPEND ANTLR_${Name}_OUTPUTS ${ANTLR_${Name}_CXX_OUTPUTS}) + + if (ANTLR_TARGET_DEPENDS_ANTLR) + if (ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT) + list(APPEND ANTLR_TARGET_DEPENDS + ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_INPUT}) + list(APPEND ANTLR_TARGET_DEPENDS + ${ANTLR_${ANTLR_TARGET_DEPENDS_ANTLR}_OUTPUTS}) + else () + message(SEND_ERROR + "ANTLR target '${ANTLR_TARGET_DEPENDS_ANTLR}' not found") + endif () + endif () + + add_custom_command( + OUTPUT ${ANTLR_${Name}_OUTPUTS} + COMMAND ${ANTLR_EXECUTABLE} + ${InputFile} + -o ${ANTLR_${Name}_OUTPUT_DIR} + -no-listener + -Dlanguage=Cpp + ${ANTLR_TARGET_COMPILE_FLAGS} + DEPENDS ${InputFile} + ${ANTLR_TARGET_DEPENDS} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Building ${Name} with ANTLR ${ANTLR_VERSION} in ${ANTLR_${Name}_OUTPUT_DIR}") +endmacro(ANTLR_TARGET) diff --git a/include/filc/grammar/Visitor.h b/include/filc/grammar/Visitor.h index a6d6d8b..d64d86c 100644 --- a/include/filc/grammar/Visitor.h +++ b/include/filc/grammar/Visitor.h @@ -26,7 +26,7 @@ #include "filc/grammar/ast.h" -#include "llvm/IR/Value.h" +#include namespace filc { template class Visitor { diff --git a/shell.nix b/shell.nix index 0db8c7f..b6b6413 100644 --- a/shell.nix +++ b/shell.nix @@ -1,11 +1,10 @@ -let - nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/3e889463e499537c602e3ea83da6e33f9dc974da.tar.gz"; - pkgs = import nixpkgs { config = {}; overlays = []; }; -in +{ pkgs ? (import ./tools/nix/pin-nixpkgs.nix) {} }: let currentDir = builtins.toString ./.; pnpm = pkgs.callPackage ./tools/nix/pnpm.nix { nodejs = pkgs.nodejs_20; }; + cxxopts = pkgs.callPackage ./tools/nix/cxxopts.nix { }; + antlr4 = pkgs.callPackage ./tools/nix/antlr4.nix { }; in pkgs.mkShell { @@ -23,9 +22,13 @@ pkgs.mkShell { pkgs.jre_minimal pkgs.nodejs_20 pnpm + pkgs.httpie pkgs.llvmPackages_18.libllvm pkgs.libffi pkgs.libxml2 + cxxopts + antlr4.antlr + antlr4.runtime.cpp ]; shellHook = '' diff --git a/tools/antlr-4.13.2-complete.jar b/tools/antlr-4.13.2-complete.jar deleted file mode 100644 index 75bfcc3..0000000 Binary files a/tools/antlr-4.13.2-complete.jar and /dev/null differ diff --git a/tools/bin/build_release b/tools/bin/build_release index 9ec8ed4..21c5f79 100755 --- a/tools/bin/build_release +++ b/tools/bin/build_release @@ -4,7 +4,6 @@ set -euo pipefail WORKDIR="$ROOT_DIR/out/release" -rm -rf "$WORKDIR" cmake -B "$WORKDIR" -DCMAKE_BUILD_TYPE=Release -G Ninja cmake --build "$WORKDIR" cp "$(cat "$WORKDIR/filc.path")" "$ROOT_DIR" diff --git a/tools/bin/download_antlr b/tools/bin/download_antlr deleted file mode 100755 index af5aa9c..0000000 --- a/tools/bin/download_antlr +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -if (($# != 1)); then - echo -e "\033[31mUsage : $(basename "$0") \033[0m" - exit 1 -fi -version=$(echo "$1" | sed 's/[^A-Za-z0-9._-]//g') - -# Check that command http is installed -if ! type "http" >/dev/null; then - echo -e "\033[31mhttp command not found. Please install it.\033[0m" - exit 1 -fi - -echo -e "\033[34mRemove previous jar\033[0m" -rm -f "$ROOT_DIR/tools/antlr-*-complete.jar" -echo -e " \033[32mDone\033[0m" - -echo -e "\033[34mDownload jar \033[1m$version\033[0m" -echo -e " https://www.antlr.org/download/antlr-$version-complete.jar" -http --download --output="$ROOT_DIR/tools/antlr-$version-complete.jar" "https://www.antlr.org/download/antlr-$version-complete.jar" -q -echo -e " \033[32mDone\033[0m" diff --git a/tools/nix/antlr4.nix b/tools/nix/antlr4.nix new file mode 100644 index 0000000..24f5bb6 --- /dev/null +++ b/tools/nix/antlr4.nix @@ -0,0 +1,78 @@ +{ stdenv +, fetchurl +, fetchFromGitHub +, jre +, cmake, ninja, pkg-config +}: + +# From https://github.com/NixOS/nixpkgs/blob/nixos-24.11/pkgs/development/tools/parsing/antlr/4.nix +let + mkAntlr = { + version, jarHash, srcHash + }: rec { + antlr = stdenv.mkDerivation { + pname = "antlr"; + inherit version; + + src = fetchurl { + url = "https://www.antlr.org/download/antlr-${version}-complete.jar"; + hash = jarHash; + }; + + dontUnpack = true; + + installPhase = '' + mkdir -p "$out"/{share/java,bin} + ln -s "$src" "$out/share/java/antlr-${version}-complete.jar" + + echo "#! ${stdenv.shell}" >> "$out/bin/antlr" + echo "'${jre}/bin/java' -cp '$out/share/java/antlr-${version}-complete.jar:$CLASSPATH' -Xmx500M org.antlr.v4.Tool \"\$@\"" >> "$out/bin/antlr" + + echo "#! ${stdenv.shell}" >> "$out/bin/antlr-parse" + echo "'${jre}/bin/java' -cp '$out/share/java/antlr-${version}-complete.jar:$CLASSPATH' -Xmx500M org.antlr.v4.gui.Interpreter \"\$@\"" >> "$out/bin/antlr-parse" + + echo "#! ${stdenv.shell}" >> "$out/bin/grun" + echo "'${jre}/bin/java' -cp '$out/share/java/antlr-${version}-complete.jar:$CLASSPATH' org.antlr.v4.gui.TestRig \"\$@\"" >> "$out/bin/grun" + + chmod a+x "$out/bin/antlr" "$out/bin/antlr-parse" "$out/bin/grun" + ln -s "$out/bin/antlr"{,4} + ln -s "$out/bin/antlr"{,4}-parse + ''; + + inherit jre; + + passthru = { + inherit runtime; + jarLocation = antlr.src; + }; + }; + + runtime.cpp = stdenv.mkDerivation { + pname = "antlr-runtime-cpp"; + inherit version; + + src = fetchFromGitHub { + owner = "antlr"; + repo = "antlr4"; + tag = version; + hash = srcHash; + }; + + outputs = [ "out" "dev" "doc" ]; + + nativeBuildInputs = [ cmake ninja pkg-config ]; + + cmakeDir = "../runtime/Cpp"; + cmakeFlags = [ + "-DANTLR4_INSTALL=ON" + "-DANTLR_BUILD_CPP_TESTS=OFF" + ]; + }; + }; +in + +mkAntlr { + version = "4.13.0"; + jarHash = "sha256-vG9KvA0iWidXASbFFAJWnwAKje2jSHtw52QoQOVw5KY="; + srcHash = "sha256-s1yAdScMYg1wFpYNsBAtpifIhQsnSAgJg7JjPDx+htc="; +} diff --git a/tools/nix/cxxopts.nix b/tools/nix/cxxopts.nix new file mode 100644 index 0000000..a1e5066 --- /dev/null +++ b/tools/nix/cxxopts.nix @@ -0,0 +1,33 @@ +{ stdenv +, fetchFromGitHub +, icu +, cmake, pkg-config +}: + +# From https://github.com/NixOS/nixpkgs/blob/nixos-24.11/pkgs/by-name/cx/cxxopts/package.nix +stdenv.mkDerivation rec { + pname = "cxxopts"; + version = "3.2.0"; + + src = fetchFromGitHub { + owner = "jarro2783"; + repo = "cxxopts"; + tag = "v${version}"; + hash = "sha256-tOO0YCIG3MxSJZhurNcDR1pWIUEO/Har9mrCrZs3iVk="; + }; + + buildInputs = [ icu.dev ]; + cmakeFlags = [ + "-DCXXOPTS_BUILD_EXAMPLES=OFF" + "-DCXXOPTS_USE_UNICODE_HELP=TRUE" + ]; + nativeBuildInputs = [ cmake pkg-config ]; + + doCheck = true; + dontUserCmakeBuildDir = true; + + postPatch = '' + substituteInPlace packaging/pkgconfig.pc.in \ + --replace '$'{prefix}/@CMAKE_INSTALL_INCLUDEDIR@ @CMAKE_INSTALL_FULL_INCLUDEDIR@ + ''; +} diff --git a/tools/nix/pin-nixpkgs.nix b/tools/nix/pin-nixpkgs.nix new file mode 100644 index 0000000..b6a2ff7 --- /dev/null +++ b/tools/nix/pin-nixpkgs.nix @@ -0,0 +1,8 @@ +{}: + +let + pinNixpkgs = import (fetchTarball { + url = "https://github.com/NixOS/nixpkgs/archive/3e889463e499537c602e3ea83da6e33f9dc974da.tar.gz"; + sha256 = "1w7hilh5ix6vppxh5c2zd71l4k1y5wsx5h5s4jya3vw2hhhr99v6"; + } ) { config = {}; overlays = []; }; +in pinNixpkgs