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) if (NOT DEFINED ANTLR4_GIT_REPOSITORY) set(ANTLR4_GIT_REPOSITORY https://github.com/antlr/antlr4.git) endif() 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.1.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} GIT_SHALLOW 1 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() macro(antlr4cpp_process_grammar antlr4cpp_project antlr4cpp_project_namespace antlr4cpp_grammar_lexer antlr4cpp_grammar_parser) if(EXISTS "${ANTLR4CPP_JAR_LOCATION}") message(STATUS "Found antlr tool: ${ANTLR4CPP_JAR_LOCATION}") else() message(FATAL_ERROR "Unable to find antlr tool. ANTLR4CPP_JAR_LOCATION:${ANTLR4CPP_JAR_LOCATION}") endif() message(STATUS "GENERATED_SRC_DIR: ${ANTLR4CPP_GENERATED_SRC_DIR}") add_custom_target("antlr4cpp_generation_${antlr4cpp_project_namespace}" COMMAND ${CMAKE_COMMAND} -E make_directory "${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}" COMMAND "${Java_JAVA_EXECUTABLE}" -jar "${ANTLR4CPP_JAR_LOCATION}" -Werror -Dlanguage=Cpp -listener -visitor -o "${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}" -package ${antlr4cpp_project_namespace} "${antlr4cpp_grammar_lexer}" "${antlr4cpp_grammar_parser}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" DEPENDS "${antlr4cpp_grammar_lexer}" "${antlr4cpp_grammar_parser}" COMMENT "Generating ${antlr4cpp_project_namespace} with antlr4cpp" ) # message(STATUS "Generate Command: ${Java_JAVA_EXECUTABLE} -jar ${ANTLR4CPP_JAR_LOCATION} -Werror -Dlanguage=Cpp -listener -visitor -o ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace} -package ${antlr4cpp_project_namespace} ${antlr4cpp_grammar_lexer} ${antlr4cpp_grammar_parser}") # Find all the input files FILE(GLOB generated_files ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}/*.cpp) # export generated cpp files into list foreach(generated_file ${generated_files}) list(APPEND antlr4cpp_src_files_${antlr4cpp_project_namespace} ${generated_file}) set_source_files_properties( ${generated_file} PROPERTIES COMPILE_FLAGS -Wno-overloaded-virtual ) endforeach(generated_file) message(STATUS "Antlr4Cpp ${antlr4cpp_project_namespace} Generated: ${generated_files}") # export generated include directory set(antlr4cpp_include_dirs_${antlr4cpp_project_namespace} ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}) message(STATUS "Antlr4Cpp ${antlr4cpp_project_namespace} include: ${ANTLR4CPP_GENERATED_SRC_DIR}/${antlr4cpp_project_namespace}") endmacro()