Add code to optionaly generate two cmake package during install when 'ANTLR4_INSTALL' is set:

'antlr4-runtime' which imports the required runtime targets and
'antlr4-generator' which provides a convenient function to use the generator.
Only the latter one has a dependency to the Java package.
This commit is contained in:
Sönke Schau 2018-01-15 17:31:14 +01:00
parent 4cca8cd68d
commit 10d7878ed1
5 changed files with 371 additions and 7 deletions

View File

@ -126,13 +126,67 @@ if (WITH_DEMO)
add_subdirectory(demo)
endif(WITH_DEMO)
# Generate CMake Package Files only if install is active
if (ANTLR4_INSTALL)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
if(NOT ANTLR4_CMAKE_DIR)
set(ANTLR4_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/antlr4 CACHE STRING
"Installation directory for cmake files." FORCE )
endif(NOT ANTLR4_CMAKE_DIR)
set(version_config ${PROJECT_BINARY_DIR}/antlr4-config-version.cmake)
set(project_runtime_config ${PROJECT_BINARY_DIR}/antlr4-runtime-config.cmake)
set(project_generator_config ${PROJECT_BINARY_DIR}/antlr4-generator-config.cmake)
set(targets_export_name antlr4-targets)
set(ANTLR4_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING
"Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.")
set(ANTLR4_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/antlr4-runtime CACHE STRING
"Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.")
configure_package_config_file(
cmake/antlr4-runtime.cmake.in
${project_runtime_config}
INSTALL_DESTINATION ${ANTLR4_CMAKE_DIR}
PATH_VARS
ANTLR4_INCLUDE_DIR
ANTLR4_LIB_DIR )
configure_package_config_file(
cmake/antlr4-generator.cmake.in
${project_generator_config}
INSTALL_DESTINATION ${ANTLR4_CMAKE_DIR}
PATH_VARS
ANTLR4_INCLUDE_DIR
ANTLR4_LIB_DIR )
write_basic_package_version_file(
${version_config}
VERSION ${ANTLR_VERSION}
COMPATIBILITY SameMajorVersion )
install(EXPORT ${targets_export_name}
DESTINATION ${ANTLR4_CMAKE_DIR} )
install(FILES ${project_runtime_config}
${project_generator_config}
${version_config}
DESTINATION ${ANTLR4_CMAKE_DIR} )
endif(ANTLR4_INSTALL)
if( EXISTS LICENSE.txt)
install(FILES LICENSE.txt
DESTINATION "share/doc/libantlr4")
elseif(EXISTS ../../LICENSE.txt)
install(FILES ../../LICENSE.txt
DESTINATION "share/doc/libantlr4")
install(FILES LICENSE.txt
DESTINATION "share/doc/libantlr4")
elseif(EXISTS ../../LICENSE.txt)
install(FILES ../../LICENSE.txt
DESTINATION "share/doc/libantlr4")
endif()
install(FILES README.md VERSION
DESTINATION "share/doc/libantlr4")

View File

@ -0,0 +1,73 @@
{
// See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
"configurations": [
{
"name": "x86-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x86" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"variables": [
{
"name": "ANTLR4_INSTALL",
"value": "1"
}
],
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "x86-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x86" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"variables": [
{
"name": "ANTLR4_INSTALL",
"value": "1"
}
],
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"variables": [
{
"name": "ANTLR4_INSTALL",
"value": "1"
}
],
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
},
{
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "",
"variables": [
{
"name": "ANTLR4_INSTALL",
"value": "1"
}
],
"buildCommandArgs": "-v",
"ctestCommandArgs": ""
}
]
}

View File

