Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Finally a conan package (Soon) #675

Open
4 of 8 tasks
Ohjurot opened this issue Jun 7, 2023 · 0 comments
Open
4 of 8 tasks

Finally a conan package (Soon) #675

Ohjurot opened this issue Jun 7, 2023 · 0 comments

Comments

@Ohjurot
Copy link

Ohjurot commented Jun 7, 2023

Hello,

I recently wondered how the state of nana and conan is.
I found this: https://github.com/ppetraki/conan-nana-meson (#283)
However, I noticed a few issues with the package:

  • No options exposed (audio, jpeg, png)
  • Not following the latest (conan2) style
  • Not working on Linux (dependencies for xorg and libxft missing)
  • Build dependencies (CMake) missing
  • Not available in conan center

So I opted in rewriting the recipe to meet all modern conan requirements.
The recipe has been implemented on my Windows machine and works. However
for full Linux support, I need to wait until conan-io/conan-center-index#18789 is done.

The purpose of this issue is to keep you updated on the progress and provide a draft recipe for download. Any feedback is highly appreciated!

TODO List:

  • Basic recipe
  • Windows compatibility
  • Windows shared lib (CMake / Conan / Nana bug? Does not build... wants to export == on debug... ofc this symbol is not defined)
  • OSX compatibility (Simple: It's not going to happen for 1.4.7 ... I don't have a mac...)
  • Linux compatibility (What is going on freetype... why do you not include yourself...)
  • PR on conan-center-index
  • Probably bug fixing until it works on all configurations
  • Merged into conan center

Here is my current working draft conanfile.py:

"""
Conan package for http://nanapro.org
Recipe Author: https://github.com/Ohjurot

AVAILABLE OPTIONS:
  - enable_audio: WAV Audio player
  - enable_jpeg: JPEG Decoding for picture widget
  - enable_png: PNG Decoding for picture widget

INFORMATION FOR LINUX USERS:
  Make sure to install xorg/system once as root! After that non root user will be able
  to use the lib / it's x11 dependencies!
  > conan install --requires=xorg/system -c tools.system.package_manager:mode=install
"""

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.build import check_min_cppstd
from conan.tools.files import get, copy, replace_in_file

import os.path

class NanaRecipe(ConanFile):
    name = "nana"
    version = "1.7.4"

    # Optional metadata
    license = "BSL-1.0"
    author = "Jinhao and individual nanapro.org contributors"
    url = "http://nanapro.org/"
    description = "Nana is a cross-platform library for GUI programming in modern C++ style"
    topics = ("gui", "ui", "forms", "user", "interface", "modern")

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {
        # Conan CMake defaults
        "shared": [True, False], 
        "fPIC": [True, False],
        # Nana options
        "enable_audio": [True, False],
        "enable_jpeg": [True, False],
        "enable_png": [True, False],
    }
    default_options = {
        "shared": False, 
        "fPIC": True,
        "enable_audio": False,
        "enable_jpeg": False,
        "enable_png": False,
    }

    def source(self):
        get(self, **self.conan_data["sources"][self.version])

    def validate(self):
        check_min_cppstd(self, "11")

    def requirements(self):
        # Linux requirements
        if self.settings.os == "Linux":
            self.requires("xorg/system")
            # libxft is not conan2 compatible... 
            # See: https://github.com/conan-io/conan-center-index/pull/17485
            self.requires("libxft/2.3.6") 

        # Option based requirements
        if self.options.enable_jpeg:
            self.requires("libjpeg/9e")
        if self.options.enable_png:
            self.requires("libpng/1.6.39")

    def build_requirements(self):
        self.build_requires("cmake/3.26.4")
        if self.settings.os == "Linux":
            self.tool_requires("pkgconf/1.9.3")

    def config_options(self):
        if self.settings.os == "Windows":
            self.options.rm_safe("fPIC")

    def configure(self):
        if self.options.shared:
            self.options.rm_safe("fPIC")

    def layout(self):
        cmake_layout(self)

    def generate(self):
        deps = CMakeDeps(self)
        deps.generate()

        tc = CMakeToolchain(self)

        # Enable the use of the conan configuration header 
        # (required for all following options)
        tc.variables["NANA_CMAKE_ENABLE_CONF"] = True
        # Use os like include paths (but the libs will be provided by conan)
        tc.variables["NANA_CMAKE_LIBJPEG_FROM_OS"] = True
        tc.variables["NANA_CMAKE_LIBPNG_FROM_OS"] = True
        # Make cmake install work 
        tc.variables["NANA_CMAKE_INSTALL"] = True 

        # Set vars for optional features
        if self.options.enable_audio:
            tc.variables["NANA_CMAKE_ENABLE_AUDIO"] = True
        if self.options.enable_jpeg:
            tc.variables["NANA_CMAKE_ENABLE_JPEG"] = True
        if self.options.enable_png:
            tc.variables["NANA_CMAKE_ENABLE_PNG"] = True
        
        # Static runtime for msvc
        compiler = self.settings.get_safe("compiler")
        if compiler and str(compiler).lower() == "msvc":
            compiler_runtime = self.settings.get_safe("compiler.runtime")
            tc.variables["MSVC_USE_STATIC_RUNTIME"] = (
                compiler_runtime != None and (compiler_runtime).lower() == "static"
                )

        tc.generate()

    def build(self):
        # We need to patch "system/split_string.cpp" on old versions 
        # they used "and" instead of "&&" in this file
        if self.version == "1.7.4":
            replace_in_file(
                self, 
                os.path.join(self.source_folder, "source/system", "split_string.cpp"), 
                " and ", " && "
                )

        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()
        copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))

    def package_info(self):
        self.cpp_info.libs = ["nana"]

        # Add defines based on options
        if self.options.enable_audio:
            self.cpp_info.defines.append("NANA_ENABLE_AUDIO")
        if self.options.enable_jpeg:
            self.cpp_info.defines.extend(("NANA_ENABLE_JPEG", "USE_LIBJPEG_FROM_OS"))
        if self.options.enable_png:
            self.cpp_info.defines.extend(("NANA_ENABLE_PNG", "USE_LIBPNG_FROM_OS"))

And the corresponding conandata.yml

sources:
  "1.7.4":
    url: "https://github.com/cnjinhao/nana/archive/refs/tags/v1.7.4.zip"
    sha256: "f80f70624383026ff7c74a42cdb4beba9ec9bb0fb411f3c108325a15cfb11dcb"
    strip_root: true
@Ohjurot Ohjurot closed this as completed Jun 13, 2023
@Ohjurot Ohjurot reopened this Jun 13, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant