changeset 694:8ea357435c46

fix linking against system-wide Orthanc
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 16 Jun 2025 08:14:22 +0200 (3 weeks ago)
parents 540918f7417b
children 91bb3a44573f
files Resources/CMake/DatabasesPluginConfiguration.cmake Resources/Orthanc/CMake/EmbedResources.py Resources/Orthanc/EmbedResources.py Resources/Orthanc/LinuxStandardBaseToolchain.cmake Resources/Orthanc/MinGW-W64-Toolchain32.cmake Resources/Orthanc/MinGW-W64-Toolchain64.cmake Resources/Orthanc/MinGWToolchain.cmake Resources/Orthanc/Toolchains/LinuxStandardBaseToolchain.cmake Resources/Orthanc/Toolchains/MinGW-W64-Toolchain32.cmake Resources/Orthanc/Toolchains/MinGW-W64-Toolchain64.cmake Resources/Orthanc/Toolchains/MinGWToolchain.cmake Resources/SyncOrthancFolder.py
diffstat 12 files changed, 674 insertions(+), 672 deletions(-) [+]
line wrap: on
line diff
--- a/Resources/CMake/DatabasesPluginConfiguration.cmake	Mon Jun 16 08:03:15 2025 +0200
+++ b/Resources/CMake/DatabasesPluginConfiguration.cmake	Mon Jun 16 08:14:22 2025 +0200
@@ -50,6 +50,8 @@
     set(ORTHANC_SDK_ROOT ${ORTHANC_DATABASES_ROOT}/Resources/Orthanc/Sdk-1.12.4)
   elseif (ORTHANC_SDK_VERSION STREQUAL "1.12.5")
     set(ORTHANC_SDK_ROOT ${ORTHANC_DATABASES_ROOT}/Resources/Orthanc/Sdk-1.12.5)
+  elseif (ORTHANC_SDK_VERSION STREQUAL "1.12.8")
+    set(ORTHANC_SDK_ROOT ${ORTHANC_DATABASES_ROOT}/Resources/Orthanc/Sdk-1.12.8)
   elseif (ORTHANC_SDK_VERSION STREQUAL "framework")
     set(tmp ${ORTHANC_FRAMEWORK_ROOT}/../../OrthancServer/Plugins/Include/)
     message(${tmp})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/CMake/EmbedResources.py	Mon Jun 16 08:14:22 2025 +0200
