LLVM编译器 – 未定义的引用

huangapple go评论88阅读模式
英文:

LLVM compiler - undefined references

问题

我正在使用C++和LLVM开发一个编译器。我已经实现了简单的数字和字符串功能。然而,当我尝试编译程序时,我遇到了构建错误。

undefined reference to 'llvm::BasicBlock::BasicBlock(llvm::LLVMContext&, llvm::Twine const&, llvm::Function*, llvm::BasicBlock*)'
undefined reference to 'llvm::ConstantInt::get(llvm::IntegerType*, unsigned long long, bool)'
undefined reference to 'llvm::Type::getInt32Ty(llvm::LLVMContext&)'
undefined reference to 'llvm::Type::getInt64Ty(llvm::LLVMContext&)'
undefined reference to 'llvm::Function::Create(llvm::FunctionType*, llvm::GlobalValue::LinkageTypes, llvm::Twine const&, llvm::Module&)'
undefined reference to 'llvm::outs()'

这并不是实际错误,只是其中一部分。我得到了许多"undefined references"错误。以下是我的代码生成器类的代码:

#ifndef COMPILER_CODEGENERATION_H
#define COMPILER_CODEGENERATION_H

#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/Function.h"
#include "ASTNode.h"

namespace COMPILER {

    class CodeGenerator {
        std::shared_ptr<llvm::Module> _module;
        std::shared_ptr<llvm::LLVMContext> _context;
        std::shared_ptr<llvm::IRBuilder<>> _irBuilder;

        llvm::BasicBlock * createBlock(const std::string &blockName, llvm::Function *targetFunc) {
            return llvm::BasicBlock::Create(*_context, blockName, targetFunc);
        }

        llvm::Function * createFunctionPrototype(const std::string &funcName, llvm::FunctionType *funcType) {
            auto proto = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, funcName, *_module);
            llvm::verifyFunction(*proto);
            return proto;
        }

        void createFunction(const std::string &funcName, llvm::FunctionType *funcType) {
            auto proto = createFunctionPrototype(funcName, funcType);
            auto block = createBlock("entry", proto);
            _irBuilder->SetInsertPoint(block);
        }

    public:
        CodeGenerator(
                const std::shared_ptr<llvm::Module> &module, const std::shared_ptr<llvm::LLVMContext> &context,
                const std::shared_ptr<llvm::IRBuilder<>> &builder
        ) {
            _module = module;
            _context = context;
            _irBuilder = builder;
        }

        // LLVM Value可以表示任何内容,例如指令、字符串、数字等...
        void Compile(const std::vector<std::unique_ptr<Compiler::IExpression>> &statementList) {
            createFunction("main", llvm::FunctionType::get(_irBuilder->getInt32Ty(), false));
            for(auto &expressionStatement: statementList) {
                expressionStatement->codegen(_module, _context, _irBuilder);
            }
        }
    };

    llvm::Value * Compiler::NumberExpressionNode::codegen(
            const std::shared_ptr<llvm::Module> &module,
            const std::shared_ptr<llvm::LLVMContext> &context,
            const std::shared_ptr<llvm::IRBuilder<>> &builder){
        return builder->getInt64(_num);
    }
}

#endif

你可以忽略头文件和命名空间名称,因为它们不重要。我正在使用Windows 10和CLion进行项目开发。以下是我用于下载和编译LLVM的命令:

cd <path_where_the_files_will_be_installed>
git clone --config core.autocrlf=false --depth 1 https://github.com/llvm/llvm-project.git
cd llvm-project
cd llvm
mkdir build
cd build
cmake ..
cmake --build . --config Debug --target INSTALL -j <number_of_cores>

这是我的CMakeLists文件:

cmake_minimum_required(VERSION 3.24)
project(Compiler)

set(CMAKE_CXX_STANDARD 17)

find_package(LLVM REQUIRED CONFIG PATHS Dependencies/llvm/llvm-project/llvm/build NO_DEFAULT_PATH)

include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})

add_executable(Compiler main.cpp compiler/src/Tokenization.h compiler/src/ASTNode.h compiler/src/Parser.h compiler/src/CodeGeneration.h compiler/src/Compiler.h)

llvm_map_components_to_libnames(llvm_libs support core irreader)

target_link_libraries(Compiler ${llvm_libs})

每个AST中的节点都有一个在上面的CodeGeneration文件中实现的codegen()方法。

请问有人可以帮我解决这个错误吗?谢谢!我已经尝试了不同的下载和编译LLVM的方法,但都没有成功。我还检查了正确的LLVM安装和我的CMakeLists.txt文件。

英文:

I'm woriking on a comiler in C++ using LLVM. I've already came to the point where I implemented simple numbers and strings. However, when I tried compiling the programm I got a build error.

undefined reference to `llvm::BasicBlock::BasicBlock(llvm::LLVMContext&amp;, llvm::Twine const&amp;, llvm::Function*, llvm::BasicBlock*)&#39;
undefined reference to `llvm::ConstantInt::get(llvm::IntegerType*, unsigned long long, bool)&#39;
undefined reference to `llvm::Type::getInt32Ty(llvm::LLVMContext&amp;)&#39;
undefined reference to `llvm::Type::getInt64Ty(llvm::LLVMContext&amp;)&#39;
undefined reference to `llvm::Function::Create(llvm::FunctionType*, llvm::GlobalValue::LinkageTypes, llvm::Twine const&amp;, llvm::Module&amp;)&#39;
undefined reference to `llvm::outs()&#39;

