2012-02-25 3 views
0

В библиотеке, которую я поддерживаю, есть несколько функций, которые зависят от pthreads. В проекте используется automake. Я хочу создать параметр configure, чтобы отключить зависимость от pthreads, которая должна просто не компилировать эти функции. (Причина в том, что некоторые кросс-компилирующие и внедренные цели.)Каков правильный способ обработки дополнительных общедоступных типов/функций для библиотеки с использованием automake?

Избегание компиляции файла, содержащего эти функции, работает нормально до сих пор, но теперь я понял, что эти функции и одна структура, которые они используют, определены в публичных заголовках.

  1. Каков правильный подход здесь, с точки зрения обслуживания библиотеки?
  2. Каков правильный способ сделать типы или функции опционными в публичных заголовках?

Первоначально я думал, что должен превращать заголовки в файлы ввода autoconf (.in) и генерировать заголовки с этими необязательными функциями и типами.

Но что же такое системы, которые могут иметь разные версии библиотеки, установленные одновременно? Обычно они должны иметь возможность делиться заголовками.

Должен ли я заголовок использовать препроцессор, чтобы избежать этих функций, и использовать pkg-config, чтобы указать его как вариант командной строки?

Еще одна идея - переместить эти функции и типы в свой собственный заголовок и избежать установки этого заголовка, когда pthreads отключены. Это означало бы неправильное использование организации заголовков, но, возможно, это лучшая идея. Я хочу ваше мнение, хотя, что лучший способ справиться с дополнительной функциональностью в публичных заголовках библиотеки?

ответ

0

Еще одна идея состоит в том, чтобы переместить эти функции и типы в свой собственный заголовок и избежать установки этого заголовка при отключении pthreads.

Это был бы самый чистый выбор. Когда вы включаете опцию через AC_ARG_ENABLE, вы также можете обойти все настройки pthreads.С помощью этой опции пакеты, зависящие от вашей библиотеки, смогут легко (через AC_TRY_COMPILE) сказать, что функции pthread-optional отсутствуют, а не AC_TRY_RUN, чтобы увидеть, работают ли эти функции во время выполнения.

1

Один из способов заключается в том, чтобы ваши потоковые функции продолжали существовать на встроенной платформе, но возвращали код ошибки в случае их вызова. Таким образом, API остается неизменным на разных платформах, что очень желательно для кода, использующего вашу библиотеку («Программа»), поскольку программе не нужны тесты с автоконфигурированием для присутствия функций в вашей библиотеке, но они могут просто использовать их и использовать исходный код уровня ifs для определения их функциональности.

int mylib_thread_frenzy(void) 
{ 
#ifdef HAVE_PTHREAD_CREATE 
     int ret = pthread_create(...); 
     if (ret < 0) 
       return -errno; 
     return 0; 
#else 
     return -ENOSYS; 
#endif 
} 

.

/* Program */ 
int ret = mylib_thread_frenzy(); 
if (ret == -ENOSYS) { 
    /* Hm, castrated platform. Try something else... */ 
    printf("Or just tell the user the platform is too weak.\n"); 
} else { 
    printf("World domination acquired\n"); 
} 

В любом случае, не пытайтесь #include «config.h» в mylib.h, и не грузит этот config.h либо, так как определяет, изложенный в вашем config.h может столкнуться с те из другой библиотеки и/или Программы.

Если вы абсолютно хотите удалить функции из mylib.h, я думаю, это приходит на ум:

/* mylib.h.in */ 
#if [email protected][email protected] 
extern int mylib_pthread_frenzy(void); 
#endif 

/* configure.ac */ 
AC_SEARCH_LIBS([pthread_create], [pthread], 
    [HAVE_PTHREAD_CREATE=1 
    AC_SUBST([HAVE_PTHREAD_CREATE]) 
    ]) 
AC_CONFIG_FILES([mylib.h.in]) 
AC_OUTPUT 

Я же не нравится второй подход, поскольку это означает, что должно настроить перезапускать каждый раз, когда mylib.h.in изменения.