Repository: conan-io/conan-center-index

Issue:
[question] Cyclical dependencies from zlib and minizip
Hello Everyone,

I was wondering what is the difference between the minizip and the zlib libraries. Both 
libraries use the same source (i.e. the zlib source code, but from different sources) 
and they have cyclical (invisible) dependencies. The zlib library is building the minizip
library (with CMakeLists_minizip) and the minizip library has a dependency from zlib. 
Is that necessary? Am I missing something? Can it be re-factored somehow? 

KR,
Vasileios


Discussion:

Resolving patch:
diff --git a/recipes/zlib/1.2.11/conanfile.py b/recipes/zlib/1.2.11/conanfile.py
--- a/recipes/zlib/1.2.11/conanfile.py
+++ b/recipes/zlib/1.2.11/conanfile.py
@@ -12,13 +12,20 @@ class ZlibConan(ConanFile):
     description = ("A Massively Spiffy Yet Delicately Unobtrusive Compression Library "
                    "(Also Free, Not to Mention Unencumbered by Patents)")
     settings = "os", "arch", "compiler", "build_type"
-    options = {"shared": [True, False], "fPIC": [True, False], "minizip": [True, False]}
-    default_options = {"shared": False, "fPIC": True, "minizip": False}
+    options = {"shared": [True, False], "fPIC": [True, False], "minizip": [True, False, "deprecated"]}
+    default_options = {"shared": False, "fPIC": True, "minizip": "deprecated"}
     exports_sources = ["CMakeLists.txt", "CMakeLists_minizip.txt", "patches/**"]
     generators = "cmake"
-    _source_subfolder = "source_subfolder"
     topics = ("conan", "zlib", "compression")
 
+    @property
+    def _source_subfolder(self):
+        return "source_subfolder"
+
+    @property
+    def _build_subfolder(self):
+        return "build_subfolder"
+
     def config_options(self):
         if self.settings.os == "Windows":
             del self.options.fPIC
@@ -27,24 +34,20 @@ def configure(self):
         del self.settings.compiler.libcxx
         del self.settings.compiler.cppstd
 
-    def source(self):
-        tools.get(**self.conan_data["sources"][self.version])
-        os.rename("{}-{}".format(self.name, self.version), self._source_subfolder)
+        if self.options.shared:
+            del self.options.fPIC
 
-    def build(self):
-        self._build_zlib()
-        if self.options.minizip:
-            self._build_minizip()
+        if self.options.minizip != "deprecated":
+            self.output.warn("minizip option is deprecated. Please use the new minizip/1.2.11 package")
 
-    def _build_zlib_cmake(self):
-        cmake = CMake(self)
-        cmake.configure(build_dir=".")
-        # we need to build only libraries without test example/example64 and minigzip/minigzip64
-        make_target = "zlib" if self.options.shared else "zlibstatic"
+    def package_id(self):
+        del self.info.options.minizip
 
-        cmake.build(build_dir=".", target=make_target)
+    def source(self):
+        tools.get(**self.conan_data["sources"][self.version])
+        os.rename("{}-{}".format(self.name, self.version), self._source_subfolder)
 
-    def _build_zlib(self):
+    def _patch_sources(self):
         for patch in self.conan_data["patches"][self.version]:
             tools.patch(**patch)
 
@@ -65,18 +68,13 @@ def _build_zlib(self):
                                           '#ifdef HAVE_STDARG_H    '
                                           '/* may be set to #if 1 by ./configure */',
                                           '#if defined(HAVE_STDARG_H) && (1-HAVE_STDARG_H-1 != 0)')
-            tools.mkdir("_build")
-            with tools.chdir("_build"):
-                self._build_zlib_cmake()
-
-    def _build_minizip(self):
-        minizip_dir = os.path.join(self._source_subfolder, 'contrib', 'minizip')
-        os.rename("CMakeLists_minizip.txt", os.path.join(minizip_dir, 'CMakeLists.txt'))
-        with tools.chdir(minizip_dir):
-            cmake = CMake(self)
-            cmake.configure(source_folder=minizip_dir)
-            cmake.build()
-            cmake.install()
+
+    def build(self):
+        self._patch_sources()
+        make_target = "zlib" if self.options.shared else "zlibstatic"
+        cmake = CMake(self)
+        cmake.configure(build_folder=self._build_subfolder)
+        cmake.build(target=make_target)
 
     def _rename_libraries(self):
         if self.settings.os == "Windows":
