changeset 167:bd5597966b3d

sync
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 22 Aug 2017 21:46:50 +0200
parents e5ac1fd6cf7d
children 38aa615b7667
files NEWS Orthanc/Core/SystemToolbox.cpp Orthanc/Core/SystemToolbox.h Orthanc/Core/Toolbox.cpp Orthanc/Core/Toolbox.h Orthanc/Resources/CMake/BoostConfiguration.cmake Orthanc/Resources/CMake/Compiler.cmake
diffstat 7 files changed, 404 insertions(+), 188 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Jul 19 14:53:59 2017 +0200
+++ b/NEWS	Tue Aug 22 21:46:50 2017 +0200
@@ -1,6 +1,8 @@
 Pending changes in the mainline
 ===============================
 
+* Support of OpenBSD 64bit
+
 
 Version 2.3 (2017-07-19)
 ========================
--- a/Orthanc/Core/SystemToolbox.cpp	Wed Jul 19 14:53:59 2017 +0200
+++ b/Orthanc/Core/SystemToolbox.cpp	Tue Aug 22 21:46:50 2017 +0200
@@ -35,11 +35,6 @@
 #include "SystemToolbox.h"
 
 
-#if BOOST_HAS_DATE_TIME == 1
-#  include <boost/date_time/posix_time/posix_time.hpp>
-#endif
-
-
 #if defined(_WIN32)
 #  include <windows.h>
 #  include <process.h>   // For "_spawnvp()" and "_getpid()"
@@ -62,12 +57,17 @@
 #endif
 
 
+#if defined(__OpenBSD__)
+#  include <sys/sysctl.h>  // For "sysctl", "CTL_KERN" and "KERN_PROC_ARGS"
+#endif
+
+
 // Inclusions for UUID
 // http://stackoverflow.com/a/1626302
 
 extern "C"
 {
-#ifdef WIN32
+#if defined(_WIN32)
 #  include <rpc.h>
 #else
 #  include <uuid/uuid.h>
@@ -81,6 +81,7 @@
 
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 
 namespace Orthanc
@@ -157,7 +158,7 @@
   {
 #if defined(_WIN32)
     ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000)));
-#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__native_client__)
+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__native_client__)
     usleep(microSeconds);
 #else
 #error Support your platform here
@@ -193,7 +194,7 @@
     }
 
     std::streamsize size = GetStreamSize(f);
-    content.resize(size);
+    content.resize(static_cast<size_t>(size));
     if (size != 0)
     {
       f.read(reinterpret_cast<char*>(&content[0]), size);
@@ -231,7 +232,7 @@
       }
       else if (static_cast<size_t>(size) < headerSize)
       {
-        headerSize = size;  // Truncate to the size of the file
+        headerSize = static_cast<size_t>(size);  // Truncate to the size of the file
         full = false;
       }
     }
@@ -349,6 +350,8 @@
 #elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
   static std::string GetPathToExecutableInternal()
   {
+    // NOTE: For FreeBSD, using KERN_PROC_PATHNAME might be a better alternative
+
     std::vector<char> buffer(PATH_MAX + 1);
     ssize_t bytes = readlink("/proc/self/exe", &buffer[0], buffer.size() - 1);
     if (bytes == 0)
@@ -370,6 +373,37 @@
     return std::string(pathbuf);
   }
 
+#elif defined(__OpenBSD__)
+  static std::string GetPathToExecutableInternal()
+  {
+    // This is an adapted version of the patch proposed in issue #64
+    // without an explicit call to "malloc()" to prevent memory leak
+    // https://bitbucket.org/sjodogne/orthanc/issues/64/add-openbsd-support
+    // https://stackoverflow.com/q/31494901/881731
+
+    const int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
+
+    size_t len;
+    if (sysctl(mib, 4, NULL, &len, NULL, 0) == -1) 
+    {
+      throw OrthancException(ErrorCode_PathToExecutable);
+    }
+
+    std::string tmp;
+    tmp.resize(len);
+
+    char** buffer = reinterpret_cast<char**>(&tmp[0]);
+
+    if (sysctl(mib, 4, buffer, &len, NULL, 0) == -1) 
+    {
+      throw OrthancException(ErrorCode_PathToExecutable);
+    }
+    else
+    {
+      return std::string(buffer[0]);
+    }
+  }
+
 #else
 #error Support your platform here
 #endif
