2015-07-01 10 views
21

Possiedo un C++/Qt project esistente creato con CMake. Vorrei iniziare ad aggiungere il codice Rust che posso richiamare dall'interno della base di codice C++ principale.Come posso creare il codice Rust con un progetto C++/Qt/CMake?

Qual è il modo giusto per strutturare il progetto?

attuale struttura del progetto:

./CMakeLists.txt 
./subproject-foo/CMakeLists.txt 
./subproject-foo/src/... 
./subproject-bar/CmakeLists.txt 
./subproject-bar/src/... 
./common/CMakeLists.txt 
./common/src/... 

Vorrei aggiungere una directory common-rust/... con struttura simile.

Come posso incorporarlo nel progetto?

+0

Sei in grado di utilizzare 'carico'? Se è così, suggerirei di avere regole che chiamano Cargo. – Shepmaster

risposta

29

Per questo è possibile utilizzare ExternalProject module. È progettato per consentire la creazione di dipendenze esterne, anche quelle che non utilizzano CMake. Ecco un useful article sul suo utilizzo.

Così dicono che hai il tuo sottodirectory "common-ruggine" e il suo Cargo.toml contiene:

[package] 
name = "rust_example" 
version = "0.1.0" 

[lib] 
name = "rust_example" 
crate-type = ["staticlib"] 

ed espone una funzione add attraverso le sue lib.rs:

#[no_mangle] 
pub extern fn add(lhs: u32, rhs: u32) -> u32 { 
    lhs + rhs 
} 

Allora la vostra CMakeLists.txt di primo livello potrebbe essere qualcosa del genere:

Quando si costruisce il target Rust come staticlib emette quali altre librerie devono essere collegate. Ho provato questo solo su Windows, quindi ws2_32, userenv e advapi32 sono collegati. Questo non sarà ovviamente cross-platform, ma puoi gestirlo abbastanza facilmente (ad esempio, impostare una variabile nell'elenco delle dipendenze appropriato per ogni piattaforma all'interno di un blocco if..else e aggiungerla alla chiamata target_link_libraries).

Si noti inoltre che ciò dipende dal fatto che Cargo è disponibile nel percorso.

Dovresti essere a posto ora. Il file "cpp/main.cpp" potrebbe contenere qualcosa come:

#include <cstdint> 
#include <iostream> 

extern "C" { 
    uint32_t add(uint32_t lhs, uint32_t rhs); 
} 

int main() { 
    std::cout << "1300 + 14 == " << add(1300, 14) << '\n'; 
    return 0; 
} 

Ecco un link ad un example project lavorare.

+0

Wow, che risposta completa. Grazie mille! – Daenyth

+0

Sì, non preoccuparti. Era una domanda interessante e volevo vedere come avrebbe funzionato :) – Fraser

+0

grazie, questo mi ha fatto risparmiare un sacco di tempo! –