diff options
| -rw-r--r-- | configure.ac | 26 | ||||
| -rw-r--r-- | src/plist.c | 39 |
2 files changed, 45 insertions, 20 deletions
diff --git a/configure.ac b/configure.ac index 9300f31..0d13e04 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -55,17 +55,17 @@ AC_C_BIGENDIAN([AC_DEFINE([__BIG_ENDIAN__], [1], [big endian])], | |||
| 55 | 55 | ||
| 56 | 56 | ||
| 57 | # Check for operating system | 57 | # Check for operating system |
| 58 | AC_MSG_CHECKING([wether we need platform-specific build settings for ${host_os}]) | 58 | AC_MSG_CHECKING([for platform-specific build settings]) |
| 59 | case ${host_os} in | 59 | case ${host_os} in |
| 60 | *mingw32*|*cygwin*) | 60 | *mingw32*|*cygwin*) |
| 61 | AC_MSG_RESULT([yes]) | 61 | AC_MSG_RESULT([${host_os}]) |
| 62 | win32=true | 62 | win32=true |
| 63 | ;; | 63 | ;; |
| 64 | darwin*|*android*) | 64 | darwin*|*android*) |
| 65 | AC_MSG_RESULT([no]) | 65 | AC_MSG_RESULT([${host_os}]) |
| 66 | ;; | 66 | ;; |
| 67 | *) | 67 | *) |
| 68 | AC_MSG_RESULT([yes]) | 68 | AC_MSG_RESULT([${host_os}]) |
| 69 | AX_PTHREAD([], [AC_MSG_ERROR([pthread is required to build libplist])]) | 69 | AX_PTHREAD([], [AC_MSG_ERROR([pthread is required to build libplist])]) |
| 70 | AC_CHECK_LIB(pthread, [pthread_once], [], [AC_MSG_ERROR([pthread with pthread_once required to build libplist])]) | 70 | AC_CHECK_LIB(pthread, [pthread_once], [], [AC_MSG_ERROR([pthread with pthread_once required to build libplist])]) |
| 71 | ;; | 71 | ;; |
| @@ -74,6 +74,24 @@ AM_CONDITIONAL(WIN32, test x$win32 = xtrue) | |||
| 74 | 74 | ||
| 75 | AC_SEARCH_LIBS([fmin],[m]) | 75 | AC_SEARCH_LIBS([fmin],[m]) |
| 76 | 76 | ||
| 77 | # Check if the C compiler supports __attribute__((constructor)) | ||
| 78 | AC_CACHE_CHECK([wether the C compiler supports constructor/destructor attributes], | ||
| 79 | ac_cv_attribute_constructor, [ | ||
| 80 | ac_cv_attribute_constructor=no | ||
| 81 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM( | ||
| 82 | [[ | ||
| 83 | static void __attribute__((constructor)) test_constructor(void) { | ||
| 84 | } | ||
| 85 | static void __attribute__((destructor)) test_destructor(void) { | ||
| 86 | } | ||
| 87 | ]], [])], | ||
| 88 | [ac_cv_attribute_constructor=yes] | ||
| 89 | )] | ||
| 90 | ) | ||
| 91 | if test "$ac_cv_attribute_constructor" = "yes"; then | ||
| 92 | AC_DEFINE(HAVE_ATTRIBUTE_CONSTRUCTOR, 1, [Define if the C compiler supports constructor/destructor attributes]) | ||
| 93 | fi | ||
| 94 | |||
| 77 | # Check if struct tm has a tm_gmtoff member | 95 | # Check if struct tm has a tm_gmtoff member |
| 78 | AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff, | 96 | AC_CACHE_CHECK(for tm_gmtoff in struct tm, ac_cv_struct_tm_gmtoff, |
| 79 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ | 97 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ |
diff --git a/src/plist.c b/src/plist.c index 454d08c..d0e6c77 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -63,7 +63,6 @@ static void internal_plist_deinit(void) | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | #ifdef WIN32 | 65 | #ifdef WIN32 |
| 66 | |||
| 67 | typedef volatile struct { | 66 | typedef volatile struct { |
| 68 | LONG lock; | 67 | LONG lock; |
| 69 | int state; | 68 | int state; |
| @@ -83,7 +82,29 @@ static void thread_once(thread_once_t *once_control, void (*init_routine)(void)) | |||
| 83 | } | 82 | } |
| 84 | InterlockedExchange(&(once_control->lock), 0); | 83 | InterlockedExchange(&(once_control->lock), 0); |
| 85 | } | 84 | } |
| 85 | #else | ||
| 86 | static pthread_once_t init_once = PTHREAD_ONCE_INIT; | ||
| 87 | static pthread_once_t deinit_once = PTHREAD_ONCE_INIT; | ||
| 88 | #define thread_once pthread_once | ||
| 89 | #endif | ||
| 90 | |||
| 91 | #ifndef HAVE_ATTRIBUTE_CONSTRUCTOR | ||
| 92 | #if defined(__llvm__) || defined(__GNUC__) | ||
| 93 | #define HAVE_ATTRIBUTE_CONSTRUCTOR | ||
| 94 | #endif | ||
| 95 | #endif | ||
| 96 | |||
| 97 | #ifdef HAVE_ATTRIBUTE_CONSTRUCTOR | ||
| 98 | static void __attribute__((constructor)) libplist_initialize(void) | ||
| 99 | { | ||
| 100 | thread_once(&init_once, internal_plist_init); | ||
| 101 | } | ||
| 86 | 102 | ||
| 103 | static void __attribute__((destructor)) libplist_deinitialize(void) | ||
| 104 | { | ||
| 105 | thread_once(&deinit_once, internal_plist_deinit); | ||
| 106 | } | ||
| 107 | #elif defined(WIN32) | ||
| 87 | BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) | 108 | BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) |
| 88 | { | 109 | { |
| 89 | switch (dwReason) { | 110 | switch (dwReason) { |
| @@ -98,22 +119,8 @@ BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) | |||
| 98 | } | 119 | } |
| 99 | return 1; | 120 | return 1; |
| 100 | } | 121 | } |
| 101 | |||
| 102 | #else | 122 | #else |
| 103 | 123 | #warning No compiler support for constructor/destructor attributes, some features might not be available. | |
| 104 | static pthread_once_t init_once = PTHREAD_ONCE_INIT; | ||
| 105 | static pthread_once_t deinit_once = PTHREAD_ONCE_INIT; | ||
| 106 | |||
| 107 | static void __attribute__((constructor)) libplist_initialize(void) | ||
| 108 | { | ||
| 109 | pthread_once(&init_once, internal_plist_init); | ||
| 110 | } | ||
| 111 | |||
| 112 | static void __attribute__((destructor)) libplist_deinitialize(void) | ||
| 113 | { | ||
| 114 | pthread_once(&deinit_once, internal_plist_deinit); | ||
| 115 | } | ||
| 116 | |||
| 117 | #endif | 124 | #endif |
| 118 | 125 | ||
| 119 | #ifndef HAVE_MEMMEM | 126 | #ifndef HAVE_MEMMEM |