@@ -527,13 +561,13 @@
   }
 
 
-#if BOOST_HAS_DATE_TIME == 1
   std::string SystemToolbox::GetNowIsoString()
   {
     boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
     return boost::posix_time::to_iso_string(now);
   }
 
+  
   void SystemToolbox::GetNowDicom(std::string& date,
                                   std::string& time)
   {
@@ -548,5 +582,4 @@
     sprintf(s, "%02d%02d%02d.%06d", tm.tm_hour, tm.tm_min, tm.tm_sec, 0);
     time.assign(s);
   }
-#endif
 }
--- a/Orthanc/Core/SystemToolbox.h	Wed Jul 19 14:53:59 2017 +0200
+++ b/Orthanc/Core/SystemToolbox.h	Tue Aug 22 21:46:50 2017 +0200
@@ -95,11 +95,9 @@
 
     std::string GenerateUuid();
 
-#if BOOST_HAS_DATE_TIME == 1
     std::string GetNowIsoString();
 
     void GetNowDicom(std::string& date,
                      std::string& time);
-#endif
   }
 }
--- a/Orthanc/Core/Toolbox.cpp	Wed Jul 19 14:53:59 2017 +0200
+++ b/Orthanc/Core/Toolbox.cpp	Tue Aug 22 21:46:50 2017 +0200
@@ -37,24 +37,18 @@
 #include "OrthancException.h"
 #include "Logging.h"
 
+#include <boost/algorithm/string/case_conv.hpp>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/lexical_cast.hpp>
-#include <boost/locale.hpp>
+#include <boost/regex.hpp> 
 #include <boost/uuid/sha1.hpp>
-
+ 
 #include <string>
 #include <stdint.h>
 #include <string.h>
 #include <algorithm>
 #include <ctype.h>
 
-#if BOOST_HAS_REGEX == 1
-#  include <boost/regex.hpp> 
-#endif
-
-#if BOOST_HAS_LOCALE != 1
-#  error Since version 0.7.6, Orthanc entirely relies on boost::locale
-#endif
 
 #if ORTHANC_ENABLE_MD5 == 1
 #  include "../Resources/ThirdParty/md5/md5.h"
@@ -64,6 +58,10 @@
 #  include "../Resources/ThirdParty/base64/base64.h"
 #endif
 
+#if ORTHANC_ENABLE_LOCALE == 1
+#  include <boost/locale.hpp>
+#endif
+
 
 #if defined(_MSC_VER) && (_MSC_VER < 1800)
 // Patch for the missing "_strtoll" symbol when compiling with Visual Studio < 2013
@@ -368,7 +366,6 @@
   }
 
 
-#  if BOOST_HAS_REGEX == 1
   bool Toolbox::DecodeDataUriScheme(std::string& mime,
                                     std::string& content,
                                     const std::string& source)
@@ -388,7 +385,6 @@
       return false;
     }
   }
-#  endif
 
 
   void Toolbox::EncodeDataUriScheme(std::string& result,
@@ -469,6 +465,7 @@
   }
 
 
+#if ORTHANC_ENABLE_LOCALE == 1
   std::string Toolbox::ConvertToUtf8(const std::string& source,
                                      Encoding sourceEncoding)
   {
@@ -495,8 +492,10 @@
       return ConvertToAscii(source);
     }
   }
+#endif
+  
 
-
+#if ORTHANC_ENABLE_LOCALE == 1
   std::string Toolbox::ConvertFromUtf8(const std::string& source,
                                        Encoding targetEncoding)
   {
@@ -523,6 +522,7 @@
       return ConvertToAscii(source);
     }
   }
