title: Rust CXX library linked, but undefined error
body: <p>I'm using <a href="https://github.com/dtolnay/cxx" rel="nofollow noreferrer">cxx</a> to write some C++ code, and then use this from rust. I also need to compile <a href="https://github.com/satya-das/cppparser" rel="nofollow noreferrer">cppparser</a>, 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 <code>-L</code> and <code>-l</code> compiles and runs successfully.</p>
  <p>I even added the library path and the -l in both the cxx link and cargo link. I verified that the path <code>dir</code> in <code>build.rs</code> exists, and that it has <code>libcppparser.a</code>.</p>
  <h3>Cargo error:</h3>
  <pre><code>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) -&gt; 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) -&gt; void {
  warning:       |                                                                                                  ~~~~^~~~~~~~~~~~
  warning: src/cpp/parser.cpp: In member function ‘void Parser::Includes(const rust::cxxbridge1::Vec&lt;rust::cxxbridge1::String&gt;&amp;) const’:
  warning: src/cpp/parser.cpp:22:54: warning: unused parameter ‘includes’ [-Wunused-parameter]
  warning:    22 | void Parser::Includes(const rust::Vec&lt;rust::String&gt; &amp;includes) const {
  warning:       |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
     Compiling cpp-rules v0.1.0 (/home/username/repos/cpp-rules)
  error: linking with `cc` failed: exit status: 1
    |
    = note: &quot;cc&quot; &quot;-m64&quot; &quot;/tmp/rustczOwWPb/symbols.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1008qgme4q63djgz.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1249j3tvn1y25h6c.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.17lpu485lvehx0px.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.18sg5hvxsxi6pzj4.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.192mislfobnjnpyj.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1aasme8g66am3cn8.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.1yf1mog17v68i1ch.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2h8bnaeygmd91fz.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2nhqs3w80eqh3h04.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2sgko118h55x5wnu.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.2usi4oxw7rhl83xt.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.39deh2s9d1oslum9.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3a2vyfdfu3o05n0b.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3chuhoxfcyrjnfs5.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3vdsuottgx76lux.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3x7pm18i5iancyih.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.3zjckvfkhuw6w51w.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.46jea8rhpbkmaem1.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.46ztdt6t0w1n8ro5.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.49strxboh6jnpvpp.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4dj9ib29i8lnop7s.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4epwar3ysc13p1mi.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4r6odqajxcsoapgy.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4t3u9ci2hd4c9z79.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.4zukduhgspn7a43v.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.54mc800jv73ic2b0.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.55jknfdhmopkzxuk.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.58n2rpv2ymsv73zf.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.cnwdplgl6pisy4n.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.d793tq8k7cnrp4t.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.fbyn2o0rf673t7c.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.g9e60hd8zoza2wk.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.o7y6d2bxts45eyr.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.tv9vyxerboqmv2j.rcgu.o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1.5epkm5t0llgu1q4q.rcgu.o&quot; &quot;-Wl,--as-needed&quot; &quot;-L&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps&quot; &quot;-L&quot; &quot;/home/username/repos/cpp-rules/target/debug/build/cpp-rules-7f41b8ce72eba842/out/build&quot; &quot;-L&quot; &quot;/home/username/repos/cpp-rules/target/debug/build/cpp-rules-7f41b8ce72eba842/out&quot; &quot;-L&quot; &quot;/home/username/repos/cpp-rules/target/debug/build/cxx-c0fec50dc6f39ebf/out&quot; &quot;-L&quot; &quot;/home/username/repos/cpp-rules/target/debug/build/link-cplusplus-7517e535596e121b/out&quot; &quot;-L&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib&quot; &quot;-Wl,-Bstatic&quot; &quot;-lcppparser&quot; &quot;-lcpp-rules&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/libcxx-ecdd82004ef2f5d0.rlib&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/liblink_cplusplus-22452e976b210b65.rlib&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/libanyhow-acde19e659b2b89e.rlib&quot; &quot;-Wl,--start-group&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-91db243dd05c003b.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-72269a4525d4f5cf.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-28d8f1c01a28b12d.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-5b78018a9f8ae4bc.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-f4160de9657f17b2.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-1cd8b958acdf2395.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-a4c4a7e7edfa8aea.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-061c02acc74ada37.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-2aed706f056a5dfb.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-1e1f90ff4bfdca6f.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-2d16c932daf0ad41.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-8f15fae89f489a33.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-81f3d85dace75e64.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-e071db8735f10456.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-6db7e05a8de4df10.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-7c03f666869e802a.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-2a6a2797f7a73818.rlib&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-0e3656b1fda5fd7b.rlib&quot; &quot;-Wl,--end-group&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-b09abe545ed38eb1.rlib&quot; &quot;-Wl,-Bdynamic&quot; &quot;-lstdc++&quot; &quot;-lgcc_s&quot; &quot;-lutil&quot; &quot;-lrt&quot; &quot;-lpthread&quot; &quot;-lm&quot; &quot;-ldl&quot; &quot;-lc&quot; &quot;-Wl,--eh-frame-hdr&quot; &quot;-Wl,-znoexecstack&quot; &quot;-L&quot; &quot;/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib&quot; &quot;-o&quot; &quot;/home/username/repos/cpp-rules/target/debug/deps/cpp_rules-fa9509d567369da1&quot; &quot;-Wl,--gc-sections&quot; &quot;-pie&quot; &quot;-Wl,-zrelro,-znow&quot; &quot;-nodefaultlibs&quot;
    = 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&lt;CppObjFactory, std::default_delete&lt;CppObjFactory&gt; &gt;)'
            /usr/bin/ld: /home/username/repos/cpp-rules/src/cpp/parser.cpp:14: undefined reference to `CppParser::setErrorHandler(std::function&lt;void (char const*, unsigned long, unsigned long, int)&gt;)'
            /usr/bin/ld: /home/username/repos/cpp-rules/src/cpp/parser.cpp:19: undefined reference to `CppParser::parseFile(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;)'
            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) -&gt; 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) -&gt; void {
  warning:       |                                                                                                  ~~~~^~~~~~~~~~~~
  warning: src/cpp/parser.cpp: In member function ‘void Parser::Includes(const rust::cxxbridge1::Vec&lt;rust::cxxbridge1::String&gt;&amp;) const’:
  warning: src/cpp/parser.cpp:22:54: warning: unused parameter ‘includes’ [-Wunused-parameter]
  warning:    22 | void Parser::Includes(const rust::Vec&lt;rust::String&gt; &amp;includes) const {
  warning:       |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
  
  error: could not compile `cpp-rules` due to previous error
  </code></pre>
  <h3>Directory structure of cpp-rules:</h3>
  <pre><code>├── 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
  </code></pre>
  <h3>build.rs</h3>
  <pre class="lang-rs prettyprint-override"><code>fn main() {
      let dir = cmake::Config::new(&quot;CppParser&quot;).build_target(&quot;cppparser&quot;).build();
      let dir = dir.join(&quot;build&quot;);
      let dir = dir.to_str().unwrap();
  
      println!(&quot;cargo:rustc-link-search={}&quot;, dir);
      println!(&quot;cargo:rustc-link-lib=static=cppparser&quot;);
  
      cxx_build::bridge(&quot;src/rules.rs&quot;)
          .include(&quot;CppParser/pub&quot;)
          .include(&quot;src/cpp&quot;)
          .file(&quot;src/cpp/parser.cpp&quot;)
          .flag(&quot;-std=c++17&quot;)
          .flag(&amp;format!(&quot;-L {}&quot;, dir))
          .flag(&quot;-lcppparser&quot;)
          .compile(&quot;cpp-rules&quot;);
  
      println!(&quot;cargo:rerun-if-changed=src/rules.rs&quot;);
      println!(&quot;cargo:rerun-if-changed=src/cpp/parser.cpp&quot;);
      println!(&quot;cargo:rerun-if-changed=src/cpp/parser.h&quot;);
  }
  </code></pre>
  <h3>rules.rs</h3>
  <pre><code>#[cxx::bridge]
  pub mod ffi {
      unsafe extern &quot;C++&quot; {
          include!(&quot;cpp-rules/src/cpp/parser.h&quot;);
  
          type Parser;
          fn new_parser(file: String) -&gt; UniquePtr&lt;Parser&gt;;
          fn Includes(&amp;self, includes: &amp;Vec&lt;String&gt;);
      }
  }
  </code></pre>
  <h3>main.rs</h3>
  <pre><code>mod rules;
  
  use anyhow::Result;
  
  fn main() -&gt; Result&lt;()&gt; {
      println!(&quot;Hello, world!&quot;);
  
      let parser = rules::ffi::new_parser(&quot;../hello-world.cpp&quot;.to_string());
      let mut includes: Vec&lt;String&gt; = Vec::new();
      parser.Includes(&amp;mut includes);
  
      println!(&quot;{:?}&quot;, includes);
  
      Ok(())
  }
  </code></pre>
  <h3>parser.h</h3>
  <pre><code>#pragma once
  
  #include &quot;rust/cxx.h&quot;
  #include &quot;../../CppParser/pub/cppparser.h&quot;
  
  #include &lt;memory&gt;
  #include &lt;vector&gt;
  
  typedef uint64_t u64;
  
  class Parser {
  public:
      Parser() = default;
      ~Parser() = default;
      Parser(rust::String file);
      void Includes(const rust::Vec&lt;rust::String&gt; &amp;includes) const;
  private:
      CppCompoundPtr ast;
      CppParser parser;
  };
  
  std::unique_ptr&lt;Parser&gt; new_parser(rust::String file);
  </code></pre>
  <h3>parser.cpp</h3>
  <pre><code>#include &quot;cpp-rules/src/rules.rs.h&quot;
  #include &quot;cpp-rules/src/cpp/parser.h&quot;
  #include &quot;../../CppParser/pub/cppparser.h&quot;
  
  #include &lt;iostream&gt;
  #include &lt;memory&gt;
  #include &lt;string&gt;
  
  std::unique_ptr&lt;Parser&gt; new_parser(rust::String file) {
      return std::make_unique&lt;Parser&gt;(file);
  }
  
  Parser::Parser(rust::String file) {
      parser.setErrorHandler([file](const char* errLineText, size_t lineNum, size_t errorStartPos, int lexerContext) -&gt; void {
          std::cout &lt;&lt; &quot;Could not parse: &quot; &lt;&lt; file &lt;&lt; &quot;. Error at: &quot; &lt;&lt; std::to_string(lineNum) &lt;&lt; &quot;\n&quot; &lt;&lt; errLineText &lt;&lt; std::endl;
          exit(-1);
      });
  
      ast = parser.parseFile(std::string(file));
  }
  
  void Parser::Includes(const rust::Vec&lt;rust::String&gt; &amp;includes) const {
      // auto members = ast-&gt;members();
      
      // u64 n = members.size();
      // for (u64 i = 0; i &lt; n; i++) {
  
      // }
  }
  </code></pre>