LINUX.ORG.RU

Собрать Си-библиотеку mimeTeX с Qt-программой

 , , , ,


0

1

Имеется широко известный в узких кругах проект mimetex - минималистичный генератор картинок формул на основе языка разметки TeX. Его сайт:

http://www.forkosh.com/mimetex.html (в настоящий момент опять лег)

Зато последняя версия аккуратно сохранена у автора MyTetra:

https://webhamster.ru/mytetrashare/index/mtb0/15315568717nedxk2nkx

В архиве mimetex.zip есть документация по компиляции.


* * *


Задача в том, чтобы собрать Qt-программу со статической библиотекой, полученной из mimetex (исходники mimetex оформлены как программа, а не как библиотека). Для того, чтобы получить статическую библиотеку mimetex, я сделал следующее:

А. Заменил в mimetex.c все определения и вызовы функции main() на mimetexMain().

Б. В файл mimetex.h добавил:

#ifdef Q_OS_WIN
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif
MY_EXPORT int CreateGifFromEq ( char *expression, char *gifFileName );

По сути, вызывать из этой библиотеки мне нужно только одну функцию CreateGifFromEq().

Qt-проект у меня состоит из двух под-проектов: библиотека mimetex и собственно сама программа:
TEMPLATE = subdirs
 
SUBDIRS = mimetex app

app.file = app/app.pro
app.depends = mimetex

mimetex.file = thirdParty/mimetex/mimetex.pro

Библиотека mimetex компилится в файл mimetex.a. С ворнингами, но компилится.

А при сборке подпроекта приложения возникает две проблемы:

Так как из C++ - кода инклюдится Си-заголовок mimetex.h, то в нем вылазит много ошибок, типа:
In file included from ../../programm/app/src/main.cpp:2:0:
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:267:12: error: expected identifier before ‘;’ token
   int class;    /* e.g., 3=relation, TexBook pg.154*/
            ^
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:267:12: error: multiple types in one declaration
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:267:12: error: declaration does not declare anything [-fpermissive]
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:319:61: error: expected identifier before ‘;’ token
 STATIC struct {char *name; int family; int istext; int class;}
                                                             ^
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:319:61: error: multiple types in one declaration
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:319:61: error: declaration does not declare anything [-fpermissive]
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:337:34: error: too many initializers for ‘<anonymous struct>’
     {  NULL,    0,       0,  0 } }
                                  ^
../../programm/app/src/../../thirdParty/mimetex/mimetex.h:337:34: error: too many initializers for ‘<anonymous struct>’

Я обошел это так. В приложении есть дефайн APPLICATION_NAME. Весь код mimetex.h (за исключение экспорта функции CreateGifFromEq) я оборачиваю конструкцией:
#ifndef APPLICATION_NAME
...
#endif

В результате, когда собирается подпроект библиотеки mimetex, этого дефайна в коде нет, и библиотека собирается. А когда mimetex.h подключается из приложения, в mimetex.h остаются только директивы экспорта функции CreateGifFromEq(). Но на этапе линковки приложения все равно эта функция не видна:
build/main.o: In function `main':
Makefile:246: recipe for target 'bin/programm' failed
make[1]: Leaving directory '/media/wd_640_part_2/home64bit/xi/work/develop/cpp/ProgrammWithMimetex/build-build-Desktop_Qt_5_10_1_GCC_64bit-Debug/app'
Makefile:70: recipe for target 'sub-app-app-pro-make_first' failed
/media/wd_640_part_2/home64bit/xi/work/develop/cpp/ProgrammWithMimetex/build-build-Desktop_Qt_5_10_1_GCC_64bit-Debug/app/../../programm/app/src/main.cpp:12: undefined reference to `CreateGifFromEq(char*, char*)'
collect2: error: ld returned 1 exit status
make[1]: *** [bin/programm] Error 1


Вот. Мне нужно сделать две вещи.


Минимум: заставить компилиться проект приложения и делать вызов фукции CreateGifFromEq()


Максимум: настроить подпроект mimetex.pro так, чтобы не лезли варнинги. Если mimetex компилить прямой командой:
gcc -DAA mimetex.c gifsave.c -lm -o mimetex

то варнингов нет.


Готовый минимальный пример: http://rgho.st/6YP2gjCHq

★★★★★

Немного не потеме

mimeTeX - классная тулза для своего времени, когда формулы в web-страницы можно было вставлять только в виде gif-ов. Но теперь поддержка svg практически во всех browser-ах. Поэтому предпочтительнее использовать EqualX, а не mimeTeX.

zvezdochiot ()
Ответ на: Немного не потеме от zvezdochiot

Угу, только чтобы этот EqualX заработал, нужно еще LaTeX установить. Для кроссплатформенной программы тянуть за собой LaTeX со всеми его закидонами под Unix/Windows/MacOs - это вообще не вариант.