This is not the actual error, just a portion of it. I am getting a bunch of undefined references.
Here's the code for my code generator class:

#ifndef COMPILER_CODEGENERATION_H
#define COMPILER_CODEGENERATION_H
#include &quot;llvm/IR/Module.h&quot;
#include &quot;llvm/IR/IRBuilder.h&quot;
#include &quot;llvm/IR/LLVMContext.h&quot;
#include &quot;llvm/IR/Verifier.h&quot;
#include &quot;llvm/IR/Function.h&quot;
#include &quot;ASTNode.h&quot;
namespace COMPILER {
class CodeGenerator {
std::shared_ptr&lt;llvm::Module&gt; _module;
std::shared_ptr&lt;llvm::LLVMContext&gt; _context;
std::shared_ptr&lt;llvm::IRBuilder&lt;&gt;&gt; _irBuilder;
llvm::BasicBlock * createBlock(const std::string &amp;blockName, llvm::Function *targetFunc) {
return llvm::BasicBlock::Create(*_context,blockName, targetFunc);
}
llvm::Function * createFunctionPrototype(const std::string &amp;funcName, llvm::FunctionType *funcType) {
auto proto = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, funcName, *_module);
llvm::verifyFunction(*proto);
return proto;
}
void createFunction(const std::string &amp;funcName, llvm::FunctionType *funcType) {
auto proto = createFunctionPrototype(funcName, funcType);
auto block = createBlock(&quot;entry&quot;, proto);
_irBuilder-&gt;SetInsertPoint(block);
}
public:
CodeGenerator(
const std::shared_ptr&lt;llvm::Module&gt; &amp;module, const std::shared_ptr&lt;llvm::LLVMContext&gt; &amp;context,
const std::shared_ptr&lt;llvm::IRBuilder&lt;&gt;&gt; &amp;builder
) {
_module = module;
_context = context;
_irBuilder = builder;
}
// LLVM Value can represent anything. Eg. instructions, strings, numbers ...
void Compile(const std::vector&lt;std::unique_ptr&lt;Compiler::IExpression&gt;&gt; &amp;statementList) {
createFunction(&quot;main&quot;, llvm::FunctionType::get(_irBuilder-&gt;getInt32Ty(), false));
for(auto &amp;expressionStatement: statementList) {
expressionStatement-&gt;codegen(_module, _context, _irBuilder);
}
}
};
llvm::Value * Compiler::NumberExpressionNode::codegen(
const std::shared_ptr&lt;llvm::Module&gt; &amp;module,
const std::shared_ptr&lt;llvm::LLVMContext&gt; &amp;context,
const std::shared_ptr&lt;llvm::IRBuilder&lt;&gt;&gt; &amp;builder){
return builder-&gt;getInt64(_num);
}
}
#endif

You can ignore the header file and namespace names, because the don't matter.
I am using Windows 10 and CLion for my project.
Here are the commands that I've used to download and compile LLVM.

cd &lt;path_where_the_files_will_be_installed&gt;
git clone --config core.autocrlf=false --depth 1 https://github.com/llvm/llvm-project.git
cd llvm-project
cd llvm
mkdir build
cd build
cmake ..
cmake --build . --config Debug --target INSTALL -j &lt;number_of_cores&gt;

Here's my CMakeLists

cmake_minimum_required(VERSION 3.24)
project(Compiler)
set(CMAKE_CXX_STANDARD 17)
find_package(LLVM REQUIRED CONFIG PATHS Dependencies/llvm/llvm-project/llvm/build NO_DEFAULT_PATH)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
add_executable(Compiler main.cpp compiler/src/Tokenization.h compiler/src/ASTNode.h compiler/src/Parser.h compiler/src/CodeGeneration.h compiler/src/Compiler.h)
llvm_map_components_to_libnames(llvm_libs support core irreader)
target_link_libraries(Compiler ${llvm_libs})

The code hirarchy

Earch node in the AST has a codegen() method that is implemented in the CodeGeneration file above.

Please can somebody help me with this error?
Thanks LLVM编译器 – 未定义的引用

I've already tried different methods of downloading and compiling LLVM, but non of them worked.
I also checked for the right LLVM installation and checked my CMakeLists.txt

答案1

得分: 0

我已经在使用LLVM基础设施在Windows上时遇到了这个问题,并尝试修复它,但没有任何效果。
然后,我只是在Microsoft Store上安装了WSL(Windows子系统 for Linux)的Ubuntu版本。
最后,我使用apt安装了LLVM和Clang,编译了我的项目,它成功运行了!

英文:

I already ran into that issue when using the LLVM infrastructure on Windows and tried to fix it but nothing worked.
Then, I just installed the Ubuntu version of WSL (The Windows Subsystem for Linux) on the Microsoft Store.
Finally, I installed LLVM and Clang with apt, compiled my project and it worked!

huangapple
  • 本文由 发表于 2023年6月2日 05:12:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76385747.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定