【问题标题】:How can I use the library that I have built without error from source, but not compiling for my own project?如何使用我从源代码构建的库而没有错误,但不能为我自己的项目编译?
【发布时间】:2020-06-06 14:49:12
【问题描述】:

我想试试AsmJit library。用'cmake'和'make'从源代码构建它是没有问题的,它提供的例子都被完美地编译和执行。我还做了make install 来导出依赖文件。

然后我想使用这个库编译我自己的程序,所以我检索了生成的文件(头文件和静态库)以将它们添加到一个新项目中,其代码是第一个示例的复制/粘贴library's website:

// #define ASMJIT_NO_DEPRECATED // this line is no part of the original code
#include <asmjit/asmjit.h>
#include <stdio.h>

using namespace asmjit;

// Signature of the generated function.
typedef int (*Func)(void);

int main(int argc, char* argv[]) {
  JitRuntime rt;                          // Runtime designed for JIT code execution.

  CodeHolder code;                        // Holds code and relocation information.
  code.init(rt.environment());            // Initialize CodeHolder to match JIT environment.

  x86::Assembler a(&code);                // Create and attach x86::Assembler to `code`.
  a.mov(x86::eax, 1);                     // Move one to 'eax' register.
  a.ret();                                // Return from function.
  // ----> x86::Assembler is no longer needed from here and can be destroyed <----

  Func fn;
  Error err = rt.add(&fn, &code);         // Add the generated code to the runtime.
  if (err) return 1;                      // Handle a possible error returned by AsmJit.
  // ----> CodeHolder is no longer needed from here and can be destroyed <----

  int result = fn();                      // Execute the generated code.
  printf("%d\n", result);                 // Print the resulting "1".

  // All classes use RAII, all resources will be released before `main()` returns,
  // the generated function can be, however, released explicitly if you intend to
  // reuse or keep the runtime alive, which you should in a production-ready code.
  rt.release(fn);

  return 0;
}

这是我的测试项目的层次结构:

include\
    asmjit\    // The generated headers from the library build
libasmjit.a    // The generated static library from the library build
main.cpp       // My program's code, as pasted above

这是用于编译的命令行:

g++ main.cpp -o main -Iinclude -L -lasmjit

出现第一个编译错误:

In file included from include/asmjit/./core.h:2008,
                 from include/asmjit/asmjit.h:27,
                 from main.cpp:1:
include/asmjit/././core/builder.h:375:20: error: function 'asmjit::Error asmjit::BaseBuilder::dump(asmjit::String&, uint32_t) const' definition is marked dllimport
  375 |   ASMJIT_API Error dump(String& sb, uint32_t formatFlags = 0) const noexcept {
      |                    ^~~~

在对 lib 代码进行一些研究后,定义 ASMJIT_NO_DEPRECATED 宏(参见上面代码中的第一行注释)可以防止此错误被重现。我怀疑这是一个好主意,因为它可能是导致以下下一个链接错误的原因:

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x35): undefined reference to `__imp__ZN6asmjit10JitRuntimeC1EPKNS_12JitAllocator12CreateParamsE'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x45): undefined reference to `__imp__ZN6asmjit10CodeHolderC1Ev'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x6e): undefined reference to `__imp__ZN6asmjit10CodeHolder4initERKNS_11EnvironmentEy'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x82): undefined reference to `__imp__ZN6asmjit3x869AssemblerC1EPNS_10CodeHolderE'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x11f): undefined reference to `__imp__ZN6asmjit3x869AssemblerD1Ev'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x12f): undefined reference to `__imp__ZN6asmjit10CodeHolderD1Ev'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x142): undefined reference to `__imp__ZN6asmjit10JitRuntimeD1Ev'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x159): undefined reference to `__imp__ZN6asmjit3x869AssemblerD1Ev'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x169): undefined reference to `__imp__ZN6asmjit10CodeHolderD1Ev'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text+0x17c): undefined reference to `__imp__ZN6asmjit10JitRuntimeD1Ev'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text$_ZN6asmjit11BaseEmitter4emitIJRKNS_3x862GpEiEEEjjDpOT_[_ZN6asmjit11BaseEmitter4emitIJRKNS_3x862GpEiEEEjjDpOT_]+0x4c): undefined reference to `__imp__ZN6asmjit11BaseEmitter6_emitIEjRKNS_8Operand_ES3_'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\<my user name>\AppData\Local\Temp\cc4WaQ7J.o:main.cpp:(.text$_ZN6asmjit11BaseEmitter4emitIJEEEjjDpOT_[_ZN6asmjit11BaseEmitter4emitIJEEEjjDpOT_]+0x1b): undefined reference to `__imp__ZN6asmjit11BaseEmitter6_emitIEj'
collect2.exe: error: ld returned 1 exit status

我找不到防止第一个错误发生的方法,除了定义这个宏,我也不明白为什么链接编辑器找不到引用。我也尝试将这些依赖项(头文件 + 静态库)放在适当的 MinGW 目录(即全局 include 和 lib 目录)中,但这并没有改变任何东西。

如何编译这个非常简单的程序?我也想知道为什么我做的没用,知道了这个错误的原因,我以后应该可以和其他同类型的人打交道了。

PS:我在管理 C 和 C++ 中的外部依赖项方面没有太多经验。我在 Windows 下,使用 MinGW 和最新版本的 GCC。

【问题讨论】:

  • 我已经修复了 MINGW 的编译时问题,谢谢!

标签: c++ linker mingw asmjit


【解决方案1】:

您缺少 ASMJIT_STATIC 编译时定义 - 如果您静态使用 AsmJit,则必须定义它。 AsmJit 在编译时检查此定义以设置 ASMJIT_API 宏,该宏扩展为特定于编译器的导入/导出/可见性属性。

AsmJit 文档(构建说明部分)说 [1]:

静态使用 AsmJit 的项目必须在所有使用 AsmJit 的编译单元中定义 ASMJIT_STATIC,否则 AsmJit 会在 ASMJIT_API 装饰器中使用动态库导入。建议以这种方式在使用 AsmJit 的整个项目中定义此宏。

因此,在您的特定情况下,这应该可以解决问题:

g++ main.cpp -o main -Iinclude -L. -lasmjit -DASMJIT_STATIC

注意:文档链接特意链接到索引页面,因此一旦重新组织文档,它就不会成为死链接。

[1]https://asmjit.com/doc/index.html

【讨论】:

  • 感谢您的回复!您提出的解决方案似乎只是“保留”用于构建库,而不是用于编译使用它的可执行文件。我已经使用ASMJIT_STATIC 参数构建了库,但我仍然尝试了您的解决方案,但不幸的是,在家里,问题仍然存在......
  • ASMJIT_STATIC 既适用于构建库,也适用于使用库。没有其他方法可以指定它应该是静态的还是共享的,或者应该导入还是导出。请参阅:github.com/asmjit/asmjit/blob/master/src/asmjit/core/… 搜索 ASMJIT_API 和 ASMJIT_STATIC
  • 也许 -L 参数不应该在那里,我已经在答案中修复了它。
  • 哦,确实,现在可以了!谢谢你帮我解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多