@@ -99,39 +97,34 @@ def _rename_libraries(self):
                     current_lib = os.path.join(lib_path, "zlibstatic.lib")
                     os.rename(current_lib, os.path.join(lib_path, "zlib.lib"))
 
-    def package(self):
-        # Extract the License/s from the header to a file
+    def _extract_license(self):
         with tools.chdir(os.path.join(self.source_folder, self._source_subfolder)):
             tmp = tools.load("zlib.h")
             license_contents = tmp[2:tmp.find("*/", 1)]
             tools.save("LICENSE", license_contents)
 
-        # Copy the license files
+    def package(self):
+        self._extract_license()
         self.copy("LICENSE", src=self._source_subfolder, dst="licenses")
 
         # Copy headers
         for header in ["*zlib.h", "*zconf.h"]:
             self.copy(pattern=header, dst="include", src=self._source_subfolder, keep_path=False)
-            self.copy(pattern=header, dst="include", src="_build", keep_path=False)
+            self.copy(pattern=header, dst="include", src=self._build_subfolder, keep_path=False)
 
         # Copying static and dynamic libs
-        build_dir = os.path.join(self._source_subfolder, "_build")
         if self.options.shared:
-            self.copy(pattern="*.dylib*", dst="lib", src=build_dir, keep_path=False, symlinks=True)
-            self.copy(pattern="*.so*", dst="lib", src=build_dir, keep_path=False, symlinks=True)
-            self.copy(pattern="*.dll", dst="bin", src=build_dir, keep_path=False)
-            self.copy(pattern="*.dll.a", dst="lib", src=build_dir, keep_path=False)
+            self.copy(pattern="*.dylib*", dst="lib", src=self._build_subfolder, keep_path=False, symlinks=True)
+            self.copy(pattern="*.so*", dst="lib", src=self._build_subfolder, keep_path=False, symlinks=True)
+            self.copy(pattern="*.dll", dst="bin", src=self._build_subfolder, keep_path=False)
+            self.copy(pattern="*.dll.a", dst="lib", src=self._build_subfolder, keep_path=False)
         else:
-            self.copy(pattern="*.a", dst="lib", src=build_dir, keep_path=False)
-        self.copy(pattern="*.lib", dst="lib", src=build_dir, keep_path=False)
+            self.copy(pattern="*.a", dst="lib", src=self._build_subfolder, keep_path=False)
+        self.copy(pattern="*.lib", dst="lib", src=self._build_subfolder, keep_path=False)
 
         self._rename_libraries()
 
     def package_info(self):
-        if self.options.minizip:
-            self.cpp_info.libs.append('minizip')
-            if self.options.shared:
-                self.cpp_info.defines.append('MINIZIP_DLL')
         self.cpp_info.libs.append("zlib" if self.settings.os == "Windows" and not self.settings.os.subsystem else "z")
         self.cpp_info.names["cmake_find_package"] = "ZLIB"
         self.cpp_info.names["cmake_find_package_multi"] = "ZLIB"


Test patch:
diff --git a/recipes/zlib/1.2.11/test_package/CMakeLists.txt b/recipes/zlib/1.2.11/test_package/CMakeLists.txt
--- a/recipes/zlib/1.2.11/test_package/CMakeLists.txt
+++ b/recipes/zlib/1.2.11/test_package/CMakeLists.txt
@@ -7,8 +7,3 @@ conan_basic_setup(TARGETS)
 add_executable(test_zlib test.c)
 target_link_libraries(test_zlib CONAN_PKG::zlib)
 set_target_properties(test_zlib PROPERTIES OUTPUT_NAME "test")
-
-if(WITH_MINIZIP)
-  add_executable(test_minizip test_minizip.c)
-  target_link_libraries(test_minizip CONAN_PKG::zlib)
-endif()
diff --git a/recipes/zlib/1.2.11/test_package/conanfile.py b/recipes/zlib/1.2.11/test_package/conanfile.py
--- a/recipes/zlib/1.2.11/test_package/conanfile.py
+++ b/recipes/zlib/1.2.11/test_package/conanfile.py
@@ -10,7 +10,6 @@ def configure(self):
 
     def build(self):
         cmake = CMake(self)
