diff --git a/cmake/CompilerChecks.cmake b/cmake/CompilerChecks.cmake index 4bd75d39..71f08127 100644 --- a/cmake/CompilerChecks.cmake +++ b/cmake/CompilerChecks.cmake @@ -145,16 +145,40 @@ foreach(flag ${test_flags}) endif (${test_c_flag}) endforeach(flag ${test_flags}) -# Compile C files as C++ for compatibility checking -if(cxx-compat-mode) - if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR - CMAKE_C_COMPILER_ID MATCHES "Clang") - # -x c++ forces C++ mode, -std=c++17 for modern C++ compliance - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -x c++ -std=c++17") - message(STATUS "C++ compatibility mode enabled: compiling C files as C++17") - elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") - # /TP forces C++ mode for all source files - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /TP /std:c++17") - message(STATUS "C++ compatibility mode enabled: compiling C files as C++17") +# Function to compile a target's C sources as C++ for compatibility checking +# This is a better approach than modifying CMAKE_C_FLAGS globally, as it: +# - Doesn't break CMake's feature detection tests +# - Uses proper target properties instead of global flags +# - Follows CMake best practices +function(tiff_target_compile_as_cxx target_name) + if(NOT cxx-compat-mode) + return() endif() -endif() + + # Get all source files for the target + get_target_property(target_sources ${target_name} SOURCES) + + # Filter for C source files (*.c) + set(c_sources "") + foreach(source ${target_sources}) + if(source MATCHES "\\.c$") + list(APPEND c_sources ${source}) + endif() + endforeach() + + if(c_sources) + # Set these C files to be compiled as C++ + set_source_files_properties(${c_sources} + PROPERTIES + LANGUAGE CXX + ) + # Use target properties for C++ standard (more portable than COMPILE_FLAGS) + set_target_properties(${target_name} + PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS OFF + ) + message(STATUS "C++ compatibility mode: compiling ${target_name} C sources as C++17") + endif() +endfunction() diff --git a/contrib/addtiffo/CMakeLists.txt b/contrib/addtiffo/CMakeLists.txt index cbb30ae8..25e62f74 100644 --- a/contrib/addtiffo/CMakeLists.txt +++ b/contrib/addtiffo/CMakeLists.txt @@ -26,6 +26,9 @@ add_executable(addtiffo addtiffo.c tif_overview.c tif_ovrcache.c tif_ovrcache.h) set_target_properties(addtiffo PROPERTIES LINKER_LANGUAGE CXX) target_link_libraries(addtiffo tiff tiff_port) +# Apply C++ compatibility mode if enabled +tiff_target_compile_as_cxx(addtiffo) + if(WEBP_SUPPORT AND EMSCRIPTEN) # Emscripten is pretty finnicky about linker flags. # It needs --shared-memory if and only if atomics or bulk-memory is used. diff --git a/contrib/addtiffo/addtiffo.c b/contrib/addtiffo/addtiffo.c index a4ff19b3..687a1741 100644 --- a/contrib/addtiffo/addtiffo.c +++ b/contrib/addtiffo/addtiffo.c @@ -60,13 +60,11 @@ */ #include "tiffio.h" +#include "tif_ovrcache.h" #include #include #include -void TIFFBuildOverviews(TIFF *, int, int *, int, const char *, - int (*)(double, void *), void *); - /************************************************************************/ /* main() */ /************************************************************************/ diff --git a/contrib/addtiffo/tif_overview.c b/contrib/addtiffo/tif_overview.c index 0dff4a32..2711bd04 100644 --- a/contrib/addtiffo/tif_overview.c +++ b/contrib/addtiffo/tif_overview.c @@ -67,8 +67,17 @@ #define TIFF_DIR_MAX 65534 -void TIFFBuildOverviews(TIFF *, int, int *, int, const char *, - int (*)(double, void *), void *); +#ifdef __cplusplus +extern "C" +{ +#endif + + void TIFFBuildOverviews(TIFF *, int, int *, int, const char *, + int (*)(double, void *), void *); + +#ifdef __cplusplus +} +#endif /************************************************************************/ /* TIFF_WriteOverview() */ diff --git a/contrib/dbs/CMakeLists.txt b/contrib/dbs/CMakeLists.txt index 94e7ae55..869c726e 100644 --- a/contrib/dbs/CMakeLists.txt +++ b/contrib/dbs/CMakeLists.txt @@ -38,6 +38,11 @@ add_executable(tiff-rgb tiff-rgb.c) set_target_properties(tiff-rgb PROPERTIES LINKER_LANGUAGE CXX) target_link_libraries(tiff-rgb tiff tiff_port ${CMath_LIBRARIES}) +# Apply C++ compatibility mode to all contrib/dbs targets if enabled +foreach(target tiff-bi tiff-grayscale tiff-palette tiff-rgb) + tiff_target_compile_as_cxx(${target}) +endforeach() + if(WEBP_SUPPORT AND EMSCRIPTEN) # Emscripten is pretty finnicky about linker flags. # It needs --shared-memory if and only if atomics or bulk-memory is used. diff --git a/contrib/iptcutil/CMakeLists.txt b/contrib/iptcutil/CMakeLists.txt index 8f453cb5..165431dd 100644 --- a/contrib/iptcutil/CMakeLists.txt +++ b/contrib/iptcutil/CMakeLists.txt @@ -25,3 +25,6 @@ add_executable(iptcutil iptcutil.c) set_target_properties(iptcutil PROPERTIES LINKER_LANGUAGE CXX) target_link_libraries(iptcutil tiff tiff_port) + +# Apply C++ compatibility mode if enabled +tiff_target_compile_as_cxx(iptcutil) diff --git a/libtiff/CMakeLists.txt b/libtiff/CMakeLists.txt index b6d7c9d6..d51810c5 100755 --- a/libtiff/CMakeLists.txt +++ b/libtiff/CMakeLists.txt @@ -115,6 +115,9 @@ else() set_property(SOURCE tif_unix.c APPEND PROPERTY COMPILE_DEFINITIONS ALLOW_TIFF_NON_EXT_ALLOC_FUNCTIONS) endif() +# Apply C++ compatibility mode if enabled +tiff_target_compile_as_cxx(tiff) + target_include_directories(tiff PUBLIC $ diff --git a/port/CMakeLists.txt b/port/CMakeLists.txt index d03fc3f0..a828d1c5 100755 --- a/port/CMakeLists.txt +++ b/port/CMakeLists.txt @@ -39,6 +39,9 @@ if(NOT HAVE_GETOPT) ${CMAKE_CURRENT_SOURCE_DIR}/getopt.c) endif() + # Apply C++ compatibility mode if enabled + tiff_target_compile_as_cxx(tiff_port) + target_include_directories(tiff_port PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 527df896..59ae985a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -238,6 +238,11 @@ target_link_libraries(test_RGBAImage PRIVATE tiff tiff_port) target_compile_definitions(test_RGBAImage PRIVATE SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\") list(APPEND simple_tests test_RGBAImage) +# Apply C++ compatibility mode to all test targets if enabled +foreach(target ${simple_tests}) + tiff_target_compile_as_cxx(${target}) +endforeach() + if(WEBP_SUPPORT AND EMSCRIPTEN) # Emscripten is pretty finnicky about linker flags. # It needs --shared-memory if and only if atomics or bulk-memory is used. diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 61b66de8..b57ab67a 100755 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -176,6 +176,38 @@ if(OPENGL_SUPPORT) RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") endif() +# Apply C++ compatibility mode to all tool targets if enabled +foreach(target fax2ps + fax2tiff + pal2rgb + ppm2tiff + raw2tiff + rgb2ycbcr + thumbnail + tiff2bw + tiff2pdf + tiff2ps + tiff2rgba + tiffcmp + tiffcp + tiffcrop + tiffdither + tiffdump + tiffinfo + tiffmedian + tiffset + tiffsplit) + tiff_target_compile_as_cxx(${target}) +endforeach() + +if(NOT CMAKE_CROSSCOMPILING) + tiff_target_compile_as_cxx(tiff_mkg3states) +endif() + +if(OPENGL_SUPPORT) + tiff_target_compile_as_cxx(tiffgt) +endif() + if(WEBP_SUPPORT AND EMSCRIPTEN) # Emscripten is pretty finnicky about linker flags. # It needs --shared-memory if and only if atomics or bulk-memory is used.