@@ -0,0 +1,446 @@
+#!/usr/bin/python
+
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2023 Osimis S.A., Belgium
+# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
+# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+import sys
+import os
+import os.path
+import pprint
+import re
+
+UPCASE_CHECK = True
+USE_SYSTEM_EXCEPTION = False
+EXCEPTION_CLASS = 'OrthancException'
+OUT_OF_RANGE_EXCEPTION = '::Orthanc::OrthancException(::Orthanc::ErrorCode_ParameterOutOfRange)'
+INEXISTENT_PATH_EXCEPTION = '::Orthanc::OrthancException(::Orthanc::ErrorCode_InexistentItem)'
+NAMESPACE = 'Orthanc.EmbeddedResources'
+FRAMEWORK_PATH = None
+
+ARGS = []
+for i in range(len(sys.argv)):
+    if not sys.argv[i].startswith('--'):
+        ARGS.append(sys.argv[i])
+    elif sys.argv[i].lower() == '--no-upcase-check':
+        UPCASE_CHECK = False
+    elif sys.argv[i].lower() == '--system-exception':
+        USE_SYSTEM_EXCEPTION = True
+        EXCEPTION_CLASS = '::std::runtime_error'
+        OUT_OF_RANGE_EXCEPTION = '%s("Parameter out of range")' % EXCEPTION_CLASS
+        INEXISTENT_PATH_EXCEPTION = '%s("Unknown path in a directory resource")' % EXCEPTION_CLASS
+    elif sys.argv[i].startswith('--namespace='):
+        NAMESPACE = sys.argv[i][sys.argv[i].find('=') + 1 : ]
+    elif sys.argv[i].startswith('--framework-path='):
+        FRAMEWORK_PATH = sys.argv[i][sys.argv[i].find('=') + 1 : ]
+
+if len(ARGS) < 2 or len(ARGS) % 2 != 0:
+    print ('Usage:')
+    print ('python %s [--no-upcase-check] [--system-exception] [--namespace=<Namespace>] <TargetBaseFilename> [ <Name> <Source> ]*' % sys.argv[0])
+    exit(-1)
+
+TARGET_BASE_FILENAME = ARGS[1]
+SOURCES = ARGS[2:]
+
+try:
+    # Make sure the destination directory exists
+    os.makedirs(os.path.normpath(os.path.join(TARGET_BASE_FILENAME, '..')))
+except:
+    pass
+
+
+#####################################################################
+## Read each resource file
+#####################################################################
+
+def CheckNoUpcase(s):
+    global UPCASE_CHECK
+    if (UPCASE_CHECK and
+        re.search('[A-Z]', s) != None):
+        raise Exception("Path in a directory with an upcase letter: %s" % s)
+
+resources = {}
+
+counter = 0
+i = 0
+while i < len(SOURCES):
+    resourceName = SOURCES[i].upper()
+    pathName = SOURCES[i + 1]
+
+    if not os.path.exists(pathName):
+        raise Exception("Non existing path: %s" % pathName)
+
+    if resourceName in resources:
+        raise Exception("Twice the same resource: " + resourceName)
+    
+    if os.path.isdir(pathName):
+        # The resource is a directory: Recursively explore its files
+        content = {}
+        for root, dirs, files in os.walk(pathName):
+            dirs.sort()
+            files.sort()
+            base = os.path.relpath(root, pathName)
+
+            # Fix issue #24 (Build fails on OSX when directory has .DS_Store files):
+            # Ignore folders whose name starts with a dot (".")
+            if base.find('/.') != -1:
+                print('Ignoring folder: %s' % root)
+                continue
+
+            for f in files:
+                if f.find('~') == -1:  # Ignore Emacs backup files
+                    if base == '.':
+                        r = f
+                    else:
+                        r = os.path.join(base, f)
+
+                    CheckNoUpcase(r)
+                    r = '/' + r.replace('\\', '/')
+                    if r in content:
+                        raise Exception("Twice the same filename (check case): " + r)
+
+                    content[r] = {
+                        'Filename' : os.path.join(root, f),
+                        'Index' : counter
+                        }
+                    counter += 1
+
+        resources[resourceName] = {
+            'Type' : 'Directory',
+            'Files' : content
+            }
+
+    elif os.path.isfile(pathName):
+        resources[resourceName] = {
+            'Type' : 'File',
+            'Index' : counter,
+            'Filename' : pathName
+            }
+        counter += 1
+
+    else:
+        raise Exception("Not a regular file, nor a directory: " + pathName)
+
+    i += 2
+
+#pprint.pprint(resources)
+
+
+#####################################################################
+## Write .h header
+#####################################################################
+
+header = open(TARGET_BASE_FILENAME + '.h', 'w')
+
+header.write("""
+#pragma once
+
+#include <string>
+#include <list>
+
+#if defined(_MSC_VER)
+#  pragma warning(disable: 4065)  // "Switch statement contains 'default' but no 'case' labels"
+#endif
+
+""")
+
+
+for ns in NAMESPACE.split('.'):
+    header.write('namespace %s {\n' % ns)
+    
+
+header.write("""
+    enum FileResourceId
+    {
+""")
+
+isFirst = True
+for name in resources:
+    if resources[name]['Type'] == 'File':
+        if isFirst:
+            isFirst = False
+        else:    
+            header.write(',\n')
+        header.write('      %s' % name)
+
+header.write("""
+    };
+
+    enum DirectoryResourceId
+    {
+""")
+
+isFirst = True
+for name in resources:
+    if resources[name]['Type'] == 'Directory':
+        if isFirst:
+            isFirst = False
+        else:    
+            header.write(',\n')
+        header.write('      %s' % name)
+
+header.write("""
+    };
+
+    const void* GetFileResourceBuffer(FileResourceId id);
+    size_t GetFileResourceSize(FileResourceId id);
+    void GetFileResource(std::string& result, FileResourceId id);
+
+    const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path);
+    size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path);
+    void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path);
+
+    void ListResources(std::list<std::string>& result, DirectoryResourceId id);
+
+""")
+
+
+for ns in NAMESPACE.split('.'):
+    header.write('}\n')
+
+header.close()
+
+
+
+#####################################################################
+## Write the resource content in the .cpp source
+#####################################################################
+
+PYTHON_MAJOR_VERSION = sys.version_info[0]
+
+def WriteResource(cpp, item):
+    cpp.write('    static const uint8_t resource%dBuffer[] = {' % item['Index'])
+
+    f = open(item['Filename'], "rb")
+    content = f.read()
+    f.close()
+
+    # http://stackoverflow.com/a/1035360
+    pos = 0
+    buffer = []  # instead of appending a few bytes at a time to the cpp file, 
+                 # we first append each chunk to a list, join it and write it 
+                 # to the file.  We've measured that it was 2-3 times faster in python3.
+                 # Note that speed is important since if generation is too slow,
+                 # cmake might try to compile the EmbeddedResources.cpp file while it is
+                 # still being generated !
+    for b in content:
+        if PYTHON_MAJOR_VERSION == 2:
+            c = ord(b[0])
+        else:
+            c = b
+
+        if pos > 0:
+            buffer.append(",")
+
+        if (pos % 16) == 0:
+            buffer.append("\n")
+
+        if c < 0:
+            raise Exception("Internal error")
+
+        buffer.append("0x%02x" % c)
+        pos += 1
+
+    cpp.write("".join(buffer))
+    # Zero-size array are disallowed, so we put one single void character in it.
+    if pos == 0:
+        cpp.write('  0')
+
+    cpp.write('  };\n')
+    cpp.write('    static const size_t resource%dSize = %d;\n' % (item['Index'], pos))
+
+
+cpp = open(TARGET_BASE_FILENAME + '.cpp', 'w')
+
+cpp.write('#include "%s.h"\n' % os.path.basename(TARGET_BASE_FILENAME))
+
+if USE_SYSTEM_EXCEPTION:
+    cpp.write('#include <stdexcept>')
+elif FRAMEWORK_PATH != None:
+    cpp.write('#include "%s/OrthancException.h"' % FRAMEWORK_PATH)
+else:
+    cpp.write('#include <OrthancException.h>')
+
+cpp.write("""
+#include <stdint.h>
+#include <string.h>
+
+""")
+
+for ns in NAMESPACE.split('.'):
+    cpp.write('namespace %s {\n' % ns)
+
+
+for name in resources:
+    if resources[name]['Type'] == 'File':
+        WriteResource(cpp, resources[name])
+    else:
+        for f in resources[name]['Files']:
+            WriteResource(cpp, resources[name]['Files'][f])
+
+
+
+#####################################################################
+## Write the accessors to the file resources in .cpp
+#####################################################################
+
+cpp.write("""
+    const void* GetFileResourceBuffer(FileResourceId id)
+    {
+      switch (id)
+      {
+""")
+for name in resources:
+    if resources[name]['Type'] == 'File':
+        cpp.write('      case %s:\n' % name)
+        cpp.write('        return resource%dBuffer;\n' % resources[name]['Index'])
+
+cpp.write("""
+      default:
+        throw %s;
+      }
+    }
+
+    size_t GetFileResourceSize(FileResourceId id)
+    {
+      switch (id)
+      {
+""" % OUT_OF_RANGE_EXCEPTION)
+
+for name in resources:
+    if resources[name]['Type'] == 'File':
+        cpp.write('      case %s:\n' % name)
+        cpp.write('        return resource%dSize;\n' % resources[name]['Index'])
+
+cpp.write("""
+      default:
+        throw %s;
+      }
+    }
+""" % OUT_OF_RANGE_EXCEPTION)
+
+
+
+#####################################################################
+## Write the accessors to the directory resources in .cpp
+#####################################################################
+
+cpp.write("""
+    const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path)
+    {
+      switch (id)
+      {
+""")
+
+for name in resources:
+    if resources[name]['Type'] == 'Directory':
+        cpp.write('      case %s:\n' % name)
+        isFirst = True
+        for path in resources[name]['Files']:
+            cpp.write('        if (!strcmp(path, "%s"))\n' % path)
+            cpp.write('          return resource%dBuffer;\n' % resources[name]['Files'][path]['Index'])
+        cpp.write('        throw %s;\n\n' % INEXISTENT_PATH_EXCEPTION)
+
+cpp.write("""      default:
+        throw %s;
+      }
+    }
+
+    size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path)
+    {
+      switch (id)
+      {
+""" % OUT_OF_RANGE_EXCEPTION)
+
+for name in resources:
+    if resources[name]['Type'] == 'Directory':
+        cpp.write('      case %s:\n' % name)
+        isFirst = True
+        for path in resources[name]['Files']:
+            cpp.write('        if (!strcmp(path, "%s"))\n' % path)
+            cpp.write('          return resource%dSize;\n' % resources[name]['Files'][path]['Index'])
+        cpp.write('        throw %s;\n\n' % INEXISTENT_PATH_EXCEPTION)
+
+cpp.write("""      default:
+        throw %s;
+      }
+    }
+""" % OUT_OF_RANGE_EXCEPTION)
+
+
+
+
+#####################################################################
+## List the resources in a directory
+#####################################################################
+
+cpp.write("""
+    void ListResources(std::list<std::string>& result, DirectoryResourceId id)
+    {
+      result.clear();
+
+      switch (id)
+      {
+""")
+
+for name in resources:
+    if resources[name]['Type'] == 'Directory':
+        cpp.write('      case %s:\n' % name)
+        for path in sorted(resources[name]['Files']):
+            cpp.write('        result.push_back("%s");\n' % path)
+        cpp.write('        break;\n\n')
+
+cpp.write("""      default:
+        throw %s;
+      }
+    }
+""" % OUT_OF_RANGE_EXCEPTION)
+
+
+
+
+#####################################################################
+## Write the convenience wrappers in .cpp
+#####################################################################
+
+cpp.write("""
+    void GetFileResource(std::string& result, FileResourceId id)
+    {
+      size_t size = GetFileResourceSize(id);
+      result.resize(size);
+      if (size > 0)
+        memcpy(&result[0], GetFileResourceBuffer(id), size);
+    }
+
+    void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path)
+    {
+      size_t size = GetDirectoryResourceSize(id, path);
+      result.resize(size);
+      if (size > 0)
+        memcpy(&result[0], GetDirectoryResourceBuffer(id, path), size);
+    }
+""")
+
+
+for ns in NAMESPACE.split('.'):
+    cpp.write('}\n')
+
+cpp.close()
--- a/Resources/Orthanc/EmbedResources.py	Mon Jun 16 08:03:15 2025 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,446 +0,0 @@
-#!/usr/bin/python
-
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2023 Osimis S.A., Belgium
-# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
-# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-import sys
-import os
-import os.path
-import pprint
-import re
-
-UPCASE_CHECK = True
-USE_SYSTEM_EXCEPTION = False
-EXCEPTION_CLASS = 'OrthancException'
-OUT_OF_RANGE_EXCEPTION = '::Orthanc::OrthancException(::Orthanc::ErrorCode_ParameterOutOfRange)'
-INEXISTENT_PATH_EXCEPTION = '::Orthanc::OrthancException(::Orthanc::ErrorCode_InexistentItem)'
-NAMESPACE = 'Orthanc.EmbeddedResources'
-FRAMEWORK_PATH = None
-
-ARGS = []
-for i in range(len(sys.argv)):
-    if not sys.argv[i].startswith('--'):
-        ARGS.append(sys.argv[i])
-    elif sys.argv[i].lower() == '--no-upcase-check':
-        UPCASE_CHECK = False
-    elif sys.argv[i].lower() == '--system-exception':
-        USE_SYSTEM_EXCEPTION = True
-        EXCEPTION_CLASS = '::std::runtime_error'
-        OUT_OF_RANGE_EXCEPTION = '%s("Parameter out of range")' % EXCEPTION_CLASS
-        INEXISTENT_PATH_EXCEPTION = '%s("Unknown path in a directory resource")' % EXCEPTION_CLASS
-    elif sys.argv[i].startswith('--namespace='):
-        NAMESPACE = sys.argv[i][sys.argv[i].find('=') + 1 : ]
-    elif sys.argv[i].startswith('--framework-path='):
-        FRAMEWORK_PATH = sys.argv[i][sys.argv[i].find('=') + 1 : ]
-
-if len(ARGS) < 2 or len(ARGS) % 2 != 0:
-    print ('Usage:')
-    print ('python %s [--no-upcase-check] [--system-exception] [--namespace=<Namespace>] <TargetBaseFilename> [ <Name> <Source> ]*' % sys.argv[0])
-    exit(-1)
-
-TARGET_BASE_FILENAME = ARGS[1]
-SOURCES = ARGS[2:]
-
-try:
-    # Make sure the destination directory exists
-    os.makedirs(os.path.normpath(os.path.join(TARGET_BASE_FILENAME, '..')))
-except:
-    pass
-
-
-#####################################################################
-## Read each resource file
-#####################################################################
-
-def CheckNoUpcase(s):
-    global UPCASE_CHECK
-    if (UPCASE_CHECK and
-        re.search('[A-Z]', s) != None):
-        raise Exception("Path in a directory with an upcase letter: %s" % s)
-
-resources = {}
-
-counter = 0
-i = 0
-while i < len(SOURCES):
-    resourceName = SOURCES[i].upper()
-    pathName = SOURCES[i + 1]
-
-    if not os.path.exists(pathName):
-        raise Exception("Non existing path: %s" % pathName)
-
-    if resourceName in resources:
-        raise Exception("Twice the same resource: " + resourceName)
-    
-    if os.path.isdir(pathName):
-        # The resource is a directory: Recursively explore its files
-        content = {}
-        for root, dirs, files in os.walk(pathName):
-            dirs.sort()
-            files.sort()
-            base = os.path.relpath(root, pathName)
-
-            # Fix issue #24 (Build fails on OSX when directory has .DS_Store files):
-            # Ignore folders whose name starts with a dot (".")
-            if base.find('/.') != -1:
-                print('Ignoring folder: %s' % root)
-                continue
-
-            for f in files:
-                if f.find('~') == -1:  # Ignore Emacs backup files
-                    if base == '.':
-                        r = f
-                    else:
-                        r = os.path.join(base, f)
-
-                    CheckNoUpcase(r)
-                    r = '/' + r.replace('\\', '/')
-                    if r in content:
-                        raise Exception("Twice the same filename (check case): " + r)
-
-                    content[r] = {
-                        'Filename' : os.path.join(root, f),
-                        'Index' : counter
-                        }
-                    counter += 1
-
-        resources[resourceName] = {
-            'Type' : 'Directory',
-            'Files' : content
-            }
-
-    elif os.path.isfile(pathName):
-        resources[resourceName] = {
-            'Type' : 'File',
-            'Index' : counter,
-            'Filename' : pathName
-            }
-        counter += 1
-
-    else:
-        raise Exception("Not a regular file, nor a directory: " + pathName)
-
-    i += 2
-
-#pprint.pprint(resources)
-
-
-#####################################################################
-## Write .h header
-#####################################################################
-
-header = open(TARGET_BASE_FILENAME + '.h', 'w')
-
-header.write("""
-#pragma once
-
-#include <string>
-#include <list>
-
-#if defined(_MSC_VER)
-#  pragma warning(disable: 4065)  // "Switch statement contains 'default' but no 'case' labels"
-#endif
-
-""")
-
-
-for ns in NAMESPACE.split('.'):
-    header.write('namespace %s {\n' % ns)
-    
-
-header.write("""
-    enum FileResourceId
-    {
-""")
-
-isFirst = True
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        if isFirst:
-            isFirst = False
-        else:    
-            header.write(',\n')
-        header.write('      %s' % name)
-
-header.write("""
-    };
-
-    enum DirectoryResourceId
-    {
-""")
-
-isFirst = True
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        if isFirst:
-            isFirst = False
-        else:    
-            header.write(',\n')
-        header.write('      %s' % name)
-
-header.write("""
-    };
-
-    const void* GetFileResourceBuffer(FileResourceId id);
-    size_t GetFileResourceSize(FileResourceId id);
-    void GetFileResource(std::string& result, FileResourceId id);
-
-    const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path);
-    size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path);
-    void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path);
-
-    void ListResources(std::list<std::string>& result, DirectoryResourceId id);
-
-""")
-
-
-for ns in NAMESPACE.split('.'):
-    header.write('}\n')
-
-header.close()
-
-
-
-#####################################################################
-## Write the resource content in the .cpp source
-#####################################################################
-
-PYTHON_MAJOR_VERSION = sys.version_info[0]
-
-def WriteResource(cpp, item):
-    cpp.write('    static const uint8_t resource%dBuffer[] = {' % item['Index'])
-
-    f = open(item['Filename'], "rb")
-    content = f.read()
-    f.close()
-
-    # http://stackoverflow.com/a/1035360
-    pos = 0
-    buffer = []  # instead of appending a few bytes at a time to the cpp file, 
-                 # we first append each chunk to a list, join it and write it 
-                 # to the file.  We've measured that it was 2-3 times faster in python3.
-                 # Note that speed is important since if generation is too slow,
-                 # cmake might try to compile the EmbeddedResources.cpp file while it is
-                 # still being generated !
-    for b in content:
-        if PYTHON_MAJOR_VERSION == 2:
-            c = ord(b[0])
-        else:
-            c = b
-
-        if pos > 0:
-            buffer.append(",")
-
-        if (pos % 16) == 0:
-            buffer.append("\n")
-
-        if c < 0:
-            raise Exception("Internal error")
-
-        buffer.append("0x%02x" % c)
-        pos += 1
-
-    cpp.write("".join(buffer))
-    # Zero-size array are disallowed, so we put one single void character in it.
-    if pos == 0:
-        cpp.write('  0')
-
-    cpp.write('  };\n')
-    cpp.write('    static const size_t resource%dSize = %d;\n' % (item['Index'], pos))
-
-
-cpp = open(TARGET_BASE_FILENAME + '.cpp', 'w')
-
-cpp.write('#include "%s.h"\n' % os.path.basename(TARGET_BASE_FILENAME))
-
-if USE_SYSTEM_EXCEPTION:
-    cpp.write('#include <stdexcept>')
-elif FRAMEWORK_PATH != None:
-    cpp.write('#include "%s/OrthancException.h"' % FRAMEWORK_PATH)
-else:
-    cpp.write('#include <OrthancException.h>')
-
-cpp.write("""
-#include <stdint.h>
-#include <string.h>
-
-""")
-
-for ns in NAMESPACE.split('.'):
-    cpp.write('namespace %s {\n' % ns)
-
-
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        WriteResource(cpp, resources[name])
-    else:
-        for f in resources[name]['Files']:
-            WriteResource(cpp, resources[name]['Files'][f])
-
-
-
-#####################################################################
-## Write the accessors to the file resources in .cpp
-#####################################################################
-
-cpp.write("""
-    const void* GetFileResourceBuffer(FileResourceId id)
-    {
-      switch (id)
-      {
-""")
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        cpp.write('      case %s:\n' % name)
-        cpp.write('        return resource%dBuffer;\n' % resources[name]['Index'])
-
-cpp.write("""
-      default:
-        throw %s;
-      }
-    }
-
-    size_t GetFileResourceSize(FileResourceId id)
-    {
-      switch (id)
-      {
-""" % OUT_OF_RANGE_EXCEPTION)
-
-for name in resources:
-    if resources[name]['Type'] == 'File':
-        cpp.write('      case %s:\n' % name)
-        cpp.write('        return resource%dSize;\n' % resources[name]['Index'])
-
-cpp.write("""
-      default:
-        throw %s;
-      }
-    }
-""" % OUT_OF_RANGE_EXCEPTION)
-
-
-
-#####################################################################
-## Write the accessors to the directory resources in .cpp
-#####################################################################
-
-cpp.write("""
-    const void* GetDirectoryResourceBuffer(DirectoryResourceId id, const char* path)
-    {
-      switch (id)
-      {
-""")
-
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        cpp.write('      case %s:\n' % name)
-        isFirst = True
-        for path in resources[name]['Files']:
-            cpp.write('        if (!strcmp(path, "%s"))\n' % path)
-            cpp.write('          return resource%dBuffer;\n' % resources[name]['Files'][path]['Index'])
-        cpp.write('        throw %s;\n\n' % INEXISTENT_PATH_EXCEPTION)
-
-cpp.write("""      default:
-        throw %s;
-      }
-    }
-
-    size_t GetDirectoryResourceSize(DirectoryResourceId id, const char* path)
-    {
-      switch (id)
-      {
-""" % OUT_OF_RANGE_EXCEPTION)
-
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        cpp.write('      case %s:\n' % name)
-        isFirst = True
-        for path in resources[name]['Files']:
-            cpp.write('        if (!strcmp(path, "%s"))\n' % path)
-            cpp.write('          return resource%dSize;\n' % resources[name]['Files'][path]['Index'])
-        cpp.write('        throw %s;\n\n' % INEXISTENT_PATH_EXCEPTION)
-
-cpp.write("""      default:
-        throw %s;
-      }
-    }
-""" % OUT_OF_RANGE_EXCEPTION)
-
-
-
-
-#####################################################################
-## List the resources in a directory
-#####################################################################
-
-cpp.write("""
-    void ListResources(std::list<std::string>& result, DirectoryResourceId id)
-    {
-      result.clear();
-
-      switch (id)
-      {
-""")
-
-for name in resources:
-    if resources[name]['Type'] == 'Directory':
-        cpp.write('      case %s:\n' % name)
-        for path in sorted(resources[name]['Files']):
-            cpp.write('        result.push_back("%s");\n' % path)
-        cpp.write('        break;\n\n')
-
-cpp.write("""      default:
-        throw %s;
-      }
-    }
-""" % OUT_OF_RANGE_EXCEPTION)
-
-
-
-
-#####################################################################
-## Write the convenience wrappers in .cpp
-#####################################################################
-
-cpp.write("""
-    void GetFileResource(std::string& result, FileResourceId id)
-    {
-      size_t size = GetFileResourceSize(id);
-      result.resize(size);
-      if (size > 0)
-        memcpy(&result[0], GetFileResourceBuffer(id), size);
-    }
-
-    void GetDirectoryResource(std::string& result, DirectoryResourceId id, const char* path)
-    {
-      size_t size = GetDirectoryResourceSize(id, path);
-      result.resize(size);
-      if (size > 0)
-        memcpy(&result[0], GetDirectoryResourceBuffer(id, path), size);
-    }
-""")
-
-
-for ns in NAMESPACE.split('.'):
-    cpp.write('}\n')
-
-cpp.close()
--- a/Resources/Orthanc/LinuxStandardBaseToolchain.cmake	Mon Jun 16 08:03:15 2025 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2023 Osimis S.A., Belgium
-# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
-# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-#
-# Full build, as used on the BuildBot CIS:
-#
-#   $ LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake ../OrthancServer/ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON -DUSE_LEGACY_LIBICU=ON -DUSE_LEGACY_BOOST=ON -DBOOST_LOCALE_BACKEND=icu -DENABLE_PKCS11=ON -G Ninja
-#
-# Or, more lightweight version (without libp11 and ICU):
-#
-#   $ LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake ../OrthancServer/ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON -DUSE_LEGACY_BOOST=ON -G Ninja
-#
-
-INCLUDE(CMakeForceCompiler)
-
-SET(LSB_PATH $ENV{LSB_PATH} CACHE STRING "")
-SET(LSB_CC $ENV{LSB_CC} CACHE STRING "")
-SET(LSB_CXX $ENV{LSB_CXX} CACHE STRING "")
-SET(LSB_TARGET_VERSION "4.0" CACHE STRING "")
-
-IF ("${LSB_PATH}" STREQUAL "")
-  SET(LSB_PATH "/opt/lsb")
-ENDIF()
-
-IF (EXISTS ${LSB_PATH}/lib64)
-  SET(LSB_TARGET_PROCESSOR "x86_64")
-  SET(LSB_LIBPATH ${LSB_PATH}/lib64-${LSB_TARGET_VERSION})
-ELSEIF (EXISTS ${LSB_PATH}/lib)
-  SET(LSB_TARGET_PROCESSOR "x86")
-  SET(LSB_LIBPATH ${LSB_PATH}/lib-${LSB_TARGET_VERSION})
-ELSE()
-  MESSAGE(FATAL_ERROR "Unable to detect the target processor architecture. Check the LSB_PATH environment variable.")
-ENDIF()
-
-SET(LSB_CPPPATH ${LSB_PATH}/include)
-SET(PKG_CONFIG_PATH ${LSB_LIBPATH}/pkgconfig/)
-
-# the name of the target operating system
-SET(CMAKE_SYSTEM_NAME Linux)
-SET(CMAKE_SYSTEM_VERSION LinuxStandardBase)
-SET(CMAKE_SYSTEM_PROCESSOR ${LSB_TARGET_PROCESSOR})
-
-# which compilers to use for C and C++
-SET(CMAKE_C_COMPILER ${LSB_PATH}/bin/lsbcc)
-
-if (${CMAKE_VERSION} VERSION_LESS "3.6.0") 
-  CMAKE_FORCE_CXX_COMPILER(${LSB_PATH}/bin/lsbc++ GNU)
-else()
-  SET(CMAKE_CXX_COMPILER ${LSB_PATH}/bin/lsbc++)
-endif()
-
-# here is the target environment located
-SET(CMAKE_FIND_ROOT_PATH ${LSB_PATH})
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
-SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
-
-SET(CMAKE_CROSSCOMPILING OFF)
-
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -I${LSB_PATH}/include" CACHE INTERNAL "" FORCE)
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -nostdinc++ -I${LSB_PATH}/include -I${LSB_PATH}/include/c++ -I${LSB_PATH}/include/c++/backward" CACHE INTERNAL "" FORCE)
-SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
-SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
-
-if (NOT "${LSB_CXX}" STREQUAL "")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cxx=${LSB_CXX}")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
-  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
-endif()
-
-if (NOT "${LSB_CC}" STREQUAL "")
-  SET(CMAKE_C_FLAGS "${CMAKE_CC_FLAGS} --lsb-cc=${LSB_CC}")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cc=${LSB_CC}")
-  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
-  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
-endif()
-
--- a/Resources/Orthanc/MinGW-W64-Toolchain32.cmake	Mon Jun 16 08:03:15 2025 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2023 Osimis S.A., Belgium
-# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
-# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
-set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
-set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- a/Resources/Orthanc/MinGW-W64-Toolchain64.cmake	Mon Jun 16 08:03:15 2025 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2023 Osimis S.A., Belgium
-# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
-# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
-set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
-set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- a/Resources/Orthanc/MinGWToolchain.cmake	Mon Jun 16 08:03:15 2025 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-# Orthanc - A Lightweight, RESTful DICOM Store
-# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
-# Department, University Hospital of Liege, Belgium
-# Copyright (C) 2017-2023 Osimis S.A., Belgium
-# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
-# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
-#
-# This program is free software: you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public License
-# as published by the Free Software Foundation, either version 3 of
-# the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program. If not, see
-# <http://www.gnu.org/licenses/>.
-
-
-# the name of the target operating system
-set(CMAKE_SYSTEM_NAME Windows)
-
-# which compilers to use for C and C++
-set(CMAKE_C_COMPILER i586-mingw32msvc-gcc)
-set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++)
-set(CMAKE_RC_COMPILER i586-mingw32msvc-windres)
-
-# here is the target environment located
-set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc)
-
-# adjust the default behaviour of the FIND_XXX() commands:
-# search headers and libraries in the target environment, search 
-# programs in the host environment
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTACK_SIZE_PARAM_IS_A_RESERVATION=0x10000" CACHE INTERNAL "" FORCE)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTACK_SIZE_PARAM_IS_A_RESERVATION=0x10000" CACHE INTERNAL "" FORCE)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/Toolchains/LinuxStandardBaseToolchain.cmake	Mon Jun 16 08:14:22 2025 +0200
@@ -0,0 +1,101 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2023 Osimis S.A., Belgium
+# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
+# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+#
+# Full build, as used on the BuildBot CIS:
+#
+#   $ LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake ../OrthancServer/ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON -DUSE_LEGACY_LIBICU=ON -DUSE_LEGACY_BOOST=ON -DBOOST_LOCALE_BACKEND=icu -DENABLE_PKCS11=ON -G Ninja
+#
+# Or, more lightweight version (without libp11 and ICU):
+#
+#   $ LSB_CC=gcc-4.8 LSB_CXX=g++-4.8 cmake ../OrthancServer/ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake -DUSE_LEGACY_JSONCPP=ON -DUSE_LEGACY_BOOST=ON -G Ninja
+#
+
+INCLUDE(CMakeForceCompiler)
+
+SET(LSB_PATH $ENV{LSB_PATH} CACHE STRING "")
+SET(LSB_CC $ENV{LSB_CC} CACHE STRING "")
+SET(LSB_CXX $ENV{LSB_CXX} CACHE STRING "")
+SET(LSB_TARGET_VERSION "4.0" CACHE STRING "")
+
+IF ("${LSB_PATH}" STREQUAL "")
+  SET(LSB_PATH "/opt/lsb")
+ENDIF()
+
+IF (EXISTS ${LSB_PATH}/lib64)
+  SET(LSB_TARGET_PROCESSOR "x86_64")
+  SET(LSB_LIBPATH ${LSB_PATH}/lib64-${LSB_TARGET_VERSION})
+ELSEIF (EXISTS ${LSB_PATH}/lib)
+  SET(LSB_TARGET_PROCESSOR "x86")
+  SET(LSB_LIBPATH ${LSB_PATH}/lib-${LSB_TARGET_VERSION})
+ELSE()
+  MESSAGE(FATAL_ERROR "Unable to detect the target processor architecture. Check the LSB_PATH environment variable.")
+ENDIF()
+
+SET(LSB_CPPPATH ${LSB_PATH}/include)
+SET(PKG_CONFIG_PATH ${LSB_LIBPATH}/pkgconfig/)
+
+# the name of the target operating system
+SET(CMAKE_SYSTEM_NAME Linux)
+SET(CMAKE_SYSTEM_VERSION LinuxStandardBase)
+SET(CMAKE_SYSTEM_PROCESSOR ${LSB_TARGET_PROCESSOR})
+
+# which compilers to use for C and C++
+SET(CMAKE_C_COMPILER ${LSB_PATH}/bin/lsbcc)
+
+if (${CMAKE_VERSION} VERSION_LESS "3.6.0") 
+  CMAKE_FORCE_CXX_COMPILER(${LSB_PATH}/bin/lsbc++ GNU)
+else()
+  SET(CMAKE_CXX_COMPILER ${LSB_PATH}/bin/lsbc++)
+endif()
+
+# here is the target environment located
+SET(CMAKE_FIND_ROOT_PATH ${LSB_PATH})
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER)
+
+SET(CMAKE_CROSSCOMPILING OFF)
+
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -I${LSB_PATH}/include" CACHE INTERNAL "" FORCE)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -nostdinc++ -I${LSB_PATH}/include -I${LSB_PATH}/include/c++ -I${LSB_PATH}/include/c++/backward" CACHE INTERNAL "" FORCE)
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-target-version=${LSB_TARGET_VERSION} -L${LSB_LIBPATH} --lsb-besteffort" CACHE INTERNAL "" FORCE)
+
+if (NOT "${LSB_CXX}" STREQUAL "")
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cxx=${LSB_CXX}")
+  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
+  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cxx=${LSB_CXX}")
+endif()
+
+if (NOT "${LSB_CC}" STREQUAL "")
+  SET(CMAKE_C_FLAGS "${CMAKE_CC_FLAGS} --lsb-cc=${LSB_CC}")
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --lsb-cc=${LSB_CC}")
+  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
+  SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --lsb-cc=${LSB_CC}")
+endif()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/Toolchains/MinGW-W64-Toolchain32.cmake	Mon Jun 16 08:14:22 2025 +0200
@@ -0,0 +1,39 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2023 Osimis S.A., Belgium
+# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
+# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+# the name of the target operating system
+set(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
+set(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
+set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
+
+# here is the target environment located
+set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/Toolchains/MinGW-W64-Toolchain64.cmake	Mon Jun 16 08:14:22 2025 +0200
@@ -0,0 +1,39 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2023 Osimis S.A., Belgium
+# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
+# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+# the name of the target operating system
+set(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
+set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
+set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
+
+# here is the target environment located
+set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Orthanc/Toolchains/MinGWToolchain.cmake	Mon Jun 16 08:14:22 2025 +0200
@@ -0,0 +1,42 @@
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017-2023 Osimis S.A., Belgium
+# Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
+# Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+
+# the name of the target operating system
+set(CMAKE_SYSTEM_NAME Windows)
+
+# which compilers to use for C and C++
+set(CMAKE_C_COMPILER i586-mingw32msvc-gcc)
+set(CMAKE_CXX_COMPILER i586-mingw32msvc-g++)
+set(CMAKE_RC_COMPILER i586-mingw32msvc-windres)
+
+# here is the target environment located
+set(CMAKE_FIND_ROOT_PATH /usr/i586-mingw32msvc)
+
+# adjust the default behaviour of the FIND_XXX() commands:
+# search headers and libraries in the target environment, search 
+# programs in the host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTACK_SIZE_PARAM_IS_A_RESERVATION=0x10000" CACHE INTERNAL "" FORCE)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTACK_SIZE_PARAM_IS_A_RESERVATION=0x10000" CACHE INTERNAL "" FORCE)
--- a/Resources/SyncOrthancFolder.py	Mon Jun 16 08:03:15 2025 +0200
+++ b/Resources/SyncOrthancFolder.py	Mon Jun 16 08:14:22 2025 +0200
@@ -29,11 +29,11 @@
     ('default', 'OrthancFramework/Resources/CMake/GoogleTestConfiguration.cmake', 'CMake'),
     ('default', 'OrthancFramework/Resources/CMake/OpenSslConfiguration.cmake', 'CMake'),
     ('default', 'OrthancFramework/Resources/CMake/ProtobufConfiguration.cmake', 'CMake'),
-    ('default', 'OrthancFramework/Resources/EmbedResources.py', '.'),
-    ('default', 'OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake', '.'),
-    ('default', 'OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake', '.'),
-    ('default', 'OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake', '.'),
-    ('default', 'OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake', '.'),
+    ('default', 'OrthancFramework/Resources/EmbedResources.py', 'CMake'),
+    ('default', 'OrthancFramework/Resources/Toolchains/LinuxStandardBaseToolchain.cmake', 'Toolchains'),
+    ('default', 'OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain32.cmake', 'Toolchains'),
+    ('default', 'OrthancFramework/Resources/Toolchains/MinGW-W64-Toolchain64.cmake', 'Toolchains'),
+    ('default', 'OrthancFramework/Resources/Toolchains/MinGWToolchain.cmake', 'Toolchains'),
     ('default', 'OrthancServer/Plugins/Samples/Common/ExportedSymbolsPlugins.list', 'Plugins'),
     ('default', 'OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp', 'Plugins'),
     ('default', 'OrthancServer/Plugins/Samples/Common/OrthancPluginCppWrapper.h', 'Plugins'),