+#endif
 
 
   bool Toolbox::IsAsciiString(const void* data,
@@ -778,7 +778,6 @@
   }
 
 
-#if BOOST_HAS_REGEX == 1
   std::string Toolbox::WildcardToRegularExpression(const std::string& source)
   {
     // TODO - Speed up this with a regular expression
@@ -806,8 +805,6 @@
 
     return result;
   }
-#endif
-
 
 
   void Toolbox::TokenizeString(std::vector<std::string>& result,
@@ -1251,4 +1248,124 @@
 
     return IsUuid(str.substr(0, 36));
   }
+
+
+#if ORTHANC_ENABLE_LOCALE == 1
+  static std::auto_ptr<std::locale>  globalLocale_;
+
+  static bool SetGlobalLocale(const char* locale)
+  {
+    globalLocale_.reset(NULL);
+
+    try
+    {
+      if (locale == NULL)
+      {
+        LOG(WARNING) << "Falling back to system-wide default locale";
+        globalLocale_.reset(new std::locale());
+      }
+      else
+      {
+        LOG(INFO) << "Using locale: \"" << locale << "\" for case-insensitive comparison of strings";
+        globalLocale_.reset(new std::locale(locale));
+      }
+    }
+    catch (std::runtime_error&)
+    {
+    }
+
+    return (globalLocale_.get() != NULL);
+  }
+  
+  void Toolbox::InitializeGlobalLocale(const char* locale)
+  {
+    // Make Orthanc use English, United States locale
+    // Linux: use "en_US.UTF-8"
+    // Windows: use ""
+    // Wine: use NULL
+    
+#if defined(__MINGW32__)
+    // Visibly, there is no support of locales in MinGW yet
+    // http://mingw.5.n7.nabble.com/How-to-use-std-locale-global-with-MinGW-correct-td33048.html
+    static const char* DEFAULT_LOCALE = NULL;
+#elif defined(_WIN32)
+    // For Windows: use default locale (using "en_US" does not work)
+    static const char* DEFAULT_LOCALE = "";
+#else
+    // For Linux & cie
+    static const char* DEFAULT_LOCALE = "en_US.UTF-8";
+#endif
+
+    bool ok;
+    
+    if (locale == NULL)
+    {
+      ok = SetGlobalLocale(DEFAULT_LOCALE);
+
+#if defined(__MINGW32__)
+      LOG(WARNING) << "This is a MinGW build, case-insensitive comparison of "
+                   << "strings with accents will not work outside of Wine";
+#endif
+    }
+    else
+    {
+      ok = SetGlobalLocale(locale);
+    }
+
+    if (!ok &&
+        !SetGlobalLocale(NULL))
+    {
+      LOG(ERROR) << "Cannot initialize global locale";
+      throw OrthancException(ErrorCode_InternalError);
+    }
+
+  }
+
+
+  void Toolbox::FinalizeGlobalLocale()
+  {
+    globalLocale_.reset();
+  }
+#endif
+
+  
+  std::string Toolbox::ToUpperCaseWithAccents(const std::string& source)
+  {
+    if (globalLocale_.get() == NULL)
+    {
+      LOG(ERROR) << "No global locale was set, call Toolbox::InitializeGlobalLocale()";
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+
+    /**
+     * A few notes about locales:
+     *
+     * (1) We don't use "case folding":
+     * http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/conversions.html
+     *
+     * Characters are made uppercase one by one. This is because, in
+     * static builds, we are using iconv, which is visibly not
+     * supported correctly (TODO: Understand why). Case folding seems
+     * to be working correctly if using the default backend under
+     * Linux (ICU or POSIX?). If one wishes to use case folding, one
+     * would use:
+     *
+     *   boost::locale::generator gen;
+     *   std::locale::global(gen(DEFAULT_LOCALE));
+     *   return boost::locale::to_upper(source);
+     *
+     * (2) The function "boost::algorithm::to_upper_copy" does not
+     * make use of the "std::locale::global()". We therefore create a
+     * global variable "globalLocale_".
+     * 
+     * (3) The variant of "boost::algorithm::to_upper_copy()" that
+     * uses std::string does not work properly. We need to apply it
+     * one wide strings (std::wstring). This explains the two calls to
+     * "utf_to_utf" in order to convert to/from std::wstring.
+     **/
+
+    std::wstring w = boost::locale::conv::utf_to_utf<wchar_t>(source);
+    w = boost::algorithm::to_upper_copy<std::wstring>(w, *globalLocale_);
+    return boost::locale::conv::utf_to_utf<char>(w);
+  }
 }
