3

I'm using cxx to write some C++ code, and then use this from rust. I also need to compile cppparser, since my C++ code uses it. However I get undefined errors even after adding the correct link library path and the correct library to be linked. An equivalent C++ only program compiled with the same -L and -l compiles and runs successfully.

I even added the library path and the -l in both the cxx link and cargo link. I verified that the path dir in build.rs exists, and that it has libcppparser.a.

Cargo error:

warning: src/cpp/parser.cpp: In lambda function:
warning: src/cpp/parser.cpp:14:83: warning: unused parameter ‘errorStartPos’ [-Wunused-parameter]
warning:    14 |     parser.setErrorHandler([file](const char* errLineText, size_t lineNum, size_t errorStartPos, int lexerContext) -> void {
warning:       |                                                                            ~~~~~~~^~~~~~~~~~~~~
warning: src/cpp/parser.cpp:14:102: warning: unused parameter ‘lexerContext’ [-Wunused-parameter]
warning:    14 |     parser.setErrorHandler([file](const char* errLineText, size_t lineNum, size_t errorStartPos, int lexerContext) -> void {
warning:       |                                                                                                  ~~~~^~~~~~~~~~~~
warning: src/cpp/parser.cpp: In member function ‘void Parser::Includes(const rust::cxxbridge1::Vec<rust::cxxbridge1::String>&) const’:
warning: src/cpp/parser.cpp:22:54: warning: unused parameter ‘includes’ [-Wunused-parameter]
warning:    22 | void Parser::Includes(const rust::Vec<rust::String> &includes) const {
warning:       |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
   Compiling cpp-rules v0.1.0 (/home/username/repos/cpp-rules)
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" "/tmp/rustczOwWPb/symbols.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1008qgme4q63djgz.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1249j3tvn1y25h6c.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.17lpu485lvehx0px.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.18sg5hvxsxi6pzj4.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.192mislfobnjnpyj.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1aasme8g66am3cn8.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1yf1mog17v68i1ch.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2h8bnaeygmd91fz.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2nhqs3w80eqh3h04.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2sgko118h55x5wnu.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2usi4oxw7rhl83xt.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.39deh2s9d1oslum9.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3a2vyfdfu3o05n0b.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3chuhoxfcyrjnfs5.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3vdsuottgx76lux.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3x7pm18i5iancyih.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3zjckvfkhuw6w51w.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.46jea8rhpbkmaem1.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.46ztdt6t0w1n8ro5.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.49strxboh6jnpvpp.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4dj9ib29i8lnop7s.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4epwar3ysc13p1mi.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4r6odqajxcsoapgy.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4t3u9ci2hd4c9z79.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4zukduhgspn7a43v.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.54mc800jv73ic2b0.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.55jknfdhmopkzxuk.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.58n2rpv2ymsv73zf.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.cnwdplgl6pisy4n.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.d793tq8k7cnrp4t.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.fbyn2o0rf673t7c.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.g9e60hd8zoza2wk.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.o7y6d2bxts45eyr.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.tv9vyxerboqmv2j.rcgu.o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.5epkm5t0llgu1q4q.rcgu.o" "-Wl,--as-needed" "-L" "/home/username/repos/cpp-rules/target/debug/deps" "-L" "/home/username/repos/cpp-rules/target/debug/build/cpp-rules-7f41b8ce72eba842/out/build" "-L" "/home/username/repos/cpp-rules/target/debug/build/cpp-rules-7f41b8ce72eba842/out" "-L" "/home/username/repos/cpp-rules/target/debug/build/cxx-c0fec50dc6f39ebf/out" "-L" "/home/username/repos/cpp-rules/target/debug/build/link-cplusplus-7517e535596e121b/out" "-L" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "-lcppparser" "-lcpp-rules" "/home/username/repos/cpp-rules/target/debug/deps/libcxx-ecdd82004ef2f5d0.rlib" "/home/username/repos/cpp-rules/target/debug/deps/liblink_cplusplus-22452e976b210b65.rlib" "/home/username/repos/cpp-rules/target/debug/deps/libanyhow-acde19e659b2b89e.rlib" "-Wl,--start-group" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-91db243dd05c003b.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-72269a4525d4f5cf.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-28d8f1c01a28b12d.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-5b78018a9f8ae4bc.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-f4160de9657f17b2.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-1cd8b958acdf2395.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-a4c4a7e7edfa8aea.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-061c02acc74ada37.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-2aed706f056a5dfb.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-1e1f90ff4bfdca6f.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-2d16c932daf0ad41.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-8f15fae89f489a33.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-81f3d85dace75e64.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-e071db8735f10456.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-6db7e05a8de4df10.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-7c03f666869e802a.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-2a6a2797f7a73818.rlib" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-0e3656b1fda5fd7b.rlib" "-Wl,--end-group" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-b09abe545ed38eb1.rlib" "-Wl,-Bdynamic" "-lstdc++" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
  = note: /usr/bin/ld: /home/username/repos/cpp-rules/target/debug/build/cpp-rules-7f41b8ce72eba842/out/libcpp-rules.a(parser.o): in function `Parser::Parser(rust::cxxbridge1::String)':
          /home/username/repos/cpp-rules/src/cpp/parser.cpp:13: undefined reference to `CppParser::CppParser(std::unique_ptr<CppObjFactory, std::default_delete<CppObjFactory> >)'
          /usr/bin/ld: /home/username/repos/cpp-rules/src/cpp/parser.cpp:14: undefined reference to `CppParser::setErrorHandler(std::function<void (char const*, unsigned long, unsigned long, int)>)'
          /usr/bin/ld: /home/username/repos/cpp-rules/src/cpp/parser.cpp:19: undefined reference to `CppParser::parseFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
          collect2: error: ld returned 1 exit status

  = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

The following warnings were emitted during compilation:

warning: src/cpp/parser.cpp: In lambda function:
warning: src/cpp/parser.cpp:14:83: warning: unused parameter ‘errorStartPos’ [-Wunused-parameter]
warning:    14 |     parser.setErrorHandler([file](const char* errLineText, size_t lineNum, size_t errorStartPos, int lexerContext) -> void {
warning:       |                                                                            ~~~~~~~^~~~~~~~~~~~~
warning: src/cpp/parser.cpp:14:102: warning: unused parameter ‘lexerContext’ [-Wunused-parameter]
warning:    14 |     parser.setErrorHandler([file](const char* errLineText, size_t lineNum, size_t errorStartPos, int lexerContext) -> void {
warning:       |                                                                                                  ~~~~^~~~~~~~~~~~
warning: src/cpp/parser.cpp: In member function ‘void Parser::Includes(const rust::cxxbridge1::Vec<rust::cxxbridge1::String>&) const’:
warning: src/cpp/parser.cpp:22:54: warning: unused parameter ‘includes’ [-Wunused-parameter]
warning:    22 | void Parser::Includes(const rust::Vec<rust::String> &includes) const {
warning:       |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~

error: could not compile `cpp-rules` due to previous error

Directory structure of cpp-rules:

├── build.rs
├── Cargo.toml
├── common https://github.com/satya-das/common
├── CppParser https://github.com/satya-das/cppparser
├── src
│   ├── cpp
│   │   ├── parser.cpp
│   │   ├── parser.h
│   ├── main.rs
│   └── rules.rs

build.rs

fn main() {
    let dir = cmake::Config::new("CppParser").build_target("cppparser").build();
    let dir = dir.join("build");
    let dir = dir.to_str().unwrap();

    println!("cargo:rustc-link-search={}", dir);
    println!("cargo:rustc-link-lib=static=cppparser");

    cxx_build::bridge("src/rules.rs")
        .include("CppParser/pub")
        .include("src/cpp")
        .file("src/cpp/parser.cpp")
        .flag("-std=c++17")
        .flag(&format!("-L {}", dir))
        .flag("-lcppparser")
        .compile("cpp-rules");

    println!("cargo:rerun-if-changed=src/rules.rs");
    println!("cargo:rerun-if-changed=src/cpp/parser.cpp");
    println!("cargo:rerun-if-changed=src/cpp/parser.h");
}

rules.rs

#[cxx::bridge]
pub mod ffi {
    unsafe extern "C++" {
        include!("cpp-rules/src/cpp/parser.h");

        type Parser;
        fn new_parser(file: String) -> UniquePtr<Parser>;
        fn Includes(&self, includes: &Vec<String>);
    }
}

main.rs

mod rules;

use anyhow::Result;

fn main() -> Result<()> {
    println!("Hello, world!");

    let parser = rules::ffi::new_parser("../hello-world.cpp".to_string());
    let mut includes: Vec<String> = Vec::new();
    parser.Includes(&mut includes);

    println!("{:?}", includes);

    Ok(())
}

parser.h

#pragma once

#include "rust/cxx.h"
#include "../../CppParser/pub/cppparser.h"

#include <memory>
#include <vector>

typedef uint64_t u64;

class Parser {
public:
    Parser() = default;
    ~Parser() = default;
    Parser(rust::String file);
    void Includes(const rust::Vec<rust::String> &includes) const;
private:
    CppCompoundPtr ast;
    CppParser parser;
};

std::unique_ptr<Parser> new_parser(rust::String file);

parser.cpp

#include "cpp-rules/src/rules.rs.h"
#include "cpp-rules/src/cpp/parser.h"
#include "../../CppParser/pub/cppparser.h"

#include <iostream>
#include <memory>
#include <string>

std::unique_ptr<Parser> new_parser(rust::String file) {
    return std::make_unique<Parser>(file);
}

Parser::Parser(rust::String file) {
    parser.setErrorHandler([file](const char* errLineText, size_t lineNum, size_t errorStartPos, int lexerContext) -> void {
        std::cout << "Could not parse: " << file << ". Error at: " << std::to_string(lineNum) << "\n" << errLineText << std::endl;
        exit(-1);
    });

    ast = parser.parseFile(std::string(file));
}

void Parser::Includes(const rust::Vec<rust::String> &includes) const {
    // auto members = ast->members();
    
    // u64 n = members.size();
    // for (u64 i = 0; i < n; i++) {

    // }
}
2
  • 32 bit vs 64 bit library conflict? (just a total guess) Commented Jun 8, 2022 at 12:34
  • @john nope, just checked, my compiled c++ and cppparser libs are 64 bit :( Commented Jun 8, 2022 at 14:01

1 Answer 1

2

Linking order was the culprit.

Use extra-link-arg or rustc-link-arg to add link command at the end.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.