## Getting started with Antlr4Cpp Here is how you can use this external project to create the antlr4cpp demo to start your project off. 1. Create your project source folder somewhere. e.g. ~/srcfolder/ 1. Make a subfolder cmake 2. Copy the files in this folder to srcfolder/cmake 3. Cut below and use it to create srcfolder/CMakeLists.txt 4. Copy main.cpp, TLexer.g4 and TParser.g4 to ./srcfolder/ from [here](https://github.com/antlr/antlr4/tree/master/runtime/Cpp/demo) 2. Make a build folder e.g. ~/buildfolder/ 3. From the buildfolder, run `cmake ~/srcfolder; make` ```cmake # minimum required CMAKE version CMAKE_MINIMUM_REQUIRED(VERSION 3.7 FATAL_ERROR) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # compiler must be 11 or 14 set(CMAKE_CXX_STANDARD 11) # required if linking to static library add_definitions(-DANTLR4CPP_STATIC) # using /MD flag for antlr4_runtime (for Visual C++ compilers only) set(ANTLR4_WITH_STATIC_CRT OFF) # add external build for antlrcpp include(ExternalAntlr4Cpp) # add antrl4cpp artifacts to project environment include_directories(${ANTLR4_INCLUDE_DIRS}) # set variable pointing to the antlr tool that supports C++ # this is not required if the jar file can be found under PATH environment set(ANTLR_EXECUTABLE /home/user/antlr-4.9.2-complete.jar) # add macros to generate ANTLR Cpp code from grammar find_package(ANTLR REQUIRED) # Call macro to add lexer and grammar to your build dependencies. antlr_target(SampleGrammarLexer TLexer.g4 LEXER PACKAGE antlrcpptest) antlr_target(SampleGrammarParser TParser.g4 PARSER PACKAGE antlrcpptest DEPENDS_ANTLR SampleGrammarLexer COMPILE_FLAGS -lib ${ANTLR_SampleGrammarLexer_OUTPUT_DIR}) # include generated files in project environment include_directories(${ANTLR_SampleGrammarLexer_OUTPUT_DIR}) include_directories(${ANTLR_SampleGrammarParser_OUTPUT_DIR}) # add generated grammar to demo binary target add_executable(demo main.cpp ${ANTLR_SampleGrammarLexer_CXX_OUTPUTS} ${ANTLR_SampleGrammarParser_CXX_OUTPUTS}) target_link_libraries(demo antlr4_static) ``` ## Documentation for FindANTLR The module defines the following variables: ``` ANTLR_FOUND - true is ANTLR jar executable is found ANTLR_EXECUTABLE - the path to the ANTLR jar executable ANTLR_VERSION - the version of ANTLR ``` If ANTLR is found, the module will provide the macros: ``` ANTLR_TARGET( [PACKAGE namespace] [OUTPUT_DIRECTORY dir] [DEPENDS_ANTLR ] [COMPILE_FLAGS [args...]] [DEPENDS [depends...]] [LEXER] [PARSER] [LISTENER] [VISITOR]) ``` which creates a custom command to generate C++ files from ``. Running the macro defines the following variables: ``` ANTLR_${name}_INPUT - the ANTLR input used for the macro ANTLR_${name}_OUTPUTS - the outputs generated by ANTLR ANTLR_${name}_CXX_OUTPUTS - the C++ outputs generated by ANTLR ANTLR_${name}_OUTPUT_DIR - the output directory for ANTLR ``` The options are: * `PACKAGE` - defines a namespace for the generated C++ files * `OUTPUT_DIRECTORY` - the output directory for the generated files. By default it uses `${CMAKE_CURRENT_BINARY_DIR}` * `DEPENDS_ANTLR` - the dependent target generated from antlr_target for the current call * `COMPILE_FLAGS` - additional compile flags for ANTLR tool * `DEPENDS` - specify the files on which the command depends. It works the same way `DEPENDS` in [`add_custom_command()`](https://cmake.org/cmake/help/v3.11/command/add_custom_command.html) * `LEXER` - specify that the input file is a lexer grammar * `PARSER` - specify that the input file is a parser grammar * `LISTENER` - tell ANTLR tool to generate a parse tree listener * `VISITOR` - tell ANTLR tool to generate a parse tree visitor ### Examples To generate C++ files from an ANTLR input file T.g4, which defines both lexer and parser grammar one may call: ```cmake find_package(ANTLR REQUIRED) antlr_target(Sample T.g4) ``` Note that this command will do nothing unless the outputs of `Sample`, i.e. `ANTLR_Sample_CXX_OUTPUTS` gets used by some target. ## Documentation for ExternalAntlr4Cpp Including ExternalAntlr4Cpp will add `antlr4_static` and `antlr4_shared` as an optional target. It will also define the following variables: ``` ANTLR4_INCLUDE_DIRS - the include directory that should be included when compiling C++ source file ANTLR4_STATIC_LIBRARIES - path to antlr4 static library ANTLR4_SHARED_LIBRARIES - path to antlr4 shared library ANTLR4_RUNTIME_LIBRARIES - path to antlr4 shared runtime library (such as DLL, DYLIB and SO file) ANTLR4_TAG - branch/tag used for building antlr4 library ``` `ANTLR4_TAG` is set to master branch by default to keep antlr4 updated. However, it will be required to rebuild after every `clean` is called. Set `ANTLR4_TAG` to a desired commit hash value to avoid rebuilding after every `clean` and keep the build stable, at the cost of not automatically update to latest commit. The ANTLR C++ runtime source is downloaded from GitHub by default. However, users may specify `ANTLR4_ZIP_REPOSITORY` to list the zip file from [ANTLR downloads](http://www.antlr.org/download.html) (under *C++ Target*). This variable can list a zip file included in the project directory; this is useful for maintaining a canonical source for each new build. Visual C++ compiler users may want to additionally define `ANTLR4_WITH_STATIC_CRT` before including the file. Set `ANTLR4_WITH_STATIC_CRT` to true if ANTLR4 C++ runtime library should be compiled with `/MT` flag, otherwise will be compiled with `/MD` flag. This variable has a default value of `OFF`. Changing `ANTLR4_WITH_STATIC_CRT` after building the library may require reinitialization of CMake or `clean` for the library to get rebuilt. You may need to modify your local copy of ExternalAntlr4Cpp.cpp to modify some build settings. For example, to specify the C++ standard to use when building the runtime, add `-DCMAKE_CXX_STANDARD:STRING=17` to `CMAKE_CACHE_ARGS`. ### Examples To build and link ANTLR4 static library to a target one may call: ```cmake include(ExternalAntlr4Cpp) include_directories(${ANTLR4_INCLUDE_DIRS}) add_executable(output main.cpp) target_link_libraries(output antlr4_static) ``` It may also be a good idea to copy the runtime libraries (DLL, DYLIB or SO file) to the executable for it to run properly after build. i.e. To build and link antlr4 shared library to a target one may call: ```cmake include(ExternalAntlr4Cpp) include_directories(${ANTLR4_INCLUDE_DIRS}) add_executable(output main.cpp) target_link_libraries(output antlr4_shared) add_custom_command(TARGET output POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${ANTLR4_RUNTIME_LIBRARIES} . WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) ```