Giter VIP home page Giter VIP logo

rust-cpp's Introduction

rust-cpp - Embed C++ code directly in Rust

Documentation

Overview

rust-cpp is a build tool & macro which enables you to write C++ code inline in your rust code.

let name = std::ffi::CString::new("World").unwrap();
let name_ptr = name.as_ptr();
let r = unsafe {
    cpp!([name_ptr as "const char *"] -> u32 as "int32_t" {
        std::cout << "Hello, " << name_ptr << std::endl;
        return 42;
    })
};
assert_eq!(r, 42)

The crate also help to expose some C++ class to Rust by automatically implementing trait such as Drop, Clone (if the C++ type can be copied), and others

cpp_class!{
    #[derive(PartialEq)]
    unsafe struct MyClass as "std::unique_ptr<MyClass>"
}

Usage

For usage information and in-depth documentation, see the cpp crate module level documentation.

Differences with the cxx crate

This crate allows to write C++ code "inline" within your Rust functions, while with the cxx crate, you have to write a bit of boiler plate to have calls to functions declared in a different .cpp file.

Having C++ code inline might be helpful when trying to call to a C++ library and that one may wish to make plenty of call to small snippets. It can otherwise be fastidious to write and maintain the boiler plate for many small functions in different places.

These crate can also be used in together. The cxx crate offer some useful types such as CxxString that can also be used with this crate.

The cxx bridge does more type checking which can avoid some classes of errors. While this crate can only check for equal size and alignment.

rust-cpp's People

Contributors

ahmed-masud avatar aprilwade avatar curiousleo avatar efyang avatar fneddy avatar hunger avatar ian-h-chamberlain avatar inokawa avatar jeffvandyke avatar mystor avatar ogoffart avatar ratijas avatar richardeoin avatar rumblefrog avatar spacemaniac avatar sthiele avatar twistedfall avatar waywardmonkeys avatar wicast avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-cpp's Issues

member reference type '..... *const'

I really can't find a way how to solve it

I binding class

cpp_class!(pub unsafe struct IndexIVFFlat as "faiss::IndexIVFFlat");

let index = unsafe {
            cpp!([dimension as "int",index_size as "size_t",train_size as "size_t", trainvecs as "std::vector<float>"] ->  IndexIVFFlat as "faiss::IndexIVFFlat"{
                size_t nhash = 2;
                size_t nbits_subq = int (log2 (index_size+1) / 2);
                size_t ncentroids = 1 << (nhash * nbits_subq);
                faiss::MultiIndexQuantizer coarse_quantizer (dimension, nhash, nbits_subq);
                faiss::MetricType metric = faiss::METRIC_L2;
                // faiss::IndexIVFFlat *index = new faiss::IndexIVFFlat(&coarse_quantizer, dimension, ncentroids, metric);
                faiss::IndexIVFFlat index (&coarse_quantizer, dimension, ncentroids, metric);
                index.quantizer_trains_alone = true;
                index.verbose = true;
                index.nprobe = 2048;
                printf("1111111333333") ;
                index.train(train_size, trainvecs.data());
                return index ;
            })
        };

it 's run ok .

but when I split train method

 let index = unsafe {
            cpp!([dimension as "int",index_size as "size_t",train_size as "size_t", trainvecs as "std::vector<float>"] ->  IndexIVFFlat as "faiss::IndexIVFFlat"{
                size_t nhash = 2;
                size_t nbits_subq = int (log2 (index_size+1) / 2);
                size_t ncentroids = 1 << (nhash * nbits_subq);
                faiss::MultiIndexQuantizer coarse_quantizer (dimension, nhash, nbits_subq);
                faiss::MetricType metric = faiss::METRIC_L2;
                // faiss::IndexIVFFlat *index = new faiss::IndexIVFFlat(&coarse_quantizer, dimension, ncentroids, metric);
                faiss::IndexIVFFlat index (&coarse_quantizer, dimension, ncentroids, metric);
                index.quantizer_trains_alone = true;
                index.verbose = true;
                index.nprobe = 2048;
                return index ;
            })
        };

        unsafe {
            cpp!([index as "faiss::IndexIVFFlat", train_size as "size_t", trainvecs as "std::vector<float>"] ->  IndexIVFFlat as "faiss::IndexIVFFlat"{
                index.train(train_size, trainvecs.data());
            })
        }

it has err

cargo:warning=src/lib.rs:45:17: error: 'this' argument to member function 'train' has type 'const faiss::IndexIVFFlat', but function is not marked const
cargo:warning=                index.train(train_size, trainvecs.data());
cargo:warning=                ^~~~~
cargo:warning=/usr/local/include/faiss/IndexIVF.h:136:10: note: 'train' declared here
cargo:warning=    void train(idx_t n, const float* x) override;

so i take by this

