Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Demo or Example of utilizing 3rd party libs (via Conan ideally) #1129

Closed
EMCP opened this issue Nov 8, 2022 · 3 comments
Closed

Demo or Example of utilizing 3rd party libs (via Conan ideally) #1129

EMCP opened this issue Nov 8, 2022 · 3 comments

Comments

@EMCP
Copy link

EMCP commented Nov 8, 2022

I am brand new to rust.. coming from C++.. and I'd packaged a 3rd party library via conanrecipe.py ... I now want to switch from using that in C++ to Rust (via CXX I guess) .. My question is to confirm if I am going down the right way.. basically ConanRS provides some of the mechanism to pull in the conan package.. but now I need to learn how to reference those header files and .a / .so files in my rust C++ code..

based on some questions to conanrs Devolutions/conan-rs#11 .. I will read the build info metadata .. something like

build.rs


use std::path::Path;
use std::env;

use conan::*;

fn main() {
    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
    let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
    let conan_profile = format!("{}-{}", target_os, target_arch);

    let command = InstallCommandBuilder::new()
        .with_profile(&conan_profile)
        .build_policy(BuildPolicy::Missing)
        .recipe_path(Path::new("conanfile.txt"))
        .build();

    if let Some(build_info) = command.generate() {
        println!("using conan build info");
        build_info.cargo_emit();

        // Take the info and pipe it to CXX somehow

        let mycustomconanpkg = build_info.get_dependency('mycustomconanpkg')

        let mycustomconanpkg_dir = mycustomconanpkg.get_root_dir().unwrap();
        let mycustomconanpkg_lib_dir = mycustomconanpkg.get_library_dir().unwrap();
        let mycustomconanpkg_inc_dir = mycustomconanpkg.get_include_dir().unwrap();
        
 ....
    // IT IS HERE I will ADD the .h files from the conan package.. but what about the .so/.a files ? 

instructions - https://cxx.rs/build/cargo.html#header-include-paths

....    
       cxx_build::bridge("src/main.rs")
       .file("src/blobstore.cc")
       .flag_if_supported("-std=c++14")
       .compile("cxxbridge-demo");

       println!("cargo:rerun-if-changed=src/main.rs");
       println!("cargo:rerun-if-changed=src/blobstore.cc");
       println!("cargo:rerun-if-changed=include/blobstore.h");       
   }
}

I worry that even if I bring in the code via conan... I will still need to write a .cpp and .h file to reference those third parties AND bring in the Rust bits.. like I saw in here

https://github.com/dtolnay/cxx/blob/master/demo/include/blobstore.h#L2

and

https://github.com/dtolnay/cxx/blob/master/demo/src/blobstore.cc#L2

Am I going in the right direction in order to use conan based code in CXX ? it will need some bridge code which references the .h files from the mycustomconanpkg

@EMCP
Copy link
Author

EMCP commented Nov 8, 2022

I guess the main part of the docs I am after is this

https://cxx.rs/build/cargo.html#including-headers-from-dependencies

"You get to include headers from your dependencies, both handwritten ones contained as .h files in their Cargo package, as well as CXX-generated ones."

instead of my code being handwritten tho.. it's brought in from a 3rd party.. right? but I need to add those header paths still .. and reference them somehow

`#include "dependencycratename/path/to/their/header.h`` won't work since there is not "crate" in my case.. only conan.. right?

@EMCP
Copy link
Author

EMCP commented Nov 8, 2022

okay i can successfully reference things

Here's what I had to do

https://docs.rs/cxx-build/latest/cxx_build/static.CFG.html#cfgexported_header_dirs

build.rs

    if let Some(build_info) = command.generate() {
        println!("using conan build info");
        build_info.cargo_emit();

        let twsapi = build_info.get_dependency("twsapi").unwrap();
        let twsapi_inc_dir = twsapi.get_include_dir().unwrap();
        
        let twsapi_inc_dir_path = Path::new(twsapi_inc_dir);
        CFG.exported_header_dirs.extend([twsapi_inc_dir_path]);    <------- key line is here.. adding the include path

        cxx_build::bridge("src/main.rs")
            .file("src/blobstore.cc")
            .flag_if_supported("-std=c++17")
            .compile("cxxbridge-demo");
    }

then.. just to test in blobstore.cc , I can successfully build

#include "rust_twsapi_demo/include/blobstore.h"
#include "rust_twsapi_demo/src/main.rs.h"
#include <algorithm>
#include <functional>
#include <set>
#include <string>
#include <unordered_map>

#include "Contract.h"  <------ from the conan installed lib

@EMCP
Copy link
Author

EMCP commented Nov 8, 2022

My final question is.. how can I test or ensure that I've included not just the includes/ but the lib dir ?

image

EDIT : looks like I need to print out in the build something like

cargo:rustc-link-lib=<path_to_lib>

? I will give this a try and if it works close out

Looks like ConanRS took care of this already ! NICE!

...
[rust_twsapi_demo 0.1.0] conanfile.txt: Generated graphinfo
[rust_twsapi_demo 0.1.0] using conan build info
[rust_twsapi_demo 0.1.0] cargo:rustc-link-search=native=/home/emcp/.conan/data/twsapi/10.17.01/stonks/prod/package/062863c92a5a0a247840166e9f84ebe8d10786b9/lib
[rust_twsapi_demo 0.1.0] cargo:rustc-link-lib=twsapi

...

@EMCP EMCP closed this as completed Nov 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant