conan-io / conan-center-index

Recipes for the ConanCenter repository
https://conan.io/center
MIT License
966 stars 1.77k forks source link

[question] Contributing a package needing the DirectX SDK #9441

Open HerrNamenlos123 opened 2 years ago

HerrNamenlos123 commented 2 years ago

I want to create a package for the official allegro5 framework, and contribute it to conancenter. The problem is it requires the Microsoft DirectX SDK on Windows. Is there a way this can be achieved in conancenter?

On my machine I basically have to download and install it, then I can build the conan package as soon as cmake finds it. Can this be done with the automated CI as well?

Is there a windows server container which runs the build process and has the 2010 DirectX SDK already installed? Or can it be automatically downloaded and installed using conanfile.py?

The same is for linux, there it requires the x11 apt package to be installed, what's the proper way to handle this?

SpaceIm commented 2 years ago

DirectX SDK is part of Windows SDK, so it comes for free in a regular Visual Studio installation (even MinGW has proper support for DirectX since MinGW 8.0.0). For X11, there is system recipe: xorg.

HerrNamenlos123 commented 2 years ago

hmm, on my machine I had to install it separately... Thanks for the answer, I'm going to investigate this further

HerrNamenlos123 commented 2 years ago

I have now tried to add the xorg and opengl dependency to the project. When I run conan create . this is what it says:

me@ubuntu:~/allegro5-conan$ conan create .
Exporting package recipe
allegro5/5.2.7: The stored package has not changed
allegro5/5.2.7: Exported revision: 30ff965ad230f917eb4b153f61a0d080
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++11
compiler.version=9
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

allegro5/5.2.7: Forced build from source
Installing package: allegro5/5.2.7
Requirements
    allegro5/5.2.7 from local cache - Cache
    brotli/1.0.9 from 'conancenter' - Cache
    bzip2/1.0.8 from 'conancenter' - Cache
    freetype/2.11.1 from 'conancenter' - Cache
    libjpeg/9d from 'conancenter' - Cache
    libpng/1.6.37 from 'conancenter' - Cache
    libwebp/1.2.2 from 'conancenter' - Cache
    opengl/system from 'conancenter' - Cache
    xorg/system from 'conancenter' - Cache
    zlib/1.2.11 from 'conancenter' - Cache
Packages
    allegro5/5.2.7:94b4717c2d38fc5222eb656d7d66a744da2b9c4d - Build
    brotli/1.0.9:6af9cc7cb931c5ad942174fd7838eb655717c709 - Cache
    bzip2/1.0.8:da606cf731e334010b0bf6e85a2a6f891b9f36b0 - Cache
    freetype/2.11.1:f1014dc4f9380132c471ceb778980949abf136d3 - Cache
    libjpeg/9d:6af9cc7cb931c5ad942174fd7838eb655717c709 - Cache
    libpng/1.6.37:7929d8ecf29c60d74fd3c1f6cb78bbb3cb49c0c7 - Cache
    libwebp/1.2.2:034afc24309e6fc60dbccb1dab5b0f9cad6ec656 - Cache
    opengl/system:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache
    xorg/system:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache
    zlib/1.2.11:6af9cc7cb931c5ad942174fd7838eb655717c709 - Cache

Installing (downloading, building) binaries...
brotli/1.0.9: Already installed!
bzip2/1.0.8: Already installed!
bzip2/1.0.8: Appending PATH environment variable: /home/me/.conan/data/bzip2/1.0.8/_/_/package/da606cf731e334010b0bf6e85a2a6f891b9f36b0/bin
libjpeg/9d: Already installed!
libwebp/1.2.2: Already installed!
dpkg-query: no packages found matching libgl-dev
ERROR: The following packages need to be installed:
 libgl-dev
opengl/system: ERROR: while executing system_requirements(): Aborted due to CONAN_SYSREQUIRES_MODE=verify. Some system packages need to be installed
ERROR: Error in system requirements
me@ubuntu:~/allegro5-conan$