@ -0,0 +1,225 @@
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 -> <f>BaseVisitor.h
# -> <f>BaseVisitor.cpp
# -> <f>Visitor.h
# -> <f>Visitor.cpp
#
# Flag -listener active
# Output -> <f>BaseListener.h
# -> <f>BaseListener.cpp
# -> <f>Listener.h
# -> <f>Listener.cpp
#
# The function "antlr4_generate" will generate the required setup to call ANTLR for a given input file
#
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | Argument# | Required | Defaults to | |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | 0 | Yes | n/a | Unique target name. It is used to generate CMake Variables to reference the |
# | | | | various outputs of the generation |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | 1 | Yes | n/a | Input file containing the lexer/parser definition |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | 2 | No | FALSE | Boolean to indicate if a listener interface should be generated |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | 3 | No | FALSE | Boolean to indicate if a visitor interface should be generated |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | 4 | No | none | C++ namespace in which the generated classes should be placed |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | 5 | No | none | Additional files on which the input depends |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
# | 6 | No | none | Library path to use during generation |
# +-----------+-----------+-------------+------------------------------------------------------------------------------+
#
# The ANTLR4_JAR_LOCATION must be set prior calling the function!
#
# The following CMake variables are available following a call to antlr4_generate
#
# ANTLR4_INCLUDE_DIR_<Target name> - Directory containing the generated header files
# ANTLR4_SRC_FILES_<Target name> - List of generated source files
# ANTLR4_TOKEN_FILES_<Target name> - List of generated token files
# ANTLR4_TOKEN_DIRECTORY_<Target name> - Directory containing the generated token files
#
# Sample:
#
# # Bring in the required packages
# find_package(antlr4-runtime REQUIRED)
# find_package(antlr4-generator REQUIRED)
#
# # Set path to generator
# set(ANTLR4_JAR_LOCATION ${PROJECT_SOURCE_DIR}/thirdparty/antlr/antlr-4.7.1-complete.jar)
#
# # generate lexer
# antlr4_generate(
# antlrcpptest_lexer
# ${CMAKE_CURRENT_SOURCE_DIR}/TLexer.g4
# FALSE
# FALSE
# "antlrcpptest"
# )
#
# # generate parser
# antlr4_generate(
# antlrcpptest_parser
# ${CMAKE_CURRENT_SOURCE_DIR}/TParser.g4
# FALSE
# TRUE
# "antlrcpptest"
# "${ANTLR4_TOKEN_FILES_antlrcpptest_lexer}"
# "${ANTLR4_TOKEN_DIRECTORY_antlrcpptest_lexer}"
# )
#
# # add directories for generated include files
# include_directories( ${PROJECT_BINARY_DIR} ${ANTLR4_INCLUDE_DIR_antlrcpptest_lexer} ${ANTLR4_INCLUDE_DIR_antlrcpptest_parser} )
#
# # add generated source files
# add_executable( Parsertest main.cpp ${ANTLR4_SRC_FILES_antlrcpptest_lexer} ${ANTLR4_SRC_FILES_antlrcpptest_parser} )
#
# # add required runtime library
# add_dependencies( Parsertest antlr4_shared )
#
# target_link_libraries( Parsertest PRIVATE
# antlr4_shared)
#
#
function(antlr4_generate
Antlr4_ProjectTarget
Antlr4_InputFile
)
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" )
# Prepare list of generated targets
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.h" )
list( APPEND Antlr4_GeneratedTargets "${Antlr4_GeneratedSrcDir}/${Antlr4_InputFileBaseName}.cpp" )
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" )
# process optional arguments ...
if ( ( ARGC GREATER_EQUAL 3 ) AND ARGV2 )
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 4 ) AND ARGV3 )
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 5 ) AND (NOT ${ARGV4} STREQUAL "") )
set(Antlr4_NamespaceOption "-package;${ARGV4}")
list( APPEND Antlr4_GeneratorStatusMessage " in Namespace ${ARGV4}" )
else()
set(Antlr4_NamespaceOption "")
endif ()
if ( (ARGC GREATER_EQUAL 6 ) AND (NOT ${ARGV5} STREQUAL "") )
set(Antlr4_AdditionalDependencies ${ARGV5})
else()
set(Antlr4_AdditionalDependencies "")
endif ()
if ( (ARGC GREATER_EQUAL 7 ) AND (NOT ${ARGV6} STREQUAL "") )
set(Antlr4_LibOption "-lib;${ARGV6}")
list( APPEND Antlr4_GeneratorStatusMessage " using Library ${ARGV6}" )
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} -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()

View File

@ -0,0 +1,10 @@
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(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
check_required_components(antlr)

View File

@ -97,9 +97,11 @@ set_target_properties(antlr4_static
COMPILE_FLAGS "${disabled_compile_warnings} ${extra_static_compile_flags}")
install(TARGETS antlr4_shared
DESTINATION lib)
DESTINATION lib
EXPORT antlr4-targets)
install(TARGETS antlr4_static
ARCHIVE DESTINATION lib)
DESTINATION lib
EXPORT antlr4-targets)
install(DIRECTORY "${PROJECT_SOURCE_DIR}/runtime/src/"
DESTINATION "include/antlr4-runtime"