ANTLR4 C ++ cmake文件“ ld:找不到体系结构x86_64的符号”

问题描述

我正在尝试通过遵循以下git repo来编写cmake文件https://github.com/paraka/c-compiler-antlr4-cpp-llvm

但是,我在100%的CMake上遇到了问题:ld: symbol(s) not found for architecture x86_64

它的完整错误消息是这样的:

[100%] Linking CXX executable pryst
Undefined symbols for architecture x86_64:
  "antlrcpptest::PrystLexer::PrystLexer(antlr4::CharStream*)",referenced from:
      Compiler::compile() in compiler.cpp.o
  "antlrcpptest::PrystLexer::~PrystLexer()",referenced from:
      Compiler::compile() in compiler.cpp.o
  "antlrcpptest::PrystParser::compilationunit()",referenced from:
      Compiler::compile() in compiler.cpp.o
  "antlrcpptest::PrystParser::PrystParser(antlr4::TokenStream*)",referenced from:
      Compiler::compile() in compiler.cpp.o
  "antlrcpptest::PrystParser::~PrystParser()",referenced from:
      Compiler::compile() in compiler.cpp.o
  "typeinfo for antlrcpptest::PrystParser::typespecifierContext",referenced from:
      std::__1::vector<antlrcpptest::PrystParser::typespecifierContext*,std::__1::allocator<antlrcpptest::PrystParser::typespecifierContext*> > antlr4::ParserRuleContext::getRuleContexts<antlrcpptest::PrystParser::typespecifierContext>() in def_symbols.cpp.o
      bool antlrcpp::is<antlrcpptest::PrystParser::typespecifierContext*,antlr4::tree::ParseTree>(antlr4::tree::ParseTree*) in def_symbols.cpp.o
  "typeinfo for antlrcpptest::PrystParser::DeclarationSpecifierContext",referenced from:
      std::__1::vector<antlrcpptest::PrystParser::DeclarationSpecifierContext*,std::__1::allocator<antlrcpptest::PrystParser::DeclarationSpecifierContext*> > antlr4::ParserRuleContext::getRuleContexts<antlrcpptest::PrystParser::DeclarationSpecifierContext>() in def_symbols.cpp.o
      bool antlrcpp::is<antlrcpptest::PrystParser::DeclarationSpecifierContext*,antlr4::tree::ParseTree>(antlr4::tree::ParseTree*) in def_symbols.cpp.o
  "typeinfo for antlrcpptest::PrystParser::DeclarationSpecifiersContext",referenced from:
      std::__1::vector<antlrcpptest::PrystParser::DeclarationSpecifiersContext*,std::__1::allocator<antlrcpptest::PrystParser::DeclarationSpecifiersContext*> > antlr4::ParserRuleContext::getRuleContexts<antlrcpptest::PrystParser::DeclarationSpecifiersContext>() in def_symbols.cpp.o
      bool antlrcpp::is<antlrcpptest::PrystParser::DeclarationSpecifiersContext*,antlr4::tree::ParseTree>(antlr4::tree::ParseTree*) in def_symbols.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command Failed with exit code 1 (use -v to see invocation)
make[2]: *** [pryst] Error 1
make[1]: *** [CMakeFiles/pryst.dir/all] Error 2
make: *** [all] Error 2

项目树是这样的:

pryst/
|-- cmake/
|---- ExternalAntlr4Cpp.cmake
|-- 3rdparty/
|---- antlr/
|------ antlr-4.8-complete.jar
|------ antlr-master.zip
|-- grammar/
|---- Pryst.g4
|-- src/
|---- main.cpp
|-- CMakeLists.txt

我的CMakeLists.txt是这样的:

# Set the minimum version of CMake that can be used
# To find the cmake version run
# $ cmake --version
cmake_minimum_required(VERSION 3.5)

# Set the project name
project (pryst)

set(CMAKE_CXX_STANDARD 14)

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