This is my conanfile.py: It's the entire file, it's so long because of all the cmake flags. You only need to look at the requirements() callback.

from conans import ConanFile, CMake, tools
import os

class Allegro5Conan(ConanFile):
    name = "allegro5"
    version = "5.2.7"
    license = "<Put the package license here>"
    author = "<Put your name here> <And your email here>"
    url = "<Package recipe repository url here, for issues about the package>"
    description = "<Description of Allegro5 here>"
    topics = ("<Put some tag here>", "<here>", "<and here>")
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}
    generators = "cmake"

    # Fixed dependencies
    requires = "libpng/1.6.37", "zlib/1.2.11", "libjpeg/9d", "libwebp/1.2.2", "freetype/2.11.1", "bzip2/1.0.8"

    def requirements(self):       # Conditional dependencies
        if self.settings.os != "Windows":
            self.requires("xorg/system")
            self.requires("opengl/system")

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

    def source(self):
        self.run("git clone https://github.com/liballeg/allegro5.git --depth=1 --single-branch --branch=5.2.7")

    def generate(self):

        zlib = self.dependencies["zlib"]
        libpng = self.dependencies["libpng"]
        libjpeg = self.dependencies["libjpeg"]
        libwebp = self.dependencies["libwebp"]
        freetype = self.dependencies["freetype"]
        bzip2 = self.dependencies["bzip2"]

        # Read paths into variables because they are read-only
        zlib_package_folder = zlib.package_folder
        libpng_package_folder = libpng.package_folder
        libjpeg_package_folder = libjpeg.package_folder
        libwebp_package_folder = libwebp.package_folder
        freetype_package_folder = freetype.package_folder
        bzip2_package_folder = bzip2.package_folder

        # Library paths cannot contain windows backspaces because of cmake's target_link_libraries()
        if self.settings.os == "Windows":
            zlib_package_folder = zlib_package_folder.replace("\\","/")
            libpng_package_folder = libpng_package_folder.replace("\\","/")
            libjpeg_package_folder = libjpeg_package_folder.replace("\\","/")
            libwebp_package_folder = libwebp_package_folder.replace("\\","/")
            freetype_package_folder = freetype_package_folder.replace("\\","/")
            bzip2_package_folder = bzip2_package_folder.replace("\\","/")

        # Configure dependency flags for cmake
        flags = "-Wno-dev"
        flags += " -DPREFER_STATIC_DEPS=true"
        flags += " -DSHARED=" + str(self.options.shared).lower()
        flags += " -DWANT_DOCS=false"
        flags += " -DWANT_DOCS_HTML=false"
        flags += " -DWANT_EXAMPLES=false"
        flags += " -DWANT_FONT=true"
        flags += " -DWANT_MONOLITH=true"
        flags += " -DWANT_TESTS=false"
        flags += " -DWANT_DEMO=false"
        flags += " -DWANT_RELEASE_LOGGING=false"

        if self.settings.os == "Windows":
            flags += " -DWANT_STATIC_RUNTIME=" + str(self.settings.compiler.runtime == "MT").lower()
        else:
            flags += " -DWANT_STATIC_RUNTIME=false"

        flags += " -DPNG_PNG_INCLUDE_DIR=" + libpng_package_folder + "/include/"
        flags += " -DPNG_LIBRARY=" + libpng_package_folder + "/lib/libpng16.lib;"
        flags += " -DPNG_LIBRARIES=" + libpng_package_folder + "/lib/libpng16.lib;"
        flags += " -DPNG_FOUND=TRUE"

        flags += " -DJPEG_INCLUDE_DIR=" + libjpeg_package_folder + "/include/"
        flags += " -DJPEG_LIBRARY=" + libjpeg_package_folder + "/lib/libjpeg.lib;"
        flags += " -DJPEG_FOUND=TRUE"

        flags += " -DZLIB_INCLUDE_DIR=" + zlib_package_folder + "/include/"
        flags += " -DZLIB_LIBRARIES=" + zlib_package_folder + "/lib/zlib.lib"
        flags += " -DZLIB_FOUND=TRUE"

        flags += " -DWEBP_INCLUDE_DIRS=" + libwebp_package_folder + "/include/"
        flags += " -DWEBP_LIBRARIES=" + libwebp_package_folder + "/lib/webp.lib;" + \
            libwebp_package_folder + "/lib/webpdecoder.lib;" + \
            libwebp_package_folder + "/lib/webpdemux.lib;" + \
            libwebp_package_folder + "/lib/webpmux.lib"

        flags += " -DFREETYPE_INCLUDE_DIRS=" + freetype_package_folder + "/include/"
        flags += " -DFREETYPE_LIBRARY=" + freetype_package_folder + "/lib/freetype.lib;"
        flags += " -DBZIP2_INCLUDE_DIR=" + bzip2_package_folder + "/include/"
        flags += " -DBZIP2_LIBRARIES=" + bzip2_package_folder + "/lib/bz2.lib;"
        flags += " -DBZIP2_FOUND=TRUE"

        flags += " -DFREETYPE_PNG=on"
        flags += " -DFREETYPE_BZIP2=on"
        flags += " -DFREETYPE_ZLIB=on"

        # Call cmake generate
        if not os.path.exists("allegro5/build"):
            os.mkdir("allegro5/build")
        os.chdir("allegro5/build")
        self.run("cmake .. " + flags)

    def build(self):
        self.run("cd allegro5/build & cmake --build . --config RelWithDebInfo") # Build the project

    def package(self):
        self.copy("*", dst="include", src="allegro5/include")
        self.copy("*.lib", dst="lib", src="allegro5/build/lib/RelWithDebInfo")

    def package_info(self):
        self.cpp_info.libs = ["allegro_monolith-static"]

