首页 > 解决方案 > 柯南在生成 CMake 文件时的奇怪行为

问题描述

我目前正在编写一个conanfile.py构建 OpenCV,这是我公司内部使用的自定义构建。我们正在尝试使用 CMake 进行构建,但我们遇到了 OpenCV 的意外行为:在生成 Release 构建而不在设置中指定 build_type 时,OpenCV 会生成发布和调试构建。

这是我们的 conanfile.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Conan file to build OpenCV according to other specs.
"""

from conans import ConanFile, CMake, tools
import re
import os.path


class OpenCVConan(ConanFile):
    name = "opencv"
    version = "3.4.3"
    url = "https://github.com/opencv/opencv"
    license = "https://github.com/opencv/opencv/blob/master/LICENSE"
    settings = "os", "compiler", "arch"
    options = {"shared": [True, False]}
    default_options = {"shared": True}
    topics = ("kv", "opencv", "C++")
    generators = "cmake_find_package"
    description = "Building OpenCV from sources according to our specs."
    _msvc_archs = {"x86": "x86", "x86_64": "x64"}

    def source(self):
        self.run("git clone --depth 1 --branch %s https://github.com/opencv/opencv" % (self.version))
        self.run("git clone --depth 1 --branch %s https://github.com/opencv/opencv_contrib" % (self.version))

    def _configure_cmake(self):
        cmake = CMake(self)

        cmake.definitions["CPACK_BINARY_NSIS"] = False
        cmake.definitions["CPACK_SOURCE_7Z"] = False
        cmake.definitions["CPACK_SOURCE_ZIP"] = False

        cmake.definitions["ENABLE_CXX11"] = True
        cmake.definitions["ENABLE_LTO"] = False
        cmake.definitions["ENABLE_THIN_LTO"] = False
        cmake.definitions["OPENCV_ENABLE_NONFREE"] = False
        cmake.definitions["TINYDNN_USE_AVX"] = False
        cmake.definitions["ENABLE_SOLUTION_FOLDERS"] = False

        cmake.definitions["OPENCV_EXTRA_MODULES_PATH"] = "opencv_contrib/modules"

        cmake.definitions["WITH_1394"] = False
        cmake.definitions["WITH_MATLAB"] = False
        cmake.definitions["WITH_NVCUVID"] = False
        cmake.definitions["WITH_GSTREAMER"] = False
        cmake.definitions["WITH_OPENEXR"] = False
        cmake.definitions["WITH_OPENGL"] = True
        cmake.definitions["WITH_FFMPEG"] = False

        cmake.definitions["BUILD_DOCS"] = False
        cmake.definitions["BUILD_EXAMPLES"] = False
        cmake.definitions["BUILD_JAVA"] = False
        cmake.definitions["BUILD_OPENEXR"] = False
        cmake.definitions["BUILD_PACKAGE"] = False
        cmake.definitions["BUILD_PERF_TESTS"] = False
        cmake.definitions["BUILD_TESTS"] = False
        cmake.definitions["BUILD_WITH_STATIC_CRT"] = False

        cmake.definitions["BUILD_opencv_ts"] = False
        cmake.definitions["BUILD_opencv_js"] = False
        cmake.definitions["BUILD_opencv_java_bindings_generator"] = False

        cmake.definitions["BUILD_CUDA_STUBS"] = True
        cmake.definitions["BUILD_opencv_world"] = False
        cmake.definitions["BUILD_opencv_cudaoptflow"] = True
        cmake.definitions["BUILD_opencv_stitching"] = False
        cmake.definitions["WITH_CUDA"] = True
        cmake.definitions["WITH_CUFFT"] = True
        cmake.definitions["WITH_CUBLAS"] = True
        cmake.definitions["CUDA_ARCH_BIN"] = "5.0 5.2 6.0 6.1"

        cmake.definitions["CMAKE_BUILD_TYPE"] = "Release"

        cmake.configure(source_folder="opencv")
        return cmake

    def build(self):
        cmake = self._configure_cmake()
        cmake.build()
        #self.run('cmake "%s" %s -DCMAKE_BUILD_TYPE="Release"' % (self.source_folder, cmake.command_line))
        #self.run('cmake --build . --config Release')

    def package(self):
        cmake = self._configure_cmake()
        self.run('cmake --build . --target install')
        cmake.patch_config_paths()

        library_folder = os.path.join(self.package_folder, self._msvc_archs[self.settings.arch.value], "vc15")
        self.copy(pattern="*.lib", dst="lib", src=library_folder, keep_path=False)
        self.copy(pattern="*.dll", dst="bin", src=library_folder, keep_path=False)

        # Remove debug headers from the packages
        with open(self.package_folder + "\include\opencv2\core\cvdef.h", 'r+') as f:
            """
            Let's clarify what's going on here:
            We open a file for reading, change the data we read from the buffer, then place the
            cursor at the beginning of the file and save the content. Since this will append to
            the file we need to call truncate() to remove excessive data that may have remained there.

            Yep, this is a thing.
            """
            content = f.read()
            first_change = re.sub("namespace(\s+)debug_build_guard(\s+){", "", content, 1)
            second_change = re.sub("}", "", first_change, 1)
            f.seek(0)
            f.write(second_change)
            f.truncate()

    def package_info(self):
        self.cpp_info.libs.extend(tools.collect_libs(self))

这是生成的配置:

[...]
-- General configuration for OpenCV 3.4.3 =====================================
--   Version control:               3.4.3
--
--   Extra modules:
--     Location (extra):            C:/Users/RHPACHECO/.conan/data/opencv/3.4.3/kiwi/testing/build/66bc1bfbe8eb268302b5afcd9e75e1a476dbdbef/opencv_contrib/modules
--     Version control (extra):     3.4.3
--
--   Platform:
--     Timestamp:                   2019-07-31T10:13:15Z
--     Host:                        Windows 10.0.17763 AMD64
--     CMake:                       3.14.1
--     CMake generator:             Visual Studio 15 2017 Win64
--     CMake build tool:            C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/MSBuild/15.0/Bin/MSBuild.exe
--     MSVC:                        1916
--
--   CPU/HW features:
--     Baseline:                    SSE SSE2 SSE3
--       requested:                 SSE3
--     Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2
--       requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
--       SSE4_1 (3 files):          + SSSE3 SSE4_1
--       SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2
--       FP16 (1 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
--       AVX (5 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
--       AVX2 (9 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
--
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++11:                       YES
--     C++ Compiler:                C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe  (ver 19.16.27032.1)
--     C++ flags (Release):         /DWIN32 /D_WINDOWS /W4 /GR  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi      /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP12   /MD /O2 /Ob2 /DNDEBUG
--     C++ flags (Debug):           /DWIN32 /D_WINDOWS /W4 /GR  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi      /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /MP12   /MDd /Zi /Ob0 /Od /RTC1
--     C Compiler:                  C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe
--     C flags (Release):           /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi        /MP12    /MD /O2 /Ob2 /DNDEBUG
--     C flags (Debug):             /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi        /MP12  /MDd /Zi /Ob0 /Od /RTC1
--     Linker flags (Release):      /machine:x64  /INCREMENTAL:NO
--     Linker flags (Debug):        /machine:x64  /debug /INCREMENTAL
--     ccache:                      NO
--     Precompiled headers:         YES
--     Extra dependencies:          opengl32 glu32 cudart_static.lib nppc.lib nppial.lib nppicc.lib nppicom.lib nppidei.lib nppif.lib nppig.lib nppim.lib nppist.lib nppisu.lib nppitc.lib npps.lib cublas.lib cufft.lib -LIBPATH:C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.1/lib/x64
--     3rdparty dependencies:
--
--   OpenCV modules:
--     To be built:                 aruco bgsegm bioinspired calib3d ccalib core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev datasets dnn dnn_objdetect dpm face features2d flann fuzzy hfs highgui img_hash imgcodecs imgproc line_descriptor ml objdetect optflow phase_unwrapping photo plot python_bindings_generator reg rgbd saliency shape stereo structured_light superres surface_matching text tracking video videoio videostab xfeatures2d ximgproc xobjdetect xphoto
--     Disabled:                    java_bindings_generator js stitching world
--     Disabled by dependency:      -
--     Unavailable:                 cnn_3dobj cvv freetype hdf java matlab ovis python2 python3 sfm ts viz
--     Applications:                apps
--     Documentation:               NO
--     Non-free algorithms:         NO
--
--   Windows RT support:            NO
--
--   GUI:
--     Win32 UI:                    YES
--     OpenGL support:              YES (opengl32 glu32)
--     VTK support:                 NO
--
--   Media I/O:
--     ZLib:                        build (ver 1.2.11)
--     JPEG:                        build-libjpeg-turbo (ver 1.5.3-62)
--     WEBP:                        build (ver encoder: 0x020e)
--     PNG:                         build (ver 1.6.34)
--     TIFF:                        build (ver 42 - 4.0.9)
--     JPEG 2000:                   build (ver 1.900.1)
--     HDR:                         YES
--     SUNRASTER:                   YES
--     PXM:                         YES
--
--   Video I/O:
--     Video for Windows:           YES
--     DirectShow:                  YES
--     Media Foundation:            YES
--
--   Parallel framework:            Concurrency
--
--   Trace:                         YES (with Intel ITT)
--
--   Other third-party libraries:
--     Intel IPP:                   2017.0.3 [2017.0.3]
--            at:                   C:/Users/RHPACHECO/.conan/data/opencv/3.4.3/kiwi/testing/build/66bc1bfbe8eb268302b5afcd9e75e1a476dbdbef/3rdparty/ippicv/ippicv_win
--     Intel IPP IW:                sources (2017.0.3)
--               at:                C:/Users/RHPACHECO/.conan/data/opencv/3.4.3/kiwi/testing/build/66bc1bfbe8eb268302b5afcd9e75e1a476dbdbef/3rdparty/ippicv/ippiw_win
--     Lapack:                      NO
--     Eigen:                       NO
--     Custom HAL:                  NO
--     Protobuf:                    build (3.5.1)
--
--   NVIDIA CUDA:                   YES (ver 10.1, CUFFT CUBLAS)
--     NVIDIA GPU arch:             50 52 60 61
--     NVIDIA PTX archs:
--
--   OpenCL:                        YES (no extra features)
--     Include path:                C:/Users/RHPACHECO/.conan/data/opencv/3.4.3/kiwi/testing/build/66bc1bfbe8eb268302b5afcd9e75e1a476dbdbef/opencv/3rdparty/include/opencl/1.2
--     Link libraries:              Dynamic load
--
--   Python (for build):            C:/Program Files (x86)/Python37-32/python.exe
--
--   Install to:                    C:/Users/RHPACHECO/.conan/data/opencv/3.4.3/kiwi/testing/package/66bc1bfbe8eb268302b5afcd9e75e1a476dbdbef
-- -----------------------------------------------------------------
[...]

请注意它是如何生成 Release 和 Debug 构建的,然后它同时构建了两者。

我们还有一个批处理文件,它使用 CMake 为 OpenCV 生成 Visual Studio 解决方案,然后使用 MSBuild 构建它并且完全按照我们想要的方式工作,所以我怀疑问题出在柯南身上。我们还尝试使用 CMake 助手构建 OpenCV self.run(),结果似乎是一样的。

标签: windowsopencvcmakeconan

解决方案


运行安装目标将触发第二次构建,因为它的构建类型与构建命令不同。解决方案是,如果使用 CMake 帮助器,则传递 build_type="Release" 作为构造函数的参数,或者,如果从命令行帮助器运行 CMake,则传递“--config Release”。


推荐阅读