# set variable pointing to the antlr tool that supports C++
set(ANTLR4CPP_JAR_LOCATION ${PROJECT_SOURCE_DIR}/3rdparty/antlr/antlr-4.8-complete.jar)

# add external build for antlrcpp
include(ExternalAntlr4Cpp)

# add antlr4cpp artifacts to project environment
include_directories(${ANTLR4CPP_INCLUDE_Dirs})
link_directories(${ANTLR4CPP_LIBS})

message(STATUS "Found antlr4cpp libs: ${ANTLR4CPP_LIBS} and includes: ${ANTLR4CPP_INCLUDE_Dirs} ")

# Call macro to add lexer and grammar to your build dependencies.
antlr4cpp_process_grammar(pryst antlrcpptest
  ${CMAKE_CURRENT_SOURCE_DIR}/grammar/Pryst.g4
  ${CMAKE_CURRENT_SOURCE_DIR}/grammar/Pryst.g4)

# include generated files in project environment
include_directories(${antlr4cpp_include_dirs_antlrcpptest})

# Create a sources variable with a link to all cpp files to compile
set(SOURCES
    src/compiler.cpp
    src/def_symbols.cpp
    src/main.cpp
    ${antlr4cpp_src_files_antlrcpptest}
)

# Add an executable with the above sources
add_executable(pryst ${SOURCES})

# Set the directories that should be included in the build command for this target
# when running g++ these will be included as -I/directory/path/
target_include_directories(pryst
    PRIVATE 
        ${PROJECT_SOURCE_DIR}/include
)

add_dependencies(pryst antlr4cpp antlr4cpp_generation_antlrcpptest)
target_link_libraries(pryst antlr4-runtime)

最后,我的ExternalAntlr4Cpp.cmake文件如下所示:

# -*- mode:cmake -*-
#
# This Cmake file is for those using a superbuild Cmake Pattern,it
# will download the tools and build locally
#
# use 2the antlr4cpp_process_grammar to support multiple grammars in the
# same project
#
# - Getting quicky started with Antlr4cpp
#
# Here is how you can use this external project to create the antlr4cpp
# demo to start your project off.
#
# create your project source folder somewhere. e.g. ~/srcfolder/
# + make a subfolder cmake
# + copy this file to srcfolder/cmake
# + cut below and use it to create srcfolder/CMakeLists.txt,# + from https://github.com/DanMcLaughlin/antlr4/tree/master/runtime/Cpp/demo copy main.cpp,TLexer.g4 and TParser.g4 to ./srcfolder/
#
# next make a build folder e.g. ~/buildfolder/
# from the buildfolder,run cmake ~/srcfolder; make
#
###############################################################
# # minimum required CMAKE version
# CMAKE_MINIMUM_required(VERSION 2.8.12.2 FATAL_ERROR)
#
# LIST( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake )
#
# # compiler must be 11 or 14
# SET (CMAKE_CXX_STANDARD 11)
#
# # set variable pointing to the antlr tool that supports C++
# set(ANTLR4CPP_JAR_LOCATION /home/user/antlr4-4.5.4-SNAPSHOT.jar)
# # add external build for antlrcpp
# include( ExternalAntlr4Cpp )
# # add antrl4cpp artifacts to project environment
# include_directories( ${ANTLR4CPP_INCLUDE_Dirs} )
# link_directories( ${ANTLR4CPP_LIBS} )
# message(STATUS "Found antlr4cpp libs: ${ANTLR4CPP_LIBS} and includes: ${ANTLR4CPP_INCLUDE_Dirs} ")
#
# # Call macro to add lexer and grammar to your build dependencies.
# antlr4cpp_process_grammar(demo antlrcpptest
#   ${CMAKE_CURRENT_SOURCE_DIR}/TLexer.g4
#   ${CMAKE_CURRENT_SOURCE_DIR}/TParser.g4)
# # include generated files in project environment
# include_directories(${antlr4cpp_include_dirs_antlrcpptest})
#
# # add generated grammar to demo binary target
# add_executable(demo main.cpp ${antlr4cpp_src_files_antlrcpptest})
# add_dependencies(demo antlr4cpp antlr4cpp_generation_antlrcpptest)
# target_link_libraries(demo antlr4-runtime)
#
###############################################################