Apparently it tries to install libgl-dev. sudo apt install libgl-dev works, however. What could this be?

Croydon commented 2 years ago

opengl/system: ERROR: while executing system_requirements(): Aborted due to CONAN_SYSREQUIRES_MODE=verify. Some system packages need to be installed

https://docs.conan.io/en/latest/reference/env_vars.html#conan-sysrequires-mode

If you want Conan to install the packages automatically (you still might need to enter your account password), then you have to set CONAN_SYSREQUIRES_MODE to enabled

HerrNamenlos123 commented 2 years ago

Hmm, interesting. The strange thing is when I remove opengl and only leave xorg, it runs apt automatically, asks for the root password and installs the packages. Wouldn't know why it can install xorg automatically with root access, but not opengl.

But okay, i will try this. Thank you for your hint!

HerrNamenlos123 commented 2 years ago

I think i'm wrapping myself in confusion as i go. I will solve the xorg problem later. I want to build allegro5. I did it by cloning the git repo in source(), then when generating i construct a huge string with all cmake flags and the location for each library from the other conan packages and the i call cmake manually from the command line.

This works for windows. Now with some fiddling it also works for linux, but most of the libraries are not found yet. So i tried separating it because not all libraries are needed on linux that are needed on windows (are needed, but don't need to be specified). Now i have two separate huge code chunks for windows and linux.

But now i realised on windows you can also compile with MinGW instead of MSVC and suddenly all the .lib library endings are not correct anymore. So the problem keeps getting more and more complex. Now i need .lib and .a endings, based on the compiler used.

Is this the right way to go? Or do i have to view the problem from a completely different angle?

The problem is that i don't want to modify large parts of the allegro source code, otherwise my code probably wouldn't be accepted so easily. Currently i saw the only option to compile it to call cmake manually and supply all library paths.

And if this actually is the way to go, is there a more cross platform way to do it? I can't really use the builtin library dirs and paths, because the cmake flags only accept full paths of the .lib or .a files...