Rust CXX库链接,但未定义错误



我正在使用cxx编写一些c++代码,然后从rust中使用它。我还需要编译cppparser,因为我的c++代码使用它。然而,我得到未定义的错误,即使添加正确的链接库路径和正确的库被链接。用相同的-L-l编译的等效c++程序可以成功编译并运行。

我甚至在cxx链接和cargo链接中都添加了库路径和-l。我验证了build.rs中的路径dir存在,并且它有libcppparser.a

货物错误:

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

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++) {
// }
}

链接顺序是罪魁祸首。

使用extra-link-arg或rust -link-arg在末尾添加link命令。

最新更新