CMAKE_MINIMUM_required(VERSION 3.5)
PROJECT(antlr4cpp_fetcher CXX)
INCLUDE(ExternalProject)
FIND_PACKAGE(Git required)

# only JRE required
FIND_PACKAGE(Java COMPONENTS Runtime required)

############ Download and Generate runtime #################
set(ANTLR4CPP_EXTERNAL_ROOT ${CMAKE_BINARY_DIR}/externals/antlr4cpp)

# external repository
# GIT_REPOSITORY     https://github.com/antlr/antlr4.git
# set(ANTLR4CPP_EXTERNAL_REPO "https://github.com/antlr/antlr4.git")
# set(ANTLR4CPP_EXTERNAL_TAG  "4.7.1")

# Add deFinitions for the local repository
set(ANTLR4CPP_LOCAL_ROOT ${CMAKE_BINARY_DIR}/locals/antlr4cpp)
SET(ANTLR4CPP_LOCAL_REPO ${PROJECT_SOURCE_DIR}/3rdparty/antlr/antlr4-master.zip)

if(NOT EXISTS "${ANTLR4CPP_JAR_LOCATION}")
  message(FATAL_ERROR "Unable to find antlr tool. ANTLR4CPP_JAR_LOCATION:${ANTLR4CPP_JAR_LOCATION}")
endif()

# default path for source files
if (NOT ANTLR4CPP_GENERATED_SRC_DIR)
  set(ANTLR4CPP_GENERATED_SRC_DIR ${CMAKE_BINARY_DIR}/antlr4cpp_generated_src)
endif()

# !Todo! This should probably check with Cmake Find first?
# set(ANTLR4CPP_JAR_LOCATION ${ANTLR4CPP_EXTERNAL_ROOT}/${ANTLR4CPP_JAR_NAME})
#
# !Todo! Ensure Antlr tool available - copy from internet
#
# # !Todo! this shold be calculated based on the tags
# if (NOT ANTLR4CPP_JAR_NAME)
#   # default location to find antlr Java binary
#   set(ANTLR4CPP_JAR_NAME antlr4-4.5.4-SNAPSHOT.jar)
# endif()
#
# if(NOT EXISTS "${ANTLR4CPP_JAR_LOCATION}")
#   # download Java tool if not installed
#   ExternalProject_ADD(
#     #--External-project-name------
#     antlrtool
#     #--Core-directories-----------
#     PREFIX             ${ANTLR4CPP_EXTERNAL_ROOT}
#     #--Download step--------------
#     DOWNLOAD_DIR       ${ANTLR4CPP_EXTERNAL_ROOT}
#     DOWNLOAD_COMMAND   ""
#     # URL              http://www.antlr.org/download/${ANTLR4CPP_JAR_NAME}
#     # antlr4-4.5.4-SNAPSHOT.jar
#     # GIT_TAG            v4.5.4
#     TIMEOUT            10
#     LOG_DOWNLOAD       ON
#     #--Update step----------
#     # UPDATE_COMMAND     ${GIT_EXECUTABLE} pull
#     #--Patch step----------
#     # PATCH_COMMAND sh -c "cp <SOURCE_DIR>/scripts/CMakeLists.txt <SOURCE_DIR>"
#     #--Configure step-------------
#     CMAKE_ARGS         ""
#     CONfigURE_COMMAND  ""
#     LOG_CONfigURE ON
#     #--Build step-----------------
#     BUILD_COMMAND      ""
#     LOG_BUILD ON
#     #--Install step---------------
#     INSTALL_COMMAND    ""
#     )
#   # Verify Antlr Available
#   if(NOT EXISTS "${ANTLR4CPP_JAR_LOCATION}")
#     message(FATAL_ERROR "Unable to find ANTLR4CPP_JAR_LOCATION:${ANTLR4CPP_JAR_LOCATION} -> ${ANTLR4CPP_JAR_NAME} not in ${ANTLR4CPP_DIR} ")
#   endif()
# endif()