-        cmake.definitions["WITH_MINIZIP"] = self.options["zlib"].minizip
         cmake.configure()
         cmake.build()
 
@@ -19,5 +18,3 @@ def test(self):
         assert os.path.exists(os.path.join(self.build_folder, "zlib.pc"))
         if "x86" in self.settings.arch and not tools.cross_building(self.settings):
             self.run(os.path.join("bin", "test"), run_environment=True)
-            if self.options["zlib"].minizip:
-                self.run(os.path.join("bin", "test_minizip"), run_environment=True)
diff --git a/recipes/zlib/1.2.11/test_package/test_minizip.c b/recipes/zlib/1.2.11/test_package/test_minizip.c
deleted file mode 100644
--- a/recipes/zlib/1.2.11/test_package/test_minizip.c
+++ /dev/null
@@ -1,261 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <zip.h>
-#include <unzip.h>
-#ifdef _WIN32
-    #include <iowin32.h>
-#endif
-
-/* TODO: create test for this header */
-#include <mztools.h>
-
-const char text[] = ""
-"Conveying or northward offending admitting perfectly my. Colonel gravity get thought fat smiling add but. Wonder twenty hunted and put income set desire expect. Am cottage calling my is mistake cousins talking up. Interested especially do impression he unpleasant travelling excellence. All few our knew time done draw ask.\n"
-"\n"
-"Village did removed enjoyed explain nor ham saw calling talking. Securing as informed declared or margaret. Joy horrible moreover man feelings own shy. Request norland neither mistake for yet. Between the for morning assured country believe. On even feet time have an no at. Relation so in confined smallest children unpacked delicate. Why sir end believe uncivil respect. Always get adieus nature day course for common. My little garret repair to desire he esteem.\n"
-""
-"As it so contrasted oh estimating instrument. Size like body some one had. Are conduct viewing boy minutes warrant expense. Tolerably behaviour may admitting daughters offending her ask own. Praise effect wishes change way and any wanted. Lively use looked latter regard had. Do he it part more last in. Merits ye if mr narrow points. Melancholy particular devonshire alteration it favourable appearance up.\n"
-""
-"Extremity direction existence as dashwoods do up. Securing marianne led welcomed offended but offering six raptures. Conveying concluded newspaper rapturous oh at. Two indeed suffer saw beyond far former mrs remain. Occasional continuing possession we insensible an sentiments as is. Law but reasonably motionless principles she. Has six worse downs far blush rooms above stood.\n"
-""
-"Comfort reached gay perhaps chamber his six detract besides add. Moonlight newspaper up he it enjoyment agreeable depending. Timed voice share led his widen noisy young. On weddings believed laughing although material do exercise of. Up attempt offered ye civilly so sitting to. She new course get living within elinor joy. She her rapturous suffering concealed.\n"
-""
-"Neat own nor she said see walk. And charm add green you these. Sang busy in this drew ye fine. At greater prepare musical so attacks as on distant. Improving age our her cordially intention. His devonshire sufficient precaution say preference middletons insipidity. Since might water hence the her worse. Concluded it offending dejection do earnestly as me direction. Nature played thirty all him.\n"
-""
-"Mr do raising article general norland my hastily. Its companions say uncommonly pianoforte favourable. Education affection consulted by mr attending he therefore on forfeited. High way more far feet kind evil play led. Sometimes furnished collected add for resources attention. Norland an by minuter enquire it general on towards forming. Adapted mrs totally company two yet conduct men.\n"
-""
-"An sincerity so extremity he additions. Her yet there truth merit. Mrs all projecting favourable now unpleasing. Son law garden chatty temper. Oh children provided to mr elegance marriage strongly. Off can admiration prosperous now devonshire diminution law.\n"
-""
-"He share of first to worse. Weddings and any opinions suitable smallest nay. My he houses or months settle remove ladies appear. Engrossed suffering supposing he recommend do eagerness. Commanded no of depending extremity recommend attention tolerably. Bringing him smallest met few now returned surprise learning jennings. Objection delivered eagerness he exquisite at do in. Warmly up he nearer mr merely me.\n"
-""
-"Yet remarkably appearance get him his projection. Diverted endeavor bed peculiar men the not desirous. Acuteness abilities ask can offending furnished fulfilled sex. Warrant fifteen exposed ye at mistake. Blush since so in noisy still built up an again. As young ye hopes no he place means. Partiality diminution gay yet entreaties admiration. In mr it he mention perhaps attempt pointed suppose. Unknown ye chamber of warrant of norland arrived.\n"
-"";
-
-const char* zip_fname = "test_minizip.zip";
-
-int print_zip_info(unzFile);
-void Display64BitsSize(ZPOS64_T, int);
-
-int main(int argc, char** argv) {
-    /* Zip */
-    printf("---------- Create ZIP ----------\n");
-
-    zipFile zf = zipOpen64(zip_fname, APPEND_STATUS_CREATE);
-    if (zf == NULL) {
-        printf("Error in zipOpen64, fname: %s\n", zip_fname);
-        exit(EXIT_FAILURE);
-    }
-
-    int res;
-    zip_fileinfo zfi = {0};
-    res = zipOpenNewFileInZip64(zf, "fname.bin", &zfi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION, 0);
-    if (res != ZIP_OK) {
-        printf("Error in zipOpenNewFileInZip64, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    res = zipWriteInFileInZip(zf, text, sizeof(text));
-    if (res != ZIP_OK) {
-        printf("Error in zipWriteInFileInZip, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    res = zipCloseFileInZip(zf);
-    if (res != ZIP_OK) {
-        printf("Error in zipCloseFileInZip, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    res = zipClose(zf, "Test MiniZip");
-    if(res != ZIP_OK) {
-        printf("Error in zipClose, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    printf("ZIP file created, name: %s\n", zip_fname);
-
-    /* unZip */
-    printf("---------- Test unZIP ----------\n");
-
-    unzFile unzf = unzOpen64(zip_fname);
-    if (unzf == NULL) {
-        printf("Error in unzOpen64, fname: %s\n", zip_fname);
-        exit(EXIT_FAILURE);
-    }
-
-    res = print_zip_info(unzf);
-    if (res != UNZ_OK) {
-        printf("Read ZIP info error, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    res = unzGoToFirstFile(unzf);
-    if (res != UNZ_OK) {
-        printf("Error in unzGoToFirstFile, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    unz_file_info64 unz_fi = {0};
-    res = unzGetCurrentFileInfo64(unzf, &unz_fi, NULL, 0, NULL, 0, NULL, 0);
-    if (res != UNZ_OK) {
-        printf("Error in unzGetCurrentFileInfo64, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    /* Compare size */
-    if (unz_fi.uncompressed_size != (ZPOS64_T) sizeof(text)) {
-        printf("Error in Zip, failed compare size. In Zip => %llu, source size => %llu\n", unz_fi.uncompressed_size, (ZPOS64_T) sizeof(text));
-        exit(EXIT_FAILURE);
-    }
-
-    res = unzOpenCurrentFile(unzf);
-    if (res != UNZ_OK) {
-        printf("Error in unzOpenCurrentFile, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    char* read_data = calloc(1, sizeof(text));
-    if (read_data == NULL) {
-        printf("Can`t allocate read buffer\n");
-        exit(EXIT_FAILURE);
-    }
-
-    res = unzReadCurrentFile(unzf, read_data, sizeof(text));
-    if (res < 0) {
-        printf("Error in unzReadCurrentFile, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    if (memcmp(text, read_data, sizeof(text)) != 0) {
-        printf("Error in zip, source and uncompressed data not equal.\n");
-        exit(EXIT_FAILURE);
-    }
-
-    res = unzClose(unzf);
-    if (res != UNZ_OK) {
-        printf("Error in unzClose, code: %d\n", res);
-        exit(EXIT_FAILURE);
-    }
-
-    printf("Zip / Unzip OK\n");
-    free(read_data);
-    return EXIT_SUCCESS;
-}
-
-int print_zip_info(unzFile unzf) {
-    char comment[256] = {0};
-    int res;
-    res = unzGetGlobalComment(unzf, comment, sizeof(comment));
-    if (res < 0) {
-        printf("Error in unzGetGlobalComment, code: %d\n", res);
-        return  res;
-    }
-    printf("unZIP. Global comment => %s\n", comment);
-
-    res = unzGoToFirstFile(unzf);
-    if (res != UNZ_OK) {
-        printf("Error in unzGoToFirstFile, code: %d\n", res);
-        return res;
-    }
-
-    unz_global_info64 gi = {0};
-    res = unzGetGlobalInfo64(unzf, &gi);
-    if (res != UNZ_OK) {
-        printf("Error in unzGetGlobalInfo64, code: %d\n", res);
-        return res;
-    }
-    printf("  Length  Method     Size Ratio   Date    Time   CRC-32     Name\n");
-    printf("  ------  ------     ---- -----   ----    ----   ------     ----\n");
-
-    for (uLong i = 0; i < gi.number_entry; i++) {
-        unz_file_info64 file_info = {0};
-        char fname_inzip[256] = {0};
-        res = unzGetCurrentFileInfo64(unzf, &file_info, fname_inzip, sizeof(fname_inzip), NULL, 0, NULL, 0);
-        if (res != UNZ_OK) {
-            printf("Error in unzGetCurrentFileInfo64, code: %d\n", res);
-            return res;
-        }
-
-        uLong ratio = 0;
-        if (file_info.uncompressed_size>0) {
-            ratio = (uLong) ((file_info.compressed_size*100) / file_info.uncompressed_size);
-        }
-
-        char crypt = ' ';
-        if ((file_info.flag & 1) != 0) {
-            char crypt = '*';
-        }
-
-        const char* str_method = NULL;
-        if (file_info.compression_method==0) {
-            str_method = "Stored";
-        } else if (file_info.compression_method == Z_DEFLATED) {
-            uInt iLevel=(uInt) ((file_info.flag & 0x6) / 2);
-            if (iLevel == 0) {
-              str_method = "Defl:N";
-            } else if (iLevel == 1) {
-              str_method = "Defl:X";
-            } else if ((iLevel == 2) || (iLevel == 3)) {
-              str_method="Defl:F"; /* 2:fast , 3 : extra fast*/
-            }
-        } else if (file_info.compression_method==Z_BZIP2ED) {
-              str_method="BZip2 ";
-        } else {
-            str_method="Unkn. ";
-        }
-
-        Display64BitsSize(file_info.uncompressed_size, 7);
-        printf("  %6s%c", str_method, crypt);
-        Display64BitsSize(file_info.compressed_size, 7);
-        printf(" %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\n",
-                ratio,
-                (uLong) file_info.tmu_date.tm_mon + 1,
-                (uLong) file_info.tmu_date.tm_mday,
-                (uLong) file_info.tmu_date.tm_year - 1900,
-                (uLong) file_info.tmu_date.tm_hour,
-                (uLong) file_info.tmu_date.tm_min,
-                (uLong) file_info.crc,
-                fname_inzip
-        );
-        if ((i + 1) < gi.number_entry) {
-            res = unzGoToNextFile(unzf);
-            if (res != UNZ_OK) {
-                printf("Error in unzGoToNextFile, code: %d\n", res);
-                return res;
-            }
-        }
-    }
-
-    return UNZ_OK;
-}
-
-void Display64BitsSize(ZPOS64_T n, int size_char) {
-    /* to avoid compatibility problem , we do here the conversion */
-    char number[21] = {0};
-    int offset = 19;
-    int pos_string = 19;
-    number[20] = 0;
-
-    for (;;) {
-        number[offset] = (char) ((n % 10) + '0');
-      if (number[offset] != '0') {
-          pos_string = offset;
-      }
-      n /= 10;
-      if (offset == 0) {
-          break;
-      }
-      offset--;
-  }
-
-  int size_display_string = 19 - pos_string;
-  while (size_char > size_display_string) {
-          size_char--;
-          printf(" ");
-   }
-
-  printf("%s", &number[pos_string]);
-}
-