let index: IndexIVFFlat = unsafe {
            cpp!([dimension as "int",index_size as "size_t",train_size as "size_t", trainvecs as "std::vector<float>"] ->  IndexIVFFlat as "faiss::IndexIVFFlat"{
                size_t nhash = 2;
                size_t nbits_subq = int (log2 (index_size+1) / 2);
                size_t ncentroids = 1 << (nhash * nbits_subq);
                faiss::MultiIndexQuantizer coarse_quantizer (dimension, nhash, nbits_subq);
                faiss::MetricType metric = faiss::METRIC_L2;
                // faiss::IndexIVFFlat *index = new faiss::IndexIVFFlat(&coarse_quantizer, dimension, ncentroids, metric);
                faiss::IndexIVFFlat index (&coarse_quantizer, dimension, ncentroids, metric);
                index.quantizer_trains_alone = true;
                index.verbose = true;
                index.nprobe = 2048;
                return index ;
            })
        };

        let index = &index;

        unsafe {
            cpp!([index as "faiss::IndexIVFFlat *", train_size as "size_t", trainvecs as "std::vector<float>"] ->  IndexIVFFlat as "faiss::IndexIVFFlat"{
                index -> train(train_size, trainvecs.data());
            });
        }

it has err:

running 1 test
Training level-1 quantizer
IVF quantizer trains alone...
error: test failed, to rerun pass '--lib'

Caused by:
  process didn't exit successfully: `/Users/xx/Documents/rustworkspace/rust-faiss/target/debug/deps/faiss4rs-c78b110c672d2238` (signal: 10, SIGBUS: access to undefined memory)

or let index = &mut index; the error same .

what should I do! thanks very much

Is it possible to use foreign types?

Is it, or will it be possible to use types from c++? I didn't find that in the documentation nor in the tests.
I'd like something like that:

#[macro_use]
extern crate cpp;

cpp!{{
    #include <glm/glm.hpp> 
}}

fn main() {
    let x = cpp![glm::vec3(1,0,0)];
}

Struct metadata not present in target library file

I'm building tflite 0.7.0 and I got this error:

  --> /rust/cargo/registry/src/github.com-1ecc6299db9ec823/tflite-0.7.0/src/interpreter/builder.rs:34:13
   |
34 | /             cpp!([handle as "InterpreterBuilder*"] {
35 | |                 delete handle;
36 | |             });
   | |_______________^
   |
   = help: message:
           -- rust-cpp fatal error --

           Struct metadata not present in target library file.
           NOTE: Double-check that the version of cpp_build and cpp_macros match
   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to previous error

I've included the generated files. I'm using g++, gcc, cc, and c++ versions 9.1.1 on a fedora docker image. Interestingly enough, this doesn't happen in the travis ci builds which is also on x86_64-unknown-linux-gnu or if I cross compile for aarch64-unknown-linux-gnu using the linaro 7.4.1-2019.02 toolchain.

rust_cpp.tar.gz

compile error

Just a friendly nudge to get it compiling again against nightly.
I'm curious to play with this.

build options

