[DO-1345] fixed windows packages (!16)
Reviewed-on: https://git.avroid.tech/Conan/conan_build/pulls/16 Co-authored-by: aleksandr.vodyanov <aleksandr.vodyanov@avroid.team> Co-committed-by: aleksandr.vodyanov <aleksandr.vodyanov@avroid.team>
This commit is contained in:
committed by
Aleksandr Vodyanov
parent
3759e1163f
commit
a82e89a1bc
6
recipes/msys2/all/conandata.yml
Normal file
6
recipes/msys2/all/conandata.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
sources:
|
||||
"cci.latest":
|
||||
url:
|
||||
- "https://nexus.avroid.tech/repository/devops-raw-proxy-github/msys2/msys2-installer/releases/download/2023-10-26/msys2-base-x86_64-20231026.tar.xz"
|
||||
- "https://nexus.avroid.tech/repository/devops-raw-proxy-sourceforge_net/projects/msys2/files/Base/x86_64/msys2-base-x86_64-20231026.tar.xz"
|
||||
sha256: "fa75120560563a311241c05882016978bd35612692c7f0d39815a27837bff27d"
|
||||
196
recipes/msys2/all/conanfile.py
Normal file
196
recipes/msys2/all/conanfile.py
Normal file
@@ -0,0 +1,196 @@
|
||||
from conan import ConanFile
|
||||
from conan.errors import ConanInvalidConfiguration, ConanException
|
||||
from conan.tools.files import chdir, get, replace_in_file, copy
|
||||
from conan.tools.layout import basic_layout
|
||||
import fnmatch
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import errno
|
||||
import ctypes
|
||||
|
||||
required_conan_version = ">=1.47.0"
|
||||
|
||||
|
||||
class lock:
|
||||
def __init__(self):
|
||||
self.handle = ctypes.windll.kernel32.CreateMutexA(None, 0, "Global\\ConanMSYS2".encode())
|
||||
if not self.handle:
|
||||
raise ctypes.WinError()
|
||||
|
||||
def __enter__(self):
|
||||
status = ctypes.windll.kernel32.WaitForSingleObject(self.handle, 0xFFFFFFFF)
|
||||
if status not in [0, 0x80]:
|
||||
raise ctypes.WinError()
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
status = ctypes.windll.kernel32.ReleaseMutex(self.handle)
|
||||
if not status:
|
||||
raise ctypes.WinError()
|
||||
|
||||
def close(self):
|
||||
ctypes.windll.kernel32.CloseHandle(self.handle)
|
||||
|
||||
__del__ = close
|
||||
|
||||
class MSYS2Conan(ConanFile):
|
||||
name = "msys2"
|
||||
description = "MSYS2 is a software distro and building platform for Windows"
|
||||
url = "https://github.com/conan-io/conan-center-index"
|
||||
homepage = "http://www.msys2.org"
|
||||
license = "MSYS license"
|
||||
topics = ("msys", "unix", "subsystem")
|
||||
|
||||
settings = "os", "arch"
|
||||
# "exclude_files" "packages" "additional_packages" values are a comma separated list
|
||||
options = {
|
||||
"exclude_files": ["ANY"],
|
||||
"packages": ["ANY"],
|
||||
"additional_packages": [None, "ANY"],
|
||||
"no_kill": [True, False]
|
||||
}
|
||||
default_options = {
|
||||
"exclude_files": "*/link.exe",
|
||||
"packages": "base-devel,binutils,gcc",
|
||||
"additional_packages": None,
|
||||
"no_kill": False,
|
||||
}
|
||||
|
||||
short_paths = True
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self, src_folder="src")
|
||||
|
||||
def package_id(self):
|
||||
del self.info.options.no_kill
|
||||
|
||||
def validate(self):
|
||||
if self.settings.os != "Windows":
|
||||
raise ConanInvalidConfiguration("Only Windows supported")
|
||||
if self.settings.arch != "x86_64":
|
||||
raise ConanInvalidConfiguration("Only Windows x64 supported")
|
||||
|
||||
def source(self):
|
||||
get(self, **self.conan_data["sources"][self.version],
|
||||
destination=self.source_folder, strip_root=False) # Preserve tarball root dir (msys64/)
|
||||
|
||||
def _update_pacman(self):
|
||||
with chdir(self, os.path.join(self._msys_dir, "usr", "bin")):
|
||||
try:
|
||||
self._kill_pacman()
|
||||
|
||||
# https://www.msys2.org/docs/ci/
|
||||
self.run('bash -l -c "pacman --debug --noconfirm --ask 20 -Syuu"') # Core update (in case any core packages are outdated)
|
||||
self._kill_pacman()
|
||||
self.run('bash -l -c "pacman --debug --noconfirm --ask 20 -Syuu"') # Normal update
|
||||
self._kill_pacman()
|
||||
self.run('bash -l -c "pacman --debug -Rc dash --noconfirm"')
|
||||
except ConanException:
|
||||
self.run('bash -l -c "cat /var/log/pacman.log || echo nolog"')
|
||||
self._kill_pacman()
|
||||
raise
|
||||
|
||||
# https://github.com/msys2/MSYS2-packages/issues/1966
|
||||
def _kill_pacman(self):
|
||||
if self.options.no_kill:
|
||||
return
|
||||
if (self.settings.os == "Windows"):
|
||||
taskkill_exe = os.path.join(os.environ.get('SystemRoot'), 'system32', 'taskkill.exe')
|
||||
|
||||
log_out = True
|
||||
if log_out:
|
||||
out = subprocess.PIPE
|
||||
err = subprocess.STDOUT
|
||||
else:
|
||||
out = open(os.devnull, 'w', encoding='UTF-8')
|
||||
err = subprocess.PIPE
|
||||
|
||||
if os.path.exists(taskkill_exe):
|
||||
taskkill_cmds = [
|
||||
f"{taskkill_exe} /f /t /im pacman.exe",
|
||||
f"{taskkill_exe} /f /im gpg-agent.exe",
|
||||
f"{taskkill_exe} /f /im dirmngr.exe",
|
||||
f'{taskkill_exe} /fi "MODULES eq msys-2.0.dll"',
|
||||
]
|
||||
for taskkill_cmd in taskkill_cmds:
|
||||
try:
|
||||
proc = subprocess.Popen(taskkill_cmd, stdout=out, stderr=err, bufsize=1)
|
||||
proc.wait()
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
raise ConanException("Cannot kill pacman") from e
|
||||
|
||||
@property
|
||||
def _msys_dir(self):
|
||||
subdir = "msys64" # top-level directoy in tarball
|
||||
return os.path.join(self.source_folder, subdir)
|
||||
|
||||
def build(self):
|
||||
with lock():
|
||||
self._do_build()
|
||||
|
||||
def _do_build(self):
|
||||
packages = []
|
||||
if self.options.packages:
|
||||
packages.extend(str(self.options.packages).split(","))
|
||||
if self.options.additional_packages:
|
||||
packages.extend(str(self.options.additional_packages).split(","))
|
||||
|
||||
self._update_pacman()
|
||||
|
||||
with chdir(self, os.path.join(self._msys_dir, "usr", "bin")):
|
||||
for package in packages:
|
||||
self.run(f'bash -l -c "pacman -S {package} --noconfirm"')
|
||||
for package in ['pkgconf']:
|
||||
if self.run(f'bash -l -c "pacman -Qq {package}"', ignore_errors=True, quiet=True) == 0:
|
||||
self.run(f'bash -l -c "pacman -Rs -d -d {package} --noconfirm"')
|
||||
|
||||
self._kill_pacman()
|
||||
|
||||
# create /tmp dir in order to avoid
|
||||
# bash.exe: warning: could not find /tmp, please create!
|
||||
tmp_dir = os.path.join(self._msys_dir, 'tmp')
|
||||
if not os.path.isdir(tmp_dir):
|
||||
os.makedirs(tmp_dir)
|
||||
tmp_name = os.path.join(tmp_dir, 'dummy')
|
||||
with open(tmp_name, 'a', encoding='UTF-8'):
|
||||
os.utime(tmp_name, None)
|
||||
|
||||
# Prepend the PKG_CONFIG_PATH environment variable with an eventual PKG_CONFIG_PATH environment variable
|
||||
# Note: this is no longer needed when we exclusively support Conan 2 integrations
|
||||
replace_in_file(self, os.path.join(self._msys_dir, "etc", "profile"),
|
||||
'PKG_CONFIG_PATH="', 'PKG_CONFIG_PATH="${PKG_CONFIG_PATH:+${PKG_CONFIG_PATH}:}')
|
||||
|
||||
def package(self):
|
||||
excludes = None
|
||||
if self.options.exclude_files:
|
||||
excludes = tuple(str(self.options.exclude_files).split(","))
|
||||
for exclude in excludes:
|
||||
for root, _, filenames in os.walk(self._msys_dir):
|
||||
for filename in filenames:
|
||||
fullname = os.path.join(root, filename)
|
||||
if fnmatch.fnmatch(fullname, exclude):
|
||||
os.unlink(fullname)
|
||||
# See https://github.com/conan-io/conan-center-index/blob/master/docs/error_knowledge_base.md#kb-h013-default-package-layout
|
||||
copy(self, "*", dst=os.path.join(self.package_folder, "bin", "msys64"), src=self._msys_dir, excludes=excludes)
|
||||
shutil.copytree(os.path.join(self._msys_dir, "usr", "share", "licenses"),
|
||||
os.path.join(self.package_folder, "licenses"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libdirs = []
|
||||
self.cpp_info.includedirs = []
|
||||
|
||||
msys_root = os.path.join(self.package_folder, "bin", "msys64")
|
||||
msys_bin = os.path.join(msys_root, "usr", "bin")
|
||||
self.cpp_info.bindirs.append(msys_bin)
|
||||
|
||||
self.buildenv_info.define_path("MSYS_ROOT", msys_root)
|
||||
self.buildenv_info.define_path("MSYS_BIN", msys_bin)
|
||||
|
||||
self.conf_info.define("tools.microsoft.bash:subsystem", "msys2")
|
||||
self.conf_info.define("tools.microsoft.bash:path", os.path.join(msys_bin, "bash.exe"))
|
||||
|
||||
# conan v1 specific stuff
|
||||
self.env_info.MSYS_ROOT = msys_root
|
||||
self.env_info.MSYS_BIN = msys_bin
|
||||
self.env_info.path.append(msys_bin)
|
||||
34
recipes/msys2/all/test_package/conanfile.py
Normal file
34
recipes/msys2/all/test_package/conanfile.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.env import Environment
|
||||
from io import StringIO
|
||||
|
||||
|
||||
class TestPackageConan(ConanFile):
|
||||
settings = "os", "arch"
|
||||
generators = "VirtualBuildEnv"
|
||||
test_type = "explicit"
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires(self.tested_reference_str)
|
||||
|
||||
@property
|
||||
def _secret_value(self):
|
||||
return "SECRET_CONAN_PKG_VARIABLE"
|
||||
|
||||
def generate(self):
|
||||
env = Environment()
|
||||
env.define("PKG_CONFIG_PATH", self._secret_value)
|
||||
envvars = env.vars(self)
|
||||
envvars.save_script("conanbuildenv_pkg_config_path")
|
||||
|
||||
def build(self):
|
||||
pass # nothing to do, skip hook warning
|
||||
|
||||
def test(self):
|
||||
self.run('bash.exe -c ^"make --version^"')
|
||||
self.run('bash.exe -c ^"! test -f /bin/link^"')
|
||||
self.run('bash.exe -c ^"! test -f /usr/bin/link^"')
|
||||
|
||||
output = StringIO()
|
||||
self.run('bash.exe -c "echo $PKG_CONFIG_PATH"', output)
|
||||
assert self._secret_value in output.getvalue()
|
||||
28
recipes/msys2/all/test_v1_package/conanfile.py
Normal file
28
recipes/msys2/all/test_v1_package/conanfile.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from conans import ConanFile, tools
|
||||
from conans.errors import ConanException
|
||||
from io import StringIO
|
||||
|
||||
|
||||
class TestPackageConan(ConanFile):
|
||||
settings = "os", "arch", "compiler", "build_type"
|
||||
|
||||
def build(self):
|
||||
pass # nothing to do, skip hook warning
|
||||
|
||||
def test(self):
|
||||
bash = tools.which("bash.exe")
|
||||
|
||||
if bash:
|
||||
self.output.info("using bash.exe from: " + bash)
|
||||
else:
|
||||
raise ConanException("No instance of bash.exe could be found on %PATH%")
|
||||
|
||||
self.run('bash.exe -c ^"make --version^"')
|
||||
self.run('bash.exe -c ^"! test -f /bin/link^"')
|
||||
self.run('bash.exe -c ^"! test -f /usr/bin/link^"')
|
||||
|
||||
secret_value = "SECRET_CONAN_PKG_VARIABLE"
|
||||
with tools.environment_append({"PKG_CONFIG_PATH": secret_value}):
|
||||
output = StringIO()
|
||||
self.run('bash.exe -c "echo $PKG_CONFIG_PATH"', output=output)
|
||||
assert secret_value in output.getvalue()
|
||||
3
recipes/msys2/config.yml
Normal file
3
recipes/msys2/config.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
versions:
|
||||
"cci.latest":
|
||||
folder: "all"
|
||||
Reference in New Issue
Block a user