Я ищу способ скомпилировать статическую библиотеку для Windows в Linux или Macos, кажется, есть кросс-компилятор для создания библиотеки .a для Windows, например этот, но это не то, что мне нужно, мне нужен файл статической библиотеки .lib для Windows, предпочтительно для Visual Studio. Я знаю, что могу запустить виртуальную машину Windows и использовать Visual Studio, но это слишком тяжело и не может быть сделано в командной строке.
Как скомпилировать статическую библиотеку .lib для Windows в Linux или Macos
Ответы:
Для Unix-подобных ОС (Linux, MacOS и т. д.) статическая библиотека означает ar
архив объектных файлов. ar
— архиватор общего назначения GNU. Неважно, какие файлы вы засунете в архив. Просто принято называть это «статической библиотекой», когда они являются объектными файлами. А еще просто принято, чтобы ar
архив назывался *.a
. Вы можете назвать это *.lib
или как угодно.
Для Visual Studio под статической библиотекой понимается архив объектных файлов PE-формата, обычно создаваемый инструментом Microsoft LIB
.
Формат архива Microsoft LIB фактически такой же, как у архива Unix ar
. Microsoft только что приняла его, давным-давно.
Поэтому, если вы скомпилируете несколько объектных файлов PE в Linux с помощью кросс-компилятора PE вашего дистрибутива, а затем заархивируете их в *.lib
с ar
, вы получите статическую библиотеку, которую можно использовать в Windows с компилятором Visual Studio.
Ну, у вас есть, пока эти объектные файлы имеют двоичные интерфейсы C. Если у кого-то из них есть интерфейсы C++, они бесполезны: компиляторы Microsoft и GCC C++ используют разные протоколы изменения имен и в остальном несовместимы с ABI.
Демо
Мы начинаем в Linux с некоторым исходным кодом для статической библиотеки:
привет.c
#include <stdio.h>
void hello(void)
{
puts("Hello world");
}
Кросс-компиляция:
$ x86_64-w64-mingw32-gcc-win32 -o hello.obj -c hello.c
Сделайте статическую библиотеку:
$ ar rcs hello.lib hello.obj
Затем программа, которая будет связана с hello.lib
:
main.c
extern void hello(void);
int main(void)
{
hello();
return 0;
}
Теперь мы прыгаем в виртуальную машину Windows 10, где мы смотрим на файлы, которые мы только что создали в общей папке:
E:\develop\so\xstatlib>dir
Volume in drive E is VBOX_imk
Volume Serial Number is 0000-0804
Directory of E:\develop\so\xstatlib
03/12/2017 18:37 72 main.c
03/12/2017 18:29 978 hello.lib
03/12/2017 18:26 66 hello.c
03/12/2017 18:27 832 hello.obj
4 File(s) 1,948 bytes
0 Dir(s) 153,282,871,296 bytes free
Скомпилируйте и линкуйте нашу программу:
E:\develop\so\xstatlib>cl /Fehello.exe main.c hello.lib
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:hello.exe
main.obj
hello.lib
Запустить его:
E:\develop\so\xstatlib>hello
Hello world
extern "C"
? Помогает ли это с совместимостью gcc/VisualStudio в отношении изменения имен C++? 04.12.2017extern "C"
должны быть действительными API-интерфейсами C для начала. Я сделал формулировку более точной. 04.12.2017