Как я могу использовать созданную мной библиотеку без ошибок из источника, но не компилировать для моего собственного проекта?

Я бы хотел попробовать библиотеку 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 {
      |                    ^~~~

После некоторого исследования кода библиотеки, определение 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.

1 ответ

Решение

Вам не хватает ASMJIT_STATICОпределение времени компиляции - оно должно быть определено, если вы используете AsmJit статически. Это определение проверяется во время компиляции AsmJit для настройкиASMJIT_API макрос, который расширяется до атрибута импорта / экспорта / видимости, специфичного для компилятора.

В документации AsmJit (раздел "Инструкции по сборке") сказано [1]:

Проекты, которые используют AsmJit статически, должны определять ASMJIT_STATIC во всех модулях компиляции, которые используют AsmJit, иначе AsmJit будет использовать импорт динамических библиотек в декораторе ASMJIT_API. Рекомендуется определить этот макрос во всем проекте, который использует AsmJit таким образом.

Итак, в вашем конкретном случае это должно решить проблему:

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

ПРИМЕЧАНИЕ. Ссылка на документацию намеренно ведет на страницу индекса, чтобы она не стала мертвой после реорганизации документации.

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

Другие вопросы по тегам