Skip to content

Build errors with clang because of -Werror #227

@hephil

Description

@hephil

Hi,

I noticed that this project sets -Werror when using Clang, which can cause build errors. I understand that the intended usage is to include the header and define your own tinyexr.cc, but since the repository also includes a CMake target (which compiles its own tinyexr.cc), it's easy to assume that linking against it is a supported use-case.

However, because -Werror is enforced internally, any outside project will break when compiling with clang.

If you don’t consider linking against the built-in target a valid use-case, feel free to close this.

Describe the issue
Project sets overly strict compiler flags for clang compiler which causes build errors when compiling the project with clang or when linking against the exposed cmake target.

The culprit is Line 44 following in CMakeLists.txt:

# Increase warning level for clang.
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT MSVC)
  set(CLANG_COMPILE_FLAGS "-Weverything -Werror -Wno-padded -Wno-c++98-compat-pedantic -Wno-documentation -Wno-unused-member-function")
  if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER 16)
    set(CLANG_COMPILE_FLAGS "${CLANG_COMPILE_FLAGS} -Wno-unsafe-buffer-usage")
  endif()
  set_source_files_properties(${TINYEXR_SOURCES} PROPERTIES COMPILE_FLAGS ${CLANG_COMPILE_FLAGS})
endif ()

To Reproduce
Simple way:

  1. Clone repo
  2. Configure with cmake and clang as compiler (I used Clang 20.1.6 x86_64-pc-windows-msvc)
  3. Observe build warnings in tinyexr.h (included by tinyexr.cc) regarding -Wununsed-macros and more promoted to errors because of -Werror

Complicated way:

  1. Setup a project with the tinyexr repo in a subdirectory and link against :
project (project LANGUAGES CXX)
add_executable(dummy main.cc)
add_subdirectoy(tinyexr)
target_link_libraries(dummy PUBLIC tinyexr)
  1. Compile the project with clang and observe above mentioned errors

Expected behavior
The project should not enforce -Werror on clang, provide an option to reliably disable -Werror from outside the project or fix the errors produced by -Werror.

Environment

  • OS: Windows 11
  • Compiler: Clang 20.1.6 x86_64-pc-windows-msvc

In the following is a minimal and naive way to fix the current warnings in tinyexr.h:

diff --git a/tinyexr.h b/tinyexr.h
index 37ca5b4..b1da5ba 100644
--- a/tinyexr.h
+++ b/tinyexr.h
@@ -89,6 +89,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 extern "C" {
 #endif
 
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-macros"
+#endif
+
 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
     defined(__i386) || defined(__i486__) || defined(__i486) ||  \
     defined(i386) || defined(__ia64__) || defined(__x86_64__)
@@ -225,6 +230,10 @@ extern "C" {
 #define TINYEXR_TILE_ROUND_DOWN (0)
 #define TINYEXR_TILE_ROUND_UP (1)
 
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
 typedef struct TEXRVersion {
   int version;    // this must be 2
   // tile format image;
@@ -651,7 +660,7 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
 #ifndef NOMINMAX
 #define NOMINMAX
 #endif
-#include <windows.h>  // for UTF-8 and memory-mapping
+#include <Windows.h>  // for UTF-8 and memory-mapping
 
 #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)
 #define TINYEXR_USE_WIN32_MMAP (1)
@@ -4421,11 +4430,11 @@ static unsigned char **AllocateImage(int num_channels,
 
 #ifdef _WIN32
 static inline std::wstring UTF8ToWchar(const std::string &str) {
-  int wstr_size =
-      MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0);
-  std::wstring wstr(wstr_size, 0);
-  MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &wstr[0],
-                      (int)wstr.size());
+  int wstr_size = MultiByteToWideChar(CP_UTF8, 0, str.data(),
+                                      static_cast<int>(str.size()), NULL, 0);
+  std::wstring wstr(static_cast<size_t>(wstr_size), 0);
+  MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()),
+                      &wstr[0], static_cast<int>(wstr.size()));
   return wstr;
 }
 #endif
@@ -6857,6 +6866,10 @@ struct MemoryMappedFile {
     }
 
     LARGE_INTEGER windows_file_size = {};
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wtautological-type-limit-compare"
+#endif
     if (!GetFileSizeEx(windows_file, &windows_file_size) ||
         static_cast<ULONGLONG>(windows_file_size.QuadPart) >
             std::numeric_limits<size_t>::max()) {
@@ -6864,6 +6877,9 @@ struct MemoryMappedFile {
       data = NULL;
       return;
     }
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
     size = static_cast<size_t>(windows_file_size.QuadPart);
 #elif defined(TINYEXR_USE_POSIX_MMAP)
     posix_descriptor = open(filename, O_RDONLY);

Have a nice day!

hephil

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions