2016-07-07 6 views
4

Я новичок в компиляторе LLVM и инфраструктуре. У меня есть следующая мысль. Clang - это интерфейс LLVM для C/C++, аналогично Rustc для языка программирования Rust. Оба могут испускать ИК-код LLVM, а испускаемый код может быть скомпилирован в исполняемое приложение.LLVM как базовый компилятор для разных языков

Вопрос в том, можно ли связать разные языки программирования? Пример показан ниже -

/* Code in C */ 
int add(int, int); 
int main() 
{ 
    printf("%d", add(5 ,6)); 
} 

функция, определенная в Руст, например

// Code in Rust 
fn main() 
{ 
    println!("{}", add(5, 6)); 
} 

fn add (x: i32, y: i32) -> i32 
{ 
    x + y 
} 

После того, как ИК генерируется из обоих исходных файлов, можно связать их и создать одно приложение?

Мне просто интересно узнать, работает ли это, пожалуйста, дайте мне знать.

+0

Я думаю, что у вас должно быть место для ржавчины где-то ... но проблема другая, если вызов c из ржавчины или наоборот. –

+0

Каждый исходный код должен указываться отдельно для каждого человека.Впоследствии команда llvm-link может объединять несколько файлов биткода. Если вызов из одного исходного кода соответствует второму, он может работать. –

+1

Оба языка должны быть совместимы с Binary Interface. –

ответ

2

Во-первых, Rust и C могут говорить, но через FFI (внешний интерфейс) Rust's. Для очень простых функций, я полагаю, можно было бы скомпилировать оба языка в LLVM и иметь какую-то функциональность, но мы говорим о программах глобальной длины (возможно, даже не на этом уровне). В общем, должно быть что-то вроде ABI, чтобы реализовать то, что вы предлагаете. Однако даже с ABI реализация выполняется на уровне Front End.

Вкратце, LLVM не может представлять все специфические для языка конструкции. Поэтому вы не можете просто связать LLVM IR двух программ и надеяться, что это сработает. Для обеспечения совместимости между двумя языками необходимо выполнить некоторую работу на передней панели.

5

Краткий ответ: Да.


Долгий ответ: Да, если выполняются некоторые требования.

Существует два вида совместимости: API (Application Program Interface) и ABI (Application Binary Interface). По сути, API диктует, компилируется ли ваша программа, тогда как ABI диктует, связывает ли она, загружает и запускает.

Поскольку Rust имеет C FFI, Rust может испускать код, который может нормально взаимодействовать с C (у него есть надлежащий C ABI, для рассматриваемой платформы). Это видно из того, что двоичный код Rust может вызывать библиотеку C.

Если вы берете LLVM IR этого двоичного кода Rust, LLVM IR этой библиотеки C, объединяйтесь вместе и используйте LLVM для создания нового двоичного файла, тогда вы получите единый двоичный файл (без зависимости).

Итак, требование «только» состоит в том, что ваши две части кода должны иметь возможность сначала связывать/загружать/запускать независимо.


Другой способ получения одного двоичного файла, который не зависит от LLVM, является статического связывания; в Rust вы можете, например, статическую ссылку с мультовой реализацией стандартной библиотеки C. Основным преимуществом слияния в LLVM IR является то, что вы можете выполнять пропуски LLVM-оптимизации на объединенном IR и, следовательно, извлекать выгоду из кросс-языковой встраивания (и других оптимизаций).

+0

Я думаю, что длинный ответ должен быть иногда, не обязательно да, потому что требуется ABI для взаимодействия. ABI, безусловно, требует некоторой работы для реализации, поэтому вы не можете просто связать IR-выходы разных языков. Помимо этого, я думаю, вы дали довольно хороший ответ на вопрос. –

+0

@BennetLeff: Именно этот ответ на самом деле говорит: если обе части кода могут загружаться/запускаться в отдельных библиотеках, тогда вы можете объединить свои IR и запустить их (поскольку вы подтвердили ABI). Или вы имеете в виду, что я должен что-то редактировать, потому что это не слишком ясно? –

+0

Я думаю, что ваш ответ может оставаться как есть. Однако мне было бы более понятно, если вместо «Длинный ответ: да ...» он сказал «Длинный ответ: иногда ...» –