2015.06.16 14:39 "[Tiff] CMake support for building libtiff", by Roger Leigh

2015.06.19 11:54 "Re: [Tiff] CMake support for building libtiff", by Roger Leigh

On 18/06/2015 22:08, Roger Leigh wrote:

I'd be very interested in any feedback, particularly from Windows users.

  I'll follow up with a patch to disable the non-buildable components

tomorrow; you can just comment out the test/tools/contrib directories in the top-level CMakeLists.txt in the interim.

Attached 5 additional minor patches. These add support for building with Visual Studio 2013 and 2012 (probably also 2010; I haven't got a copy handy to check). This is primarily working around a lack of snprintf(3), which is added to libport when required.

It also fixes up running the tests with the PATH correctly set. You can now run "ctest -C Debug|Release" and have it run the tests without you having to set the PATH by hand.

At this point I consider this patch set feature complete and ready to use. There may be minor portability tweaks needed on more obscure platforms (e.g. AIX, Cygwin), but it's tested to work on all the current major ones, and is ready for proper review.

Thanks all,

Roger

>From 8e7c875f3fdab21410ca554f0a003d2c69001be1 Mon Sep 17 00:00:00 2001 From: Roger Leigh <rleigh@codelibre.net> Date: Fri, 19 Jun 2015 10:27:05 +0000 Subject: [PATCH 5/9] cmake: Portability check for _snprintf in VS2013

---

 CMakeLists.txt                |  6 ++++++
 libtiff/tif_config.h.cmake.in | 10 ++++++++++

 2 files changed, 16 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b75165b..e596005 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -294,6 +294,7 @@ check_function_exists(memmove HAVE_MEMMOVE)
 check_function_exists(memset HAVE_MEMSET)
 check_function_exists(mmap HAVE_MMAP)
 check_function_exists(setmode HAVE_SETMODE)
+check_function_exists(snprintf HAVE_SNPRINTF)
 check_function_exists(strcasecmp HAVE_STRCASECMP)
 check_function_exists(strchr HAVE_STRCHR)
 check_function_exists(strrchr HAVE_STRRCHR)
@@ -304,6 +305,11 @@ check_function_exists(strtoull HAVE_STRTOULL)
 check_function_exists(getopt HAVE_GETOPT)
 check_function_exists(lfind HAVE_LFIND)

+# VS2013 has a usable _snprintf
+if(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900)
+ check_function_exists(_snprintf HAVE__SNPRINTF)
+endif()
+
 # CPU bit order
 set(fillorder FILLORDER_MSB2LSB)
 if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i.*86.*" OR
diff --git a/libtiff/tif_config.h.cmake.in b/libtiff/tif_config.h.cmake.in
index d07e3cf..1421088 100644
--- a/libtiff/tif_config.h.cmake.in
+++ b/libtiff/tif_config.h.cmake.in
@@ -92,6 +92,16 @@
 /* Define to 1 if you have the `setmode' function. */
 #cmakedefine HAVE_SETMODE 1

+/* Define to 1 if you have the `snprintf' function. */
+#cmakedefine HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `_snprintf' function. */
+#cmakedefine HAVE__SNPRINTF 1
+
+#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
+#define snprintf _snprintf
+#endif
+
 /* Define to 1 if you have the `sqrt' function. */
 #cmakedefine HAVE_SQRT 1

--
2.4.2

>From b4b7802a94f8d3a386a9fc3127db6264962fd423 Mon Sep 17 00:00:00 2001 From: Roger Leigh <rleigh@codelibre.net> Date: Fri, 19 Jun 2015 11:00:42 +0000 Subject: [PATCH 6/9] rewrite_tag: Remove K&Rism breaking VS2012 build

---
 test/rewrite_tag.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/test/rewrite_tag.c b/test/rewrite_tag.c
index de0b551..69f26f2 100644
--- a/test/rewrite_tag.c
+++ b/test/rewrite_tag.c
@@ -322,8 +322,6 @@ int rewrite_test( const char *filename, int length, int bigtiff,
 int
 main(int argc, char **argv)
 {
- (void) argc;
- (void) argv;
     int failure = 0;

     failure |= test_packbits();
--
2.4.2

>From 5110b2ab0bd4762104d6231e1ecc74bb1c96f69e Mon Sep 17 00:00:00 2001 From: Roger Leigh <rleigh@codelibre.net> Date: Fri, 19 Jun 2015 11:01:44 +0000 Subject: [PATCH 7/9] port: Link into libtiff correctly

---

 libtiff/CMakeLists.txt | 2 +-
 port/CMakeLists.txt    | 5 +++++

 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/libtiff/CMakeLists.txt b/libtiff/CMakeLists.txt
index 5d146e1..391aea3 100644
--- a/libtiff/CMakeLists.txt
+++ b/libtiff/CMakeLists.txt
@@ -115,7 +115,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
                     ${TIFF_INCLUDES})

 add_library(tiff SHARED ${tiff_SOURCES} ${tiff_HEADERS} ${nodist_tiff_HEADERS}
- ${port_USED_FILES} libtiff.def)
+ ${tiff_port_SOURCES} libtiff.def)
 target_link_libraries(tiff ${TIFF_LIBRARY_DEPS})
 set_target_properties(tiff PROPERTIES SOVERSION ${SO_COMPATVERSION})
 if(NOT CYGWIN)
diff --git a/port/CMakeLists.txt b/port/CMakeLists.txt
index 59b3aeb..af61826 100644
--- a/port/CMakeLists.txt
+++ b/port/CMakeLists.txt
@@ -50,3 +50,8 @@ if(NOT HAVE_STRTOULL)
 endif()

 add_library(port STATIC ${port_USED_FILES})
+
+foreach(file ${port_USED_FILES})
+ list(APPEND tiff_port_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
+endforeach()
+set(tiff_port_SOURCES ${tiff_port_SOURCES} PARENT_SCOPE)
--
2.4.2

>From 118cf4023b09ca36bfba3225c04892e8b10aaa0b Mon Sep 17 00:00:00 2001 From: Roger Leigh <rleigh@codelibre.net> Date: Fri, 19 Jun 2015 11:02:20 +0000 Subject: [PATCH 8/9] port: Add compatibility snprintf on Windows

---

 libtiff/tiffiop.h   |  4 ++++
 port/CMakeLists.txt |  3 +++
 port/Makefile.am    |  2 +-
 port/libport.h      |  4 ++++
 port/snprintf.c     | 37 +++++++++++++++++++++++++++++++++++++
 5 files changed, 49 insertions(+), 1 deletion(-)

 create mode 100644 port/snprintf.c

diff --git a/libtiff/tiffiop.h b/libtiff/tiffiop.h
index 53357d8..3fdd1bb 100644
--- a/libtiff/tiffiop.h
+++ b/libtiff/tiffiop.h

@@ -57,6 +57,10 @@ extern void *lfind(const void *, const void *, size_t *, size_t,

                   int (*)(const void *, const void *));
 #endif

+#if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF) +extern int snprintf(char* str, size_t size, const char* format, ...);

+#endif
+
 #include "tiffio.h"

 #include "tif_dir.h"
diff --git a/port/CMakeLists.txt b/port/CMakeLists.txt
index af61826..354ed4d 100644
--- a/port/CMakeLists.txt
+++ b/port/CMakeLists.txt
@@ -39,6 +39,9 @@ endif()
 if(NOT HAVE_LFIND)
   list(APPEND port_USED_FILES lfind.c)
 endif()
+if(NOT HAVE_SNPRINTF AND NOT HAVE__SNPRINTF)
+ list(APPEND port_USED_FILES snprintf.c)
+endif()
 if(NOT HAVE_STRCASECMP)
   list(APPEND port_USED_FILES strcasecmp.c)
 endif()
diff --git a/port/Makefile.am b/port/Makefile.am
index 94504fd..e825345 100644
--- a/port/Makefile.am
+++ b/port/Makefile.am
@@ -23,7 +23,7 @@

 # Process this file with automake to produce Makefile.in.

-EXTRA_DIST = Makefile.vc libport.h
+EXTRA_DIST = Makefile.vc libport.h snprintf.c

 noinst_LTLIBRARIES     = libport.la
 libport_la_SOURCES     = dummy.c libport.h

diff --git a/port/libport.h b/port/libport.h
index 802f478..6b7ee49 100644
--- a/port/libport.h

+++ b/port/libport.h
@@ -48,4 +48,8 @@ lfind(const void *key, const void *base, size_t *nmemb, size_t size,
       int(*compar)(const void *, const void *));
 #endif

+#if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF)
+int snprintf(char* str, size_t size, const char* format, ...);
+#endif
+
 #endif /* ndef _LIBPORT_ */
diff --git a/port/snprintf.c b/port/snprintf.c
new file mode 100644
index 0000000..ddbf658
--- /dev/null
+++ b/port/snprintf.c
@@ -0,0 +1,37 @@
+/**
+ * Workaround for lack of snprintf(3) in Visual Studio.  See
+ * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010/8712996#8712996
+ * It's a trivial wrapper around the builtin _vsnprintf_s and
+ * _vscprintf functions.
+ */
+
+#ifdef _MSC_VER
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int vsnprintf(char* str, size_t size, const char* format, va_list ap)
+{
+  int count = -1;
+
+  if (size != 0)
+    count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
+  if (count == -1)
+    count = _vscprintf(format, ap);
+
+  return count;
+}
+
+int snprintf(char* str, size_t size, const char* format, ...)
+{
+  int count;
+  va_list ap;
+
+  va_start(ap, format);
+  count = vsnprintf(str, size, format, ap);
+  va_end(ap);
+
+  return count;
+}
+
+#endif // _MSC_VER

--
2.4.2

>From e9c2ee422ba22f7a06c1a7a125b26d982b7c5497 Mon Sep 17 00:00:00 2001 From: Roger Leigh <rleigh@codelibre.net> Date: Fri, 19 Jun 2015 11:46:49 +0000 Subject: [PATCH 9/9] cmake: Run tests with correct path on Windows

---

 libtiff/CMakeLists.txt    | 6 ------
 test/CMakeLists.txt       | 5 +++++
 test/TiffTestCommon.cmake | 7 +++++++

 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/libtiff/CMakeLists.txt b/libtiff/CMakeLists.txt
index 391aea3..72e49e6 100644
--- a/libtiff/CMakeLists.txt
+++ b/libtiff/CMakeLists.txt
@@ -179,9 +179,3 @@ if(cxx)
           DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}")

 endif()
-

-# Copy DLL into the build dir so tests can run on Windows without -# having to add the library containing the DLL to the PATH (TODO) -#add_custom_target(copy-dll ALL

-#                  DEPENDS tiff tiffxx
-#                  COMMAND "${CMAKE_COMMAND}" -E echo "TARGET: $<TARGET_FILE:tiff>")

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index e3b4363..b9e373f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -194,6 +194,7 @@ macro(tiff_test_convert name command1 command2 command3 infile outfile validate)
            "-DINFILE=${infile}"
            "-DOUTFILE=${outfile}"
            "-DTIFFINFO=$<TARGET_FILE:tiffinfo>"
+ "-DLIBTIFF=$<TARGET_FILE:tiff>"
            "-DVALIDATE=${validate}"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffTest.cmake")
 endmacro()
@@ -205,6 +206,7 @@ macro(tiff_test_stdout name command infile outfile)
            "-DINFILE=${infile}"
            "-DOUTFILE=${outfile}"
            "-DTIFFINFO=$<TARGET_FILE:tiffinfo>"
+ "-DLIBTIFF=$<TARGET_FILE:tiff>"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffTest.cmake")
 endmacro()

@@ -214,6 +216,7 @@ macro(tiff_test_reader name command infile)
            "-DREADER_COMMAND=${command}"
            "-DINFILE=${infile}"
            "-DTIFFINFO=$<TARGET_FILE:tiffinfo>"
+ "-DLIBTIFF=$<TARGET_FILE:tiff>"
            -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffTest.cmake")
 endmacro()

@@ -343,6 +346,7 @@ add_test(NAME "tiffcp-split"
          "-DSPLITFILE=${TEST_OUTPUT}/tiffcp-split-split-"
          "-DTIFFCP=$<TARGET_FILE:tiffcp>"
          "-DTIFFSPLIT=$<TARGET_FILE:tiffsplit>"
+ "-DLIBTIFF=$<TARGET_FILE:tiff>"
          -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffSplitTest.cmake")
 add_test(NAME "tiffcp-split-join"
          COMMAND "${CMAKE_COMMAND}"
@@ -352,6 +356,7 @@ add_test(NAME "tiffcp-split-join"
          "-DRECONJOINED=${TEST_OUTPUT}/tiffcp-split-join-reconjoined.tif"
          "-DTIFFCP=$<TARGET_FILE:tiffcp>"
          "-DTIFFSPLIT=$<TARGET_FILE:tiffsplit>"
+ "-DLIBTIFF=$<TARGET_FILE:tiff>"
          -P "${CMAKE_CURRENT_SOURCE_DIR}/TiffSplitTest.cmake")

 # PDF
diff --git a/test/TiffTestCommon.cmake b/test/TiffTestCommon.cmake
index 1598d8b..50a4c34 100644
--- a/test/TiffTestCommon.cmake
+++ b/test/TiffTestCommon.cmake
@@ -94,3 +94,10 @@ endmacro()
 macro(tiffinfo_validate file)
   test_reader("${TIFFINFO};-D" "${file}")
 endmacro()
+
+# Add the directory containing libtiff to the PATH (Windows only)
+if(WIN32)
+ get_filename_component(LIBTIFF_DIR "${LIBTIFF}" DIRECTORY)
+ file(TO_NATIVE_PATH "${LIBTIFF_DIR}" LIBTIFF_DIR)
+ set(ENV{PATH} "${LIBTIFF_DIR};$ENV{PATH}")
+endif()
--
2.4.2