# download runtime environment
ExternalProject_ADD(
  #--External-project-name------
  antlr4cpp
  #--Depend-on-antrl-tool-----------
  # DEPENDS antlrtool
  #--Core-directories-----------
 # PREFIX             ${ANTLR4CPP_EXTERNAL_ROOT}
  PREFIX             ${ANTLR4CPP_LOCAL_ROOT}
  #--Download step--------------
 # GIT_REPOSITORY     ${ANTLR4CPP_EXTERNAL_REPO}
  URL                ${ANTLR4CPP_LOCAL_REPO}
  # GIT_TAG          ${ANTLR4CPP_EXTERNAL_TAG}
  TIMEOUT            10
  LOG_DOWNLOAD       ON
  #--Update step----------
  UPDATE_COMMAND     ${GIT_EXECUTABLE} pull
  #--Patch step----------
  # PATCH_COMMAND sh -c "cp <SOURCE_DIR>/scripts/CMakeLists.txt <SOURCE_DIR>"
  #--Configure step-------------
  CONfigURE_COMMAND  ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Release -DANTLR4CPP_JAR_LOCATION=${ANTLR4CPP_JAR_LOCATION} -DBUILD_SHARED_LIBS=ON -DBUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_SOURCE_DIR:PATH=<SOURCE_DIR>/runtime/Cpp <SOURCE_DIR>/runtime/Cpp
  LOG_CONfigURE ON
  #--Build step-----------------
  # BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
  LOG_BUILD ON
  #--Install step---------------
  # INSTALL_COMMAND    ""
  # INSTALL_DIR ${CMAKE_BINARY_DIR}/
  #--Install step---------------
  # INSTALL_COMMAND    ""
)

ExternalProject_Get_Property(antlr4cpp INSTALL_DIR)

list(APPEND ANTLR4CPP_INCLUDE_Dirs ${INSTALL_DIR}/include/antlr4-runtime)
foreach(src_path misc atn dfa tree support)
  list(APPEND ANTLR4CPP_INCLUDE_Dirs ${INSTALL_DIR}/include/antlr4-runtime/${src_path})
endforeach(src_path)

set(ANTLR4CPP_LIBS "${INSTALL_DIR}/lib")

# antlr4_shared ${INSTALL_DIR}/lib/libantlr4-runtime.so
# antlr4_static ${INSTALL_DIR}/lib/libantlr4-runtime.a

############ Generate runtime #################
# macro to add dependencies to target
#
# Param 1 project name
# Param 1 namespace (postfix for dependencies)
# Param 2 Lexer file (full path)
# Param 3 Parser File (full path)
#
# output
#
# antlr4cpp_src_files_{namespace} - src files for add_executable
# antlr4cpp_include_dirs_{namespace} - include dir for generated headers
# antlr4cpp_generation_{namespace} - for add_dependencies tracking

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()

  add_custom_target("antlr4cpp_generation_${antlr4cpp_project_namespace}"
    COMMAND
    ${CMAKE_COMMAND} -E make_directory ${ANTLR4CPP_GENERATED_SRC_DIR}
    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}"
    )

  # 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})
    if (NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
    set_source_files_properties(
      ${generated_file}
      PROPERTIES
      COMPILE_FLAGS -Wno-overloaded-virtual
      )
    endif ()
  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()

有关更多信息,我的系统信息是:

OS: macOS Catalina 10.15.6,cmake: /usr/local/bin/cmake,version: 3.18.2
make: /usr/bin/make,version: 3.81
another make: /Library/Developer/CommandLinetools/usr/bin/make,version: 3.81

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)