Xintrea ★★★★★ ()

Нет возможности сейчас проверить.

Попробуй вот что:

1. Открой файл main.cpp

2. Замени

#include "../../thirdParty/mimetex/mimetex.h"

на

#ifdef __cplusplus
extern "C" {
#endif
#include "../../thirdParty/mimetex/mimetex.h"
#ifdef __cplusplus
}
#endif
fsb4000 ()
Ответ на: комментарий от fsb4000

Ошибки стали такими:

g++ -Wl,-rpath,/opt/qt_5_10_1/5.10.1/gcc_64/lib -o bin/programm build/main.o   -L/media/wd_640_part_2/home64bit/xi/work/develop/cpp/ProgrammWithMimetex/programm/app/../thirdParty/mimetex/build/lib -lmimetex -L/opt/qt_5_10_1/5.10.1/gcc_64/lib -lQt5Core -lpthread 
/media/wd_640_part_2/home64bit/xi/work/develop/cpp/ProgrammWithMimetex/programm/app/../thirdParty/mimetex/build/lib/libmimetex.a(mimetex.o): In function `mimetexMain':
/media/wd_640_part_2/home64bit/xi/work/develop/cpp/ProgrammWithMimetex/build-build-Desktop_Qt_5_10_1_GCC_64bit-Debug/thirdParty/mimetex/../../../programm/thirdParty/mimetex/mimetex.c:16791: undefined reference to `gifSize'
/media/wd_640_part_2/home64bit/xi/work/develop/cpp/ProgrammWithMimetex/build-build-Desktop_Qt_5_10_1_GCC_64bit-Debug/thirdParty/mimetex/../../../programm/thirdParty/mimetex/mimetex.c:17542: undefined reference to `GIF_Create'
/media/wd_640_part_2/home64bit/xi/work/develop/cpp/ProgrammWithMimetex/build-build-Desktop_Qt_5_10_1_GCC_64bit-Debug/thirdParty/mimetex/../../../programm/thirdParty/mimetex/mimetex.c:17558: undefined reference to `GIF_SetColor'
...

Xintrea ★★★★★ ()
Ответ на: комментарий от zvezdochiot

Те же самые ошибки.

Я не понимаю, с какого перепуга ошибки показываются в mimetex.c, если либа подключается статически и от нее берется только заголовок.

Xintrea ★★★★★ ()
Ответ на: комментарий от Xintrea

Ну там в исходниках такое есть

/* ---
 * info needed when gif image returned in memory buffer
 * ---------------------------------------------------- */
#if defined(GIF)			/* compiling along with gifsave.c */
  extern int gifSize;
  extern int maxgifSize;

А gifsave.c я вообще не увидел...

Это объясняет ошибку

mimetex.c:16791: undefined reference to `gifSize'

fsb4000 ()
Ответ на: комментарий от Xintrea

с какого перепуга ошибки показываются в mimetex.c

Ошибки вызваны очень путанной системой уловок именно в mimetex.c и связаны они с параметром компиляции в Makefile:

cc -DAA ...

Может стоит в начало mimetex.c прописать:

#define AA

PS: Кстати GIT не дремлет: mimetex

zvezdochiot ()
Ответ на: комментарий от Xintrea

Думаю по быстрому никак. Только рефакторинг всего кода в хедере, который не является допустимым в С++(типа имени поля class и остальные ошибки которые показывает компилятор)

Правда у g++ есть флаг

-fpermissive
с которым он может компилировать С код C++ компилятором, но я думаю такой хак даже хуже чем
#ifndef APPLICATION_NAME

fsb4000 ()

А зачем инклюдить mimetex.h в код на C++? Если оттуда нужна только одна функция (в версии из Debian, например, она там и вовсе закомментирована), не проще ли объявить её вручную?

По крайней мере, у меня вот такой проект собирает libmimetex.a из оригинальных исходников (в смысле, из apt-get source mimetex):

TEMPLATE = lib
TARGET = mimetex
INCLUDEPATH += .
DEFINES += AA main=mimeTeX_main
CONFIG += staticlib
HEADERS += mimetex.h texfonts.h
SOURCES += gifsave.c mimetex.c

А вот такой - линкуется с ней:

TEMPLATE = app
TARGET = app
INCLUDEPATH += .
SOURCES += run.cpp
LIBS += ../mimetex-1.74/libmimetex.a

extern "C" int CreateGifFromEq (char *expression, char *gifFileName);

int main() {
        char *tex = "\\version", *file = "version.gif";
        return CreateGifFromEq(tex, file);
}
anonymous ()
Ответ на: комментарий от anonymous

Я немного по-другому сделал. Вместо инклюда mimetex.h сделал файл mimetexExport.h с экспортом одной функции, и инклюжу его. Так не нужно заморачиваться с APPLICATION_NAME.

Xintrea ★★★★★ ()