with version 0.2 it is not any more possible to pass the gcc config struct to the build process (#7). The structure is defined internally in the crate.

there should be an option to add an includepath to cpp_build::build.

Submodule skipping `mod.rs`, not found by `cpp_build`.

Consider:

src/main.rs:

mod foo;

fn main() {
    println!("Hello, world!");
}

src/foo.rs:

mod bar;

src/foo/bar/mod.rs (empty)

The above compiles with just cargo build. Now add

build.rs:

fn main() {
    let mut cfg = cpp_build::Config::new();
    cfg.build("src/main.rs");
}

This does not compile. I do not know the name of this feature in new Rust versions, but it should probably work.

error: failed to run custom build command for `cpp-build-modules v0.1.0 (/tmp/cpp-build-modules)`

Caused by:
  process didn't exit successfully: `/tmp/cpp-build-modules/target/debug/build/cpp-build-modules-015f8b4ab4e5a60a/build-script-build` (exit code: 101)
  --- stderr
  thread 'main' panicked at 'No file with module definition for `mod bar` in file "src/foo.rs"', /home/rsmet/.cargo/registry/src/github.com-1ecc6299db9ec823/cpp_build-0.5.5/src/parser.rs:643:9
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...
error: build failed

Edition 2018 support: macro imports

Rust 2018 brings Path Clarity.

The current crate example uses pre-"Path Clarity" syntax to import the cpp! macro: https://docs.rs/cpp/0.5.4/cpp/#librs.

Using the example without extern crate (as is the new default according to my understanding of the 2018 edition documentation) looks like this:

use cpp::{cpp, __cpp_internal, __cpp_internal_closure};

cpp!{{
    #include <iostream>
}}

fn main() {
    let name = std::ffi::CString::new("World").unwrap();
    let name_ptr = name.as_ptr();
    let r = unsafe {
        cpp!([name_ptr as "const char *"] -> u32 as "int32_t" {
            std::cout << "Hello, " << name_ptr << std::endl;
            return 42;
        })
    };
    assert_eq!(r, 42)
}

It works, but only when bringing the internal macros __cpp_internal and __cpp_internal_closure into scope.

Perhaps there is a way to structure the macros such that

use cpp::cpp;

is all that's need to use the cpp! macro in a 2018 edition Rust project?

compile error when changing code inside `cpp!` macro

Hi,
I get the following error when changing the code inside my cpp! macro:

error: This cpp! macro is not found in the library's rust-cpp metadata.
NOTE: Only cpp! macros found directly in the program source will be parsed -
NOTE: They cannot be generated by macro expansion.

Strangely I only get this when I change my code (no matter what I change) but the first time when I compile it it works fine. My current workaround is to delete the caches of my crate every time I change the contents inside a cpp macro.

I have no idea what causes this as I don't know macros that much but it seems to have something to do with caches.

Any help is highly appreciated.
Greetings, Benjamin

Segfault when adding destructor to class

This code

#[macro_use]
extern crate cpp;

cpp!{{
  #include <cstdio>
  #include <memory>

  using namespace std;

  class A {
   public:
    int x, y;
    A(): x(42), y(47) {}
    ~A() {
    }
  };
}}

#[repr(C)]
#[derive(Debug)]
pub struct A {
    pub _bindgen_opaque_blob: [u32; 2usize],
}

fn main() {
  loop {
    let x = unsafe {
      cpp!([] -> A as "A"  {
        return A();
      })
    };

    unsafe {
      cpp!([x as "A"] {
        printf("%d\n", x.x);
        printf("%d\n", x.y);
      })
    };
  }
}

Produces seqfault. However when destructor is not present code runs correctly without segfault.

embedding cpp! in other macros

The readme says that it is not possible to embed the cpp! macro in other macros. What is needed to make this possible?

class on free aborts on invalid pointer

Using the cpp_class! macro with a simple class aborts on freeing the resource. This is happening on Ubuntu 1804. Code snippet reproducing the issue:

use cpp::cpp;
use cpp::cpp_class;

cpp!{{
    #include <iostream>
    
    using std::string;

    class Test {
    public:
        Test() {
            std::cout << "creating" << std::endl;
        }
        virtual ~Test() {
            std::cout << "destroying" << std::endl;
        }

    protected:
        std::string message; // -> removing this and we don't get the issue
    };
}}

cpp_class!(pub unsafe struct Test as "Test");
impl Test {
    fn new() -> Self {
        unsafe { cpp!([] -> Test as "Test" { return Test(); }) }
    }
}

fn main() {
    let test = Test::new();
}

Error parsing when using nested modules

I tried to use nested modules

// lib.rs
mod foo {
    mod bar;
}
// foo/bar.rs
fn foo() {}

But it causes error:

warning: -- rust-cpp parse error --
warning: 
warning: There was an error parsing the crate for the rust-cpp build script:
warning: 
warning: Error while parsing `mod info` statement at lib.rs:2:4
warning: No file with module definition for `mod bar`
warning: 
warning: In order to provide a better error message, the build script will exit
warning: successfully, such that rustc can provide an error message.

It compiles with rustc successfully (well, ignoring linking errors due to missing symbols)

put "-l" "rust_cpp_generated" before other libraries

if I do this in build.rs:main

   let mut conf = cpp_build::Config::new();
   conf.flag("-lSomeLib");
   conf.build("src/main.rs");

sometimes the linker gets an error of the kind undefined reference.

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" ...
  ..."-l" "SomeLib" ... "-l" "rust_cpp_generated"
  = note: /home/fneddy/Projects/qpp/target/debug/build/qpp-f6ef9f4261aba55c/out/librust_cpp_generated.a(cpp_closures.o): In function `__cpp_closure_12982553034344175645':
  /home/fneddy/Projects/qpp/src/main.rs:18: undefined reference to `SomeLib::SomeLib()' 
   ...

if i then copy the complete cc command and put the "-l" "rust_cpp_generated" before the "-l" "SomeLib" there is no error.

is there a way to force the order of the linker instructions?

It's hard to link to staticly linked library

I get the undefined references when I'm accessing symbol from library during linking of print_sizes. As flags are passed before librust_cpp_generated archive they are not used.

Rust static variables as C++ non-type template parameter

Hello!

I'm trying to use a Rust static variable as a C++ non-type template parameter. Is this possible?

This is a simple example which outlines what I'm trying to do:

#[macro_use]
extern crate cpp;

cpp! {{
    #include <iostream>
    #include "src/tmp.h"
}}

static NUMBER: i32 = 42;

fn foo() {
    unsafe {
        cpp!([NUMBER as "int32_t"] {
            const int32_t replace_me_with_number = 3;
            std::cout << Add<replace_me_with_number>() << "   " << NUMBER << std::endl;
        })
    };
}

#[cfg(test)]
mod tests {
    use crate::foo;
    #[test]
    fn it_works() {
        foo();
    }
}

I'm trying to replace replace_me_with_number with NUMBER.

src/tmp.h is just:

template <int32_t N>
int Add()
{
    return N + 3;
}

Thank you for your help.

Linker option?

Hi, is there a way to specify custom linking options?

Metadata parsing assumes little endian, even for big endian targets

cpp_macros assumes little endian when parsing metadata, even when the target is big endian (for example, powerpc-unknown-linux-gnu). I'd write a PR, but I'm not sure how best to approach solving this. There doesn't seem to be a good way to discover the target from within a proc macro. Maybe it would be better to ensure the metadata is always stored little endian regardless of the platform?

Example of passing own class to Rust lambda

The following code (although I stripped a lot of details) fails to build with:

expected as',

cpp!(unsafe [myclass: const* std::ffi::c_void as "IMyClass*"]{
       myclass->CallMyMethod();
});

What is the correct way to pass my a pointer to an object from rust to c++ and calling a method on the object?

Invalid escape sequences in #line directives on Windows

On Windows, cpp_build generates the following #line directive inside cpp_closures.cpp:

#line 245 "C:\Users\vadimcn\.cargo\registry\src\github.com-1ecc6299db9ec823\cpp_build-0.5.1\src\lib.rs"

MSVC doesn't seem to mind, but when compiling for x86_64-pc-windows-gnu target, GCC produces a bunch of warnings and errors like these:
warning: unknown escape sequence: '\.'
error: incomplete universal character name \U

Use vis meta-variable is macros

Declarative macros like the one below could use the relatively new visibility aka :vis macro meta-variable instead of manual pub($tt*) etc. It had some issues in past, but now it's mostly fixed and safe to use.

rust-cpp/cpp/src/lib.rs

Lines 348 to 358 in 46c1f8d

macro_rules! cpp_class {
($(#[$($attrs:tt)*])* unsafe struct $name:ident as $type:expr) => {
$crate::__cpp_class_internal!{@parse [ $(#[$($attrs)*])* ] [] [unsafe struct $name as $type] }
};
($(#[$($attrs:tt)*])* pub unsafe struct $name:ident as $type:expr) => {
$crate::__cpp_class_internal!{@parse [ $(#[$($attrs)*])* ] [pub] [unsafe struct $name as $type] }
};
($(#[$($attrs:tt)*])* pub($($pub:tt)*) unsafe struct $name:ident as $type:expr) => {
$crate::__cpp_class_internal!{@parse [ $(#[$($attrs)*])* ] [pub($($pub)*)] [unsafe struct $name as $type] }
};
}

Upgrade syn version

Currently cpp_syn is a fork of an old version of syn. It does not support parsing newer rust construct.
If one use things such as impl Trait, there is just a warning saying it couldn't parse and nothing is generated.

Align and size assertion failures

cpp!{{
    #include <stdlib.h>
    #include <errno.h>
}}

fn as_cstr_ptr(str: &str) -> Result<*const u8> {

    let c_string: *const u8 = CString::new(str)?.as_bytes_with_nul().as_ptr();
    Ok(c_string)
}

pub fn set_env_variable(name: &str, value: &str, overwrite: i32) -> Result<i32> {
    let c_name_ptr = as_cstr_ptr(name)?;
    let c_value_ptr = as_cstr_ptr(value)?;
    let ret_val: i32 = cpp!(
        unsafe [
            c_name_ptr as "const char *",
            c_value_ptr as "const char *",
            overwrite as "int"
        ] -> i32 as "int"
        {
            return setenv(c_name_ptr, c_value_ptr, overwrite) != 0 ? errno : 0;
        }
    );
    match ret_val {
        0 => Ok(0),
        code => Err(StdlibError::from(code)),
    }
}

I have the above code snippet, where I am simply trying to call C++'s setenv method. For each of the argument passed to the macro, I see the assertion failure messages (from cpp_macros-0.5.5/src/lib.rs) of the following format.

"size_of for argument `{}` does not match between c++ and rust"
"align_of for argument `{}` does not match between c++ and rust"

Can some light be please shown on:

  • when/why these assertions fail?
  • how to fix them?
  • what is the impact of the size and alignment mismatch?

Structs are private only.

Structs in CPP macro are generated as private. Is it possible to make them somehow public to use them in interfaces and other modules? I do not want to rewrite data from structs defined in cpp into public defined in another place.

function is never used.

Hello. I am new to rust and want to start by playing with some cxx-rust bindings.

I followed the example from the document. The compile generated no executable binary with a warning:

warning: function is never used: `main`
  --> src/lib.rs:8:1
   |
8  | / fn main() {
9  | |     unsafe {
10 | |         cpp!([] {
11 | |             printf("Hello, World!\n");
12 | |         });
13 | |     }
14 | | }
   | |_^
   |
   = note: #[warn(dead_code)] on by default

Is this normal? Any help is appreciated.

cpp! macro with empty capture

Would it be possible to add support for using the cpp! macro without passing anything in from rust? For symmetry one might add support to the rust! macro to do the same. For example:

    cpp!(unsafe [ ] { std::cout << "Hello world!\n"; });
    let the_answer : i32 = cpp!(unsafe [ ] -> i32 as "int32_t" { return 42; });

cpp_class!() reverses lines of doc comments

Pretty much self explanatory. When documenting the following code, the lines of documentation are reversed (i.e. "This is line 2" appears before "This is line 1").

#[macro_use]
extern crate cpp;

cpp!{{
    class Test {
    };
}}

cpp_class!(
    /// This is line 1
    ///
    /// This is line 2
    pub unsafe struct Test as "Test");

Pkg-config combination?

This is probably another silly question. But is there any easy way to use the crate pkg_config to add include search path and link option? Thanks!

"No file with module definition"

Admittedly this is an odd case, but rust-cpp can't find a file that rustc can:

pub mod foo {
    pub mod bar;
}

No foo/mod.rs exists. rustc finds foo/bar.rs and compiles it, but rust-cpp claims "No file with module definition for mod bar".

Wrong ABI used for small C++ classes.

So if I generate C++ types using bindgen as described in rust-lang/rust-bindgen#778, and then try to create and return such types via cpp!, I hit the exact same problem as described in that bug.

This code crashes with a segmentation fault, because C++ compiler wants to return Bar by-pointer, whereas Rust expects it in registers.

let bar = cpp!([] -> Bar as "Bar" { return MakeBar(); });

In retrospect, this kinda makes sense, because even extern "C" functions in .cpp files must obey C++ ABI.

Not sure if cpp crate should attempt to fix this, but something to keep in mind if you decide to implement "foreign types" from #16.

Add an option for automatically handling exceptions

If the C++ code captured throws an exception, it might be nice to have an option for rust-cpp to add an exception handler which translates the exception into a rust panic.

This would have overhead so we may not want it to be the default.

error adding symbols: DSO missing from command line

I make and install faiss in system.

I compile by g++ is ok

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <cmath>
#include <cstdio>
#include <cstdlib>

#include <sys/time.h>

#include <faiss/IndexPQ.h>
#include <faiss/IndexIVFPQ.h>
#include <faiss/IndexFlat.h>
#include <faiss/index_io.h>

double elapsed()
{
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    return tv.tv_sec + tv.tv_usec * 1e-6;
}

int main()
{
    double t0 = elapsed();

    int d = 64;

    size_t nb = 1000 * 1000;
    size_t add_bs = 10000;

    size_t nt = 100 * 1000;

    size_t nhash = 2;
    size_t nbits_subq = 9;
    size_t ncentroids = 1 << (nhash * nbits_subq); // total # of centroids
    int bytes_per_code = 16;

    faiss::MultiIndexQuantizer coarse_quantizer(d, nhash, nbits_subq);
}

but use rust -cpp, has fail

warning:              ^~~~~~~~~~~~~~
   Compiling hello v0.1.0 (/home/ansj/rustworksapce/hello)
error: linking with `cc` failed: exit code: 1
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "............." "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: /usr/bin/ld: /home/ansj/rustworksapce/hello/target/debug/build/hello-64c7196ef49206ed/out/librust_cpp_generated.a(cpp_closures.o): undefined reference to symbol '__gxx_personality_v0@@CXXABI_1.3'
          //lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line
          collect2: error: ld returned 1 exit status
          

my code is"

build.rs

fn main() {
    println!("cargo:rustc-link-lib=faiss");
    cpp_build::Config::new()
        .cpp_link_stdlib(Some("faiss"))
        .build("src/lib.rs");
}

lib.rs

#![recursion_limit = "512"]
#![cfg_attr(not(test), allow(dead_code, unused_imports))]

#[macro_use]
extern crate cpp;

cpp! {{
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>

    #include <sys/time.h>

    #include <faiss/IndexPQ.h>
    #include <faiss/IndexIVFPQ.h>
    #include <faiss/IndexFlat.h>
    #include <faiss/index_io.h>

    double elapsed()
    {
        struct timeval tv;
        gettimeofday(&tv, nullptr);
        return tv.tv_sec + tv.tv_usec * 1e-6;
    }

    int bcd()
    {
        double t0 = elapsed();

        int d = 64;

        size_t nb = 1000 * 1000;
        size_t add_bs = 10000;

        size_t nt = 100 * 1000;

        size_t nhash = 2;
        size_t nbits_subq = 9;
        size_t ncentroids = 1 << (nhash * nbits_subq); // total # of centroids
        int bytes_per_code = 16;

        faiss::MultiIndexQuantizer coarse_quantizer(d, nhash, nbits_subq);

        return 0 ;
    }
}}

#[test]
fn captures() {
    unsafe {
        cpp! {[]{
            bcd();
        }}
    }
}

How to link to a library?

Has rust-cpp the ability to link an external library to my crate? I have tried to use the cpp_build::Config::new().flag("-ldill") but it shows the error:

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.100vd00syk7vz72u.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.10cnkbfd86hmmrmp.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.12a08da2prvdgxab.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.12x8c9sfcq7f0qgf.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.173e5ict49nyvgyl.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.17lmvj7qgmoogfs1.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.181vf42dusa8stsm.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.19lsjftm1vhtzuh3.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.19v57w03y19ig5kq.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.19wab1o9vo0xbg10.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1bvfba92jdwmx83v.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1e8rzpxazp2fgzz9.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1et1ccjzgd56po06.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1gbss055nmxrzhq0.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1gvinmox686bvi47.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1hen5ohut99udoiz.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1i03ah63jt0kh624.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1i64l2q2v66qtla0.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1jw0h51ilbhc7dwx.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1lw3essvrgljhvtd.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1qb1thx4ftx7mkxh.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1qo0dvfbpjorkc6n.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1r95ljiajg5yc6e.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1sbok6ksgavw4sy4.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1uj01zay9wtvlg2o.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1ur7g24ykqj63spm.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.1yeh45eq61viw0to.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.20vszhcpvb1lofqu.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.21cw1e58208vh1sr.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.21mm6k2iqjkkasfr.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.23xj3pt6hne1t3ib.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.25z4vf8tg5h5p174.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2bnyidmxpdl5vj4a.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2c1fz9405gszui2i.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2duc8zt2pbnht1cw.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2ek60q4dhh095cqd.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2eo69yxboqdgew8v.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2fd66decxbfhkime.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2j3ezuemyden8cz.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2jw5va4v4v0hq19f.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2k4l4jke2mr89emx.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2kosf0tnne7msmgu.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2mcpjj649n1b9i6a.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2mh88rip1d880rf9.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2oo54y7qqqmkj86r.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2p95hv1jgtaudy6y.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2qh552v8di9uj11b.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2s8yybmg4i1vtv92.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2sxeujeespr0fa9z.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2sxp216ouze3m383.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2t130967zcgam62j.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2vy70o6sni5ionzs.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2w0eyxq5w7fj0how.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2xl1xgwf7bxofc1z.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2z5mfmpyvsbyqskf.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.2z8dvgv5k325nb50.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.329m6darkd6hloe4.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.34anqwib1hcj4fzh.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.34o9p3i67gea5swx.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.34p5d38h78cprs22.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.39989j0i53e4uoz7.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3ba0plteo9t1f68e.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3bru6o9mg9fs2kh6.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3dewblxc94ztdicx.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3erh7ea8wtd5ngv7.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3f752dfryjlnbtiu.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3g4djdi7ppmyk5l7.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3hnhbfxb1uabmfnk.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3id7l73oo0nvld.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3j7ijv4u8s12w3y0.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3jhhuq3buzeuvgtb.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3jlt5duq33tv70nj.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3mg54840x5pqf7lv.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3mi20upbxruqcfgi.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3pa2bn25sjx0pbhf.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3svcp4ryk42us7yo.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3vfi78woq0ederf1.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3vhar7sb1m7occbx.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3wx8d6bmbfflev4z.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.3xv5tn3gntdmapnv.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.40yt4mq8sgi73248.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.42vwjwtpa1lgkt5l.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.435vxd3u525z56sg.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.45a259t3jsj5klti.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.460iojoo8z4i3sty.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.46jlozofz864o5d9.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.46vh3f42povv08nn.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.47nf3x0ionakfrmf.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.47osxk800oe2ylj0.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.47p367w2h1isbm7k.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.48sj633lnor7d0j0.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4bmqxmz4fn8p8gu1.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4c4mkqed328nyb80.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4f2hi1fwil1lqmzr.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4ie79ayzmipnuinf.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4mbohoiy4qegsvbg.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4ow4iyjroik3wtod.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4t8hzil5769y4yef.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4tfa0mkxk9xar3ig.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4tltrijgrzd3jqt2.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4tu89lgom26yetwi.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4v9bzszbna8d37g2.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4vdj95829seqleib.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4wx1frhj8n1kqo13.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4x3o7otvubuqjgji.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4x9ltk67up950xwb.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4xehx0sm6stlabuz.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4y21cmwh9txk0o33.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4yiv8gud6qesmw9q.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4ytq7g10b6dk2fi7.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.52f10oh5xwk4c44b.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.52se8xdu9qsjae0b.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.53kotxrayybe2ubf.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.54wf6v6ma465ipqr.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.569cg9htuuefmbdy.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.59l3ax8bg3cmmbhs.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.5aobamkhwvlere86.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.5eu3szhopyk3p9oe.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.5go0xr38fnnu9sy8.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.5xl6f6z4expcw9e.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.9vq0acx042xg2xn.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.a85gt05ef9772ec.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.cu4xjcysn4entpg.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.f3cmtm66u83s1cf.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.fa0zhdb4ivtyzxb.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.gd8c8jvn1e0sfq5.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.ij49it1k0rfjw6p.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.k47ft01imglsqpc.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.mgppb0rbdqv82c3.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.oa3ov6yfiiw4wpq.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.ojrfkfyltwh9i2x.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.q0p91hau2ofbw1q.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.r1lmf8qs281449k.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.r33azch0zmq6bhu.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.s1ii5e8fx12spq1.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.xcel61i8wp3g7yz.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.y8gwxgkzkw37v6e.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.ygpub9hot674qsm.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.ykehiiew75su1ed.rcgu.o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.z5i68hfjcje61lk.rcgu.o" "-o" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/finshir-72f131c2dd577466.4cm9892kxql1y3um.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-nodefaultlibs" "-L" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps" "-L" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/build/finshir-aeb8b6a0e9c1678d/out" "-L" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/build/openssl-sys-0745e1222b6011a0/out/openssl-build/install/lib" "-L" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/build/backtrace-sys-f642c8646dde8085/out" "-L" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-Wl,--whole-archive" "-lrust_cpp_generated" "-Wl,--no-whole-archive" "-Wl,-Bdynamic" "-lstdc++" "-Wl,-Bstatic" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libopenssl_probe-1cd22d529a10d8f7.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libsignal_hook-448b7f207346146e.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libsignal_hook_registry-564f71c545c106bb.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libarc_swap-0151fc64d5e9a7fd.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libfern-de93e2f9cc2f884f.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcolored-e084efca31f13926.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libopenssl-d4535373564d7c00.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libopenssl_sys-bc2814d5da5e324f.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libforeign_types-a05b3037ed1ee4e1.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libforeign_types_shared-87acc723aed1c931.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libtreexml-f9c76e2daafc969e.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libxml-451053442e404c50.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libfailure-56dcce512c15de11.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libbacktrace-d8481685f5a45308.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libbacktrace_sys-6ae7ddef12c7298d.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/librustc_demangle-a7786c66ab8ed9e9.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libserde_json-e7d61c77b20533b9.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libryu-da64da8296bb6442.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libitoa-32863750dca8e244.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libserde-0be31dd8e4c93365.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libhumantime-e75c6bfcf19fe156.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libquick_error-4bd432958a8dc66a.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libtermion-0dcf1f4795bf8329.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libnumtoa-14ae2a1d4edccb9b.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libstructopt-0ac448ef8b47a0a2.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libclap-8b0cd6065b92aee1.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libvec_map-3b09ec8813babab9.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libtextwrap-26e4934676a7f359.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libunicode_width-7e16e850b3823bed.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libstrsim-86f2147467cd2770.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libatty-009946653125a597.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libansi_term-9230cfe64103a329.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libmay-85b7ff42c5eb11bf.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libtime-8eda3918a9797dd7.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libnix-e1f683a2dd57b644.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libvoid-c8c8bb84b60bd4ad.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libbitflags-0a8e9d4123a6ba11.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libnum_cpus-f867add9d529b9f5.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libmay_queue-efef535e97c351ff.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libgenerator-2d34a8c1ee9663f1.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcrossbeam-3c2462ddc22c79fb.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcrossbeam_queue-e46df1093f704320.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcrossbeam_channel-bbefbc0087731c43.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libsmallvec-b5613738fb45ca09.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcrossbeam_deque-c0391ff125bc377b.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcrossbeam_epoch-3332fb5882fc9ac1.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libscopeguard-021b2ea9c72534b4.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libmemoffset-eaa243ce0c36f771.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcrossbeam_utils-fd93ee3e5ccc1fd8.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libarrayvec-0266c6026a911fe7.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libsocket2-c7520f9af69a0de8.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/liblibc-1b62639833d9c18b.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/liblog-f6bd7e615abeb82f.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcfg_if-c366de3e576306b9.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/liblazy_static-5e8dc2c1c71d152e.rlib" "/media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/deps/libcpp-c46fea44e38d7697.rlib" "-Wl,--start-group" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4224452e66d7414a.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-0cc41ea7c40927b6.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace-32e3f189d050061d.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libbacktrace_sys-8385e56c4bafa6df.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-20b9ee265c16a97c.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-3160820f42c2f7ac.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-4d153b6897dd19a9.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-7c0d9cd0bf2400c7.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-a3caf32fe0c2a9d5.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-747fc48f6cc5ac91.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-8a35e7aa4784dec7.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-6fba134f11895b63.rlib" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-7fcddcee75803bfc.rlib" "-Wl,--end-group" "/home/gymmasssorla/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-1480170ea2fd9d2d.rlib" "-Wl,-Bdynamic" "-lutil" "-lutil" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
  = note: /media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/target/debug/build/finshir-aeb8b6a0e9c1678d/out/librust_cpp_generated.a(cpp_closures.o): In function `__cpp_closure_9390303107642135815':
          /media/gymmasssorla/772CF8924BEBB279/Documents/rust/finshir/src/main.rs:47: undefined reference to `dill_bundle'
          collect2: error: ld returned 1 exit status

New release

Hey @ogoffart ! I'd like to publish a crate that requires the changes from #78.

Would you consider publishing a new version of rust-cpp on crates.io to make this easier?

Rusty Cheddar Integration

Is it possible to do something like this?

#[no_mangle]
pub extern "C" fn callback() {
    println!("Called from C");
}

cpp! {
    raw {
        void function() {
            callback();
        }
    }
}

Allow annotating Rust types in cpp! macro (or just allow arbitrary expressions)

I'm noticing that 99% of my errors are type errors during calling cpp! macro:

// Handle
struct Wrap {
    ptr: ::libc::c_void
}
pub fn test(wrap: &mut Wrap) {
    cpp!([wrap as "Wrap *"] {
        wrap->test();
    });
}

This compiles but segfaults. Correct way is:

// Handle
struct Wrap {
    ptr: ::libc::c_void
}
pub fn test(wrap: &mut Wrap) {
    let wrap_ptr = wrap.ptr;
    cpp!([wrap_ptr as "Wrap *"] {
        wrap_ptr->test();
    });
}

My code is littered with _ptr variables and other casting. It might be nice to have following syntax:

// Handle
struct Wrap {
    ptr: ::libc::c_void
}
pub fn test(wrap: &mut Wrap) {
    cpp!([(wrap.ptr  as ::libc::c_void) as "Wrap *"] {
        wrap->test();
    });
}

Thus avoiding temporary variables and making code more type safe (if we type by accident wrap : ::libc::c_void it will cause type error. Note that mutability should still work, only with slightly different syntax:

let y: i32 = 10;
let mut z: i32 = 20;
let x: i32 = cpp!([y as "int32_t", &mut z as "int32_t &"] -> i32 as "int32_t" {
    z++;
    return y + z;
});

Rust 2015 edition support

In the current state, this crate works with Rust 2015 only under a specific conditions: explicit extern crate core; must be added to the top of the project's main file โ€” otherwise compiler gives a lot of weird warnings per square inch of code. This is required because PR #78 introduced ::core paths instead of ::std paths for better compatibility with #[no_std]. More on topic here: https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html.

This conflict should be either a documented 'feature', or somehow mitigated via code.

cpp_synmap support for parsing source files from include! macro calls

In theory this would just be a case of Walker detecting include macro calls in its Folder implementation. Initially it could be limited to handling includes of the form

include!(concat!(env!("OUT_DIR"), "/path/to/source/file.rs"));

The main benefit of this is so that files generated from build scripts can contain macros like cpp!. I'm also relying on cpp_synmap for embed_js, so this would be of use for the js! and include_js! macros as well.

Failed to compile

I am trying to build my library which uses cpp.

src/build.rs:

fn main() {
    cpp_build::build("src/lib.rs");
}

src/lib.rs:

#[macro_use]
extern crate cpp;

cpp! {{
	#include <stdio.h>
}}

fn foo() {
	cpp!([] {
		printf("Hello, World!\n");
	});
}

After that I executed cargo build, and received the error:

error: proc-macro derive panicked
  --> src/lib.rs:9:2
   |
9  |       cpp!([] {
   |  _____^
10 | |         printf("Hello, World!\n");
11 | |     });
   | |_______^
   |
   = help: message: 
           -- rust-cpp fatal error --
           
           The OUT_DIR environment variable was not set.
           NOTE: rustc must be run by Cargo.: NotPresent
   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to previous error

error: Could not compile `cpp`.

To learn more, run the command again with --verbose.

How to fix it? Also note that if I have a binary project, no errors are displayed.

duplicate typeinfo for templates

So this is an issue I am facing. I'm wrapping quite a complex library that contains an std::vector like template class. The template is instantiated internally in the library but also externally in my wrapper (using cpp crate). The situation I am in, is that the type_info objects are independent, a dynamic cast on the template instantiation from my internal type will fail inside the library being wrapped.

I'm not 100% how to solve this, but I'm thinking along the lines of.
Declare the template instantiation as external and then rely on the third party library to provide it. Unfortunately when I try this it seems the cpp crate fails to build as I get symbol missing errors when the static library of my c++ code is built.

I don't suppose you have any suggestions on how I could resolve this? I'm pretty stumped now for how to work around this issue. So any ideas you have would be really appreciated.

Thanks again!

Add option to cpp_class! macro for std::marker::PhantomPinned

C++ allows the use of self-referential structures by convention; Rust does not. Using cpp_class! to wrap a class that is not trivially relocatable is unsafe because Rust might move the object and break internal references. Unfortunately this precludes the use of cpp_class! for most of the standard library.

Rust now supports the concept of pinning, or preventing an object from being moved/relocated in memory. With the pinning API it is now possible to do:

#![feature(optin_builtin_traits)]
cpp_class!(pub unsafe struct CppString as "std::string");
impl !Unpin for CppString {} // requires optin_builtin_traits
impl CppString {
	pub fn new_box() -> std::pin::Pin<std::boxed::Box<CppString>> {
		// allocate memory
		let mut memory = std::boxed::Box::pin(std::mem::MaybeUninit::<CppString>::uninit());
		
		// get address of allocated memory
		let address : *mut CppString =  unsafe { memory.as_mut().get_unchecked_mut() }.as_mut_ptr();
		
		// use placement new to construct a new string at the address
		cpp!(unsafe [address as "void*"] {
			new (address) std::string(cstring_ptr);
		}
		
		// unwrap the MaybeUninit
		unsafe { std::mem::transmute::<std::pin::Pin<std::boxed::Box<std::mem::MaybeUninit::<CppString>>>, std::pin::Pin<std::boxed::Box<CppString>>>(memory) }
	}
}

The only problem is Rust does not know that struct CppString is not relocatable and will happily move it out of the Pin<>. We must tell Rust that CppString is not Unpin, which is achieved in the example above using the nightly feature impl !Unpin for CppString {}. Unfortunately this means the above code doesn't compile with stable Rust.

It is possible to achieve the same effect with stable Rust using the marker type PhantonPinned, which implements !Unpin and thereby makes any structure containing it also !Unpin. This would conceptually be used to make a structure MyStruct implement !Unpin like this. Of note, the presence of phantom types does not increase the size of the structure, affect is alignment, or have any performance drawbacks.

struct MyStruct {
	my_data: i32, // or whatever type we want
	_phantom_pinned: std::marker::PhantomPinned
}

It would seem that to do this for C++ classes would require modification of the cpp_class! macro. I confess I have yet to learn much macro programming and had some trouble following all the macro_rules! and downstream parsing functions for the cpp_class! macro, so I do apologize that this is not a pull request. Some ways this could possibly look:

// Option 1
cpp_class!(pub unsafe !Unpin struct CppString as "std::string");

// Option 2
struct CppString {
	cpp_class_data!(pub unsafe struct CppString as "std::string"),
	_phantom_pinned: std::marker::PhantomPinned
}

// Option 3: Automatically detect if C++ class is relocatable?

LexError on vertical tab \v

Parsing some C++ that uses '\v' I get the following error.

warning: -- rust-cpp parse error --
warning: There was an error parsing the crate for the rust-cpp build script:
warning: Parsing crate:``:
warning: Error("LexError")
warning: In order to provide a better error message, the build script will exit successfully, such that rustc can provide an error message.
error: unknown character escape: v
  --> src/lib.rs:60:27
   |
60 |     static const char = '\v';
   |                           ^ unknown character escape

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.