--- a/Orthanc/Core/Toolbox.h	Wed Jul 19 14:53:59 2017 +0200
+++ b/Orthanc/Core/Toolbox.h	Tue Aug 22 21:46:50 2017 +0200
@@ -45,6 +45,10 @@
 #  error The macro ORTHANC_ENABLE_BASE64 must be defined
 #endif
 
+#if !defined(ORTHANC_ENABLE_LOCALE)
+#  error The macro ORTHANC_ENABLE_LOCALE must be defined
+#endif
+
 #if !defined(ORTHANC_ENABLE_MD5)
 #  error The macro ORTHANC_ENABLE_MD5 must be defined
 #endif
@@ -53,10 +57,6 @@
 #  error The macro ORTHANC_ENABLE_PUGIXML must be defined
 #endif
 
-#if !defined(BOOST_HAS_REGEX)
-#  error The macro BOOST_HAS_REGEX must be defined
-#endif
-
 
 /**
  * NOTE: GUID vs. UUID
@@ -132,22 +132,22 @@
     void EncodeBase64(std::string& result, 
                       const std::string& data);
 
-#  if BOOST_HAS_REGEX == 1
     bool DecodeDataUriScheme(std::string& mime,
                              std::string& content,
                              const std::string& source);
-#  endif
 
     void EncodeDataUriScheme(std::string& result,
                              const std::string& mime,
                              const std::string& content);
 #endif
 
+#if ORTHANC_ENABLE_LOCALE == 1
     std::string ConvertToUtf8(const std::string& source,
                               Encoding sourceEncoding);
 
     std::string ConvertFromUtf8(const std::string& source,
                                 Encoding targetEncoding);
+#endif
 
     bool IsAsciiString(const void* data,
                        size_t size);
@@ -161,9 +161,7 @@
 
     Endianness DetectEndianness();
 
-#if BOOST_HAS_REGEX == 1
     std::string WildcardToRegularExpression(const std::string& s);
-#endif
 
     void TokenizeString(std::vector<std::string>& result,
                         const std::string& source,
@@ -206,5 +204,13 @@
     bool IsUuid(const std::string& str);
 
     bool StartsWithUuid(const std::string& str);
+
+#if ORTHANC_ENABLE_LOCALE == 1
+    void InitializeGlobalLocale(const char* locale);
+
+    void FinalizeGlobalLocale();
+#endif
+
+    std::string ToUpperCaseWithAccents(const std::string& source);
   }
 }
--- a/Orthanc/Resources/CMake/BoostConfiguration.cmake	Wed Jul 19 14:53:59 2017 +0200
+++ b/Orthanc/Resources/CMake/BoostConfiguration.cmake	Tue Aug 22 21:46:50 2017 +0200
@@ -7,8 +7,12 @@
   #set(Boost_DEBUG 1)
   #set(Boost_USE_STATIC_LIBS ON)
 
+  if (ENABLE_LOCALE)
+    list(APPEND ORTHANC_BOOST_COMPONENTS locale)
+  endif()
+
   find_package(Boost
-    COMPONENTS filesystem thread system date_time regex locale ${ORTHANC_BOOST_COMPONENTS})
+    COMPONENTS filesystem thread system date_time regex ${ORTHANC_BOOST_COMPONENTS})
 
   if (NOT Boost_FOUND)
     message(FATAL_ERROR "Unable to locate Boost on this system")
@@ -27,112 +31,120 @@
       )
   endif()
 
-  #if (${Boost_VERSION} LESS 104800)
-  # boost::locale is only available from 1.48.00
-  #message("Too old version of Boost (${Boost_LIB_VERSION}): Building the static version")
-  #  set(BOOST_STATIC 1)
-  #endif()
-
   include_directories(${Boost_INCLUDE_DIRS})
   link_libraries(${Boost_LIBRARIES})
 endif()
 
 
 if (BOOST_STATIC)
-  # Parameters for Boost 1.60.0
-  set(BOOST_NAME boost_1_60_0)
-  set(BOOST_BCP_SUFFIX bcpdigest-1.0.1)
-  set(BOOST_MD5 "a789f8ec2056ad1c2d5f0cb64687cc7b")
+  ##
+  ## Parameters for static compilation of Boost 
+  ##
+  
+  set(BOOST_NAME boost_1_64_0)
+  set(BOOST_BCP_SUFFIX bcpdigest-1.3.0)
+  set(BOOST_MD5 "ecb266cf46adcc7f695ad12685871174")
   set(BOOST_URL "http://www.orthanc-server.com/downloads/third-party/${BOOST_NAME}_${BOOST_BCP_SUFFIX}.tar.gz")
-  set(BOOST_FILESYSTEM_SOURCES_DIR "${BOOST_NAME}/libs/filesystem/src") 
   set(BOOST_SOURCES_DIR ${CMAKE_BINARY_DIR}/${BOOST_NAME})
 
   DownloadPackage(${BOOST_MD5} ${BOOST_URL} "${BOOST_SOURCES_DIR}")
 
-  set(BOOST_SOURCES)
+
+  ##
+  ## Generic configuration of Boost
+  ## 
+
+  if (CMAKE_COMPILER_IS_GNUCXX)
+    add_definitions(-isystem ${BOOST_SOURCES_DIR})
+  endif()
+
+  include_directories(
+    ${BOOST_SOURCES_DIR}
+    )
 
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
+  add_definitions(
+    # Static build of Boost
+    -DBOOST_ALL_NO_LIB 
+    -DBOOST_ALL_NOLIB 
+    -DBOOST_DATE_TIME_NO_LIB 
+    -DBOOST_THREAD_BUILD_LIB
+    -DBOOST_PROGRAM_OPTIONS_NO_LIB
+    -DBOOST_REGEX_NO_LIB
+    -DBOOST_SYSTEM_NO_LIB
+    -DBOOST_LOCALE_NO_LIB
+    )
+
+  set(BOOST_SOURCES
+    ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
+    )
+
+
+  ##
+  ## Configuration of boost::thread
+  ##
+  
+  if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
+      CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+      CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+      CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD" OR
+      CMAKE_SYSTEM_NAME STREQUAL "OpenBSD" OR
+      CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+      CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+      CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
     list(APPEND BOOST_SOURCES
       ${BOOST_SOURCES_DIR}/libs/atomic/src/lockpool.cpp
       ${BOOST_SOURCES_DIR}/libs/thread/src/pthread/once.cpp
       ${BOOST_SOURCES_DIR}/libs/thread/src/pthread/thread.cpp
       )
-    add_definitions(
-      -DBOOST_LOCALE_WITH_ICONV=1
-      -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
-      -DBOOST_LOCALE_NO_STD_BACKEND=1
-      )
 
     if ("${CMAKE_SYSTEM_VERSION}" STREQUAL "LinuxStandardBase" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
+        CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+        CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+        CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
       add_definitions(-DBOOST_HAS_SCHED_YIELD=1)
     endif()
 
-  elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
+  elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
     list(APPEND BOOST_SOURCES
       ${BOOST_SOURCES_DIR}/libs/thread/src/win32/tss_dll.cpp
       ${BOOST_SOURCES_DIR}/libs/thread/src/win32/thread.cpp
       ${BOOST_SOURCES_DIR}/libs/thread/src/win32/tss_pe.cpp
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/windows_file_codecvt.cpp
       )
 
-    # Starting with release 0.8.2, Orthanc statically links against
-    # libiconv, even on Windows. Indeed, the "WCONV" library of
-    # Windows XP seems not to support properly several codepages
-    # (notably "Latin3", "Hebrew", and "Arabic").
-
-    if (USE_BOOST_ICONV)
-      include(${ORTHANC_ROOT}/Resources/CMake/LibIconvConfiguration.cmake)
-    else()
-      add_definitions(-DBOOST_LOCALE_WITH_WCONV=1)
-    endif()
-
-    add_definitions(
-      -DBOOST_LOCALE_NO_POSIX_BACKEND=1
-      -DBOOST_LOCALE_NO_STD_BACKEND=1
-      )
-
-  elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
-    add_definitions(
-      -DBOOST_LOCALE_NO_POSIX_BACKEND=1
-      -DBOOST_LOCALE_NO_STD_BACKEND=1
-      )
+  elseif (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
 
   else()
     message(FATAL_ERROR "Support your platform here")
   endif()
 
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
-    list(APPEND BOOST_SOURCES
-      ${BOOST_SOURCES_DIR}/libs/filesystem/src/utf8_codecvt_facet.cpp
-      )
-  endif()
 
+  ##
+  ## Configuration of boost::regex
+  ##
+  
   aux_source_directory(${BOOST_SOURCES_DIR}/libs/regex/src BOOST_REGEX_SOURCES)
 
   list(APPEND BOOST_SOURCES
     ${BOOST_REGEX_SOURCES}
-    ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp
-    ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
     )
 
-  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
-    list(APPEND BOOST_SOURCES
-      ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp
-      )
-  endif()
+
+  ##
+  ## Configuration of boost::datetime
+  ##
+  
+  list(APPEND BOOST_SOURCES
+    ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp
+    )
 
-  if (${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
-      ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
+
+  ##
+  ## Configuration of boost::filesystem
+  ## 
+
+  if (CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+      CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+      CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
     # boost::filesystem is not available on PNaCl
     add_definitions(
       -DBOOST_HAS_FILESYSTEM_V3=0
@@ -143,50 +155,35 @@
       -DBOOST_HAS_FILESYSTEM_V3=1
       )
     list(APPEND BOOST_SOURCES
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/codecvt_error_category.cpp
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/operations.cpp
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/path.cpp
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/path_traits.cpp
+      ${BOOST_NAME}/libs/filesystem/src/codecvt_error_category.cpp
+      ${BOOST_NAME}/libs/filesystem/src/operations.cpp
+      ${BOOST_NAME}/libs/filesystem/src/path.cpp
+      ${BOOST_NAME}/libs/filesystem/src/path_traits.cpp
       )
+
+    if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+        CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+     list(APPEND BOOST_SOURCES
+        ${BOOST_SOURCES_DIR}/libs/filesystem/src/utf8_codecvt_facet.cpp
+        )
+
+    elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
+      list(APPEND BOOST_SOURCES
+        ${BOOST_NAME}/libs/filesystem/src/windows_file_codecvt.cpp
+        )
+    endif()
   endif()
 
-  if (USE_BOOST_LOCALE_BACKENDS)
-    if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
-        ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
-      list(APPEND BOOST_SOURCES
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/converter.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/numeric.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/posix_backend.cpp
-        )
-    elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
-      list(APPEND BOOST_SOURCES
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/collate.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/converter.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/lcid.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/numeric.cpp
-        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/win_backend.cpp
-        )
-    else()
-      message(FATAL_ERROR "Support your platform here")
-    endif()
+
+  ##
+  ## Configuration of boost::locale
+  ## 
 
+  if (NOT ENABLE_LOCALE)
+    message("boost::locale is disabled")
+  else()
     list(APPEND BOOST_SOURCES
-      ${BOOST_REGEX_SOURCES}
-      ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp
-      ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
-
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/codecvt_error_category.cpp
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/operations.cpp
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/path.cpp
-      ${BOOST_FILESYSTEM_SOURCES_DIR}/path_traits.cpp
-
+      ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp
       ${BOOST_SOURCES_DIR}/libs/locale/src/shared/generator.cpp
       ${BOOST_SOURCES_DIR}/libs/locale/src/shared/date_time.cpp
       ${BOOST_SOURCES_DIR}/libs/locale/src/shared/formatting.cpp
@@ -200,39 +197,75 @@
       ${BOOST_SOURCES_DIR}/libs/locale/src/util/info.cpp
       ${BOOST_SOURCES_DIR}/libs/locale/src/util/locale_data.cpp
       )        
+
+    if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
+        CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR
+        CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
+        CMAKE_SYSTEM_NAME STREQUAL "kFreeBSD" OR
+        CMAKE_SYSTEM_NAME STREQUAL "PNaCl" OR
+        CMAKE_SYSTEM_NAME STREQUAL "NaCl32" OR
+        CMAKE_SYSTEM_NAME STREQUAL "NaCl64")
+      list(APPEND BOOST_SOURCES
+        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/codecvt.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/collate.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/converter.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/numeric.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/posix/posix_backend.cpp
+        )
+
+      add_definitions(
+        -DBOOST_LOCALE_WITH_ICONV=1
+        -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
+        -DBOOST_LOCALE_NO_STD_BACKEND=1
+        )
+      
+    elseif (CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
+      list(APPEND BOOST_SOURCES
+        ${BOOST_SOURCES_DIR}/libs/locale/src/std/codecvt.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/std/collate.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/std/converter.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/std/numeric.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/std/std_backend.cpp
+        )
+
+      add_definitions(
+        -DBOOST_LOCALE_WITH_ICONV=1
+        -DBOOST_LOCALE_NO_WINAPI_BACKEND=1
+        -DBOOST_LOCALE_NO_POSIX_BACKEND=1
+        )
+      
+    elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
+      list(APPEND BOOST_SOURCES
+        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/collate.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/converter.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/lcid.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/numeric.cpp
+        ${BOOST_SOURCES_DIR}/libs/locale/src/win32/win_backend.cpp
+        )
+
+      add_definitions(
+        -DBOOST_LOCALE_NO_POSIX_BACKEND=1
+        -DBOOST_LOCALE_NO_STD_BACKEND=1
+        )
+
+      # Starting with release 0.8.2, Orthanc statically links against
+      # libiconv, even on Windows. Indeed, the "WCONV" library of
+      # Windows XP seems not to support properly several codepages
+      # (notably "Latin3", "Hebrew", and "Arabic"). Set
+      # "USE_BOOST_ICONV" to "OFF" to use WCONV anyway.
+
+      if (USE_BOOST_ICONV)
+        add_definitions(-DBOOST_LOCALE_WITH_ICONV=1)
+      else()
+        add_definitions(-DBOOST_LOCALE_WITH_WCONV=1)
+      endif()
+
+    else()
+      message(FATAL_ERROR "Support your platform here")
+    endif()
   endif()
 
-  add_definitions(
-    # Static build of Boost
-    -DBOOST_ALL_NO_LIB 
-    -DBOOST_ALL_NOLIB 
-    -DBOOST_DATE_TIME_NO_LIB 
-    -DBOOST_THREAD_BUILD_LIB
-    -DBOOST_PROGRAM_OPTIONS_NO_LIB
-    -DBOOST_REGEX_NO_LIB
-    -DBOOST_SYSTEM_NO_LIB
-    -DBOOST_LOCALE_NO_LIB
-    -DBOOST_HAS_LOCALE=1
-    )
-
-  if (CMAKE_COMPILER_IS_GNUCXX)
-    add_definitions(-isystem ${BOOST_SOURCES_DIR})
-  endif()
-
-  include_directories(
-    ${BOOST_SOURCES_DIR}
-    )
-
+  
   source_group(ThirdParty\\boost REGULAR_EXPRESSION ${BOOST_SOURCES_DIR}/.*)
 
-else()
-  add_definitions(
-    -DBOOST_HAS_LOCALE=1
-    )
 endif()
-
-
-add_definitions(
-  -DBOOST_HAS_DATE_TIME=1
-  -DBOOST_HAS_REGEX=1
-  )
--- a/Orthanc/Resources/CMake/Compiler.cmake	Wed Jul 19 14:53:59 2017 +0200
+++ b/Orthanc/Resources/CMake/Compiler.cmake	Tue Aug 22 21:46:50 2017 +0200
@@ -7,7 +7,8 @@
 endif()
 
 if (CMAKE_COMPILER_IS_GNUCXX)
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-long-long -Wno-implicit-function-declaration")  
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-long-long")
+
   # --std=c99 makes libcurl not to compile
   # -pedantic gives a lot of warnings on OpenSSL 
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -Wno-variadic-macros")
@@ -56,11 +57,27 @@
 endif()
 
 
+if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
+    ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+  # In FreeBSD/OpenBSD, the "/usr/local/" folder contains the ports and need to be imported
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include")
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/local/include")
+  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
+  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L/usr/local/lib")
+endif()
+
+
 if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
     ${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD" OR
-    ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
-  set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
-  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
+    ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
+    ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+
+  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+    # The "--no-undefined" linker flag makes the shared libraries
+    # (plugins ModalityWorklists and ServeFolders) fail to compile on OpenBSD
+    set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
+    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
+  endif()
 
   if (NOT DEFINED ENABLE_PLUGINS_VERSION_SCRIPT OR 
       ENABLE_PLUGINS_VERSION_SCRIPT)
@@ -70,22 +87,39 @@
   # Remove the "-rdynamic" option
   # http://www.mail-archive.com/cmake@cmake.org/msg08837.html
   set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
-  link_libraries(uuid pthread rt)
+  link_libraries(uuid pthread)
+
+  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+    link_libraries(rt)
+  endif()
+
+  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND
+      NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+    link_libraries(dl)
+  endif()
 
   if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
+    # The "--as-needed" linker flag is not available on FreeBSD
     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
     set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--as-needed")
     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--as-needed")
+  endif()
+
+  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" AND
+      NOT ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
+    # FreeBSD/OpenBSD have just one single interface for file
+    # handling, which is 64bit clean, so there is no need to define macro
+    # for LFS (Large File Support).
+    # https://ohse.de/uwe/articles/lfs.html
     add_definitions(
       -D_LARGEFILE64_SOURCE=1 
       -D_FILE_OFFSET_BITS=64
       )
-    link_libraries(dl)
   endif()
 
   CHECK_INCLUDE_FILES(uuid/uuid.h HAVE_UUID_H)
   if (NOT HAVE_UUID_H)
-    message(FATAL_ERROR "Please install the uuid-dev package")
+    message(FATAL_ERROR "Please install the uuid-dev package (or e2fsprogs if OpenBSD)")
   endif()
 
 elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
@@ -145,6 +179,8 @@
     message(FATAL_ERROR "Please install the uuid-dev package")
   endif()
 
+else()
+  message(FATAL_ERROR "Support your platform here")
 endif()
 
 
@@ -155,15 +191,6 @@
 endif()
 
 
-if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
-  # In FreeBSD, the "/usr/local/" folder contains the ports and need to be imported
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include")
-  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L/usr/local/lib")
-endif()
-
-
 if (DEFINED ENABLE_PROFILING AND ENABLE_PROFILING)
   if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
     message(WARNING "Enabling profiling on a non-debug build will not produce full information")