Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant