如何使用我从源头构建的库而不出错,但又不能为自己的项目编译?

问题描述 投票:0回答:1

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

然后我想使用这个库编译我自己的程序,所以我检索了生成的文件(头文件和静态库),并将它们添加到一个新的项目中,其代码是复制了第一个在 图书馆网站:

// #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

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

这个程序很简单,我该如何编译呢?我也想知道为什么我做的事情没有成功,知道了这个错误的原因,我以后可能就可以处理其他相同风格的程序了。

PS:我在C和C++中管理外部依赖的经验不多。我是在Windows下,使用MinGW和上个版本的GCC。

c++ linker mingw asmjit
1个回答
1
投票

你缺少的是 ASMJIT_STATIC 编译时定义--如果你静态地使用AsmJit,就必须定义它。AsmJit会在编译时检查这个定义,以设置 ASMJIT_API 宏,它扩展为编译器特有的importexportvisibility属性。

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

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

所以在你的特殊情况下,这应该可以解决这个问题。

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

注意:文档链接特意链接到了索引页,所以一旦文档重组,它就不会成为一个死链接。

[1] https:/asmjit.comdocindex.html

© www.soinside.com 2019 - 2024. All rights reserved.