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

Add support for zypper package manager #3828

Merged
merged 4 commits into from
Jun 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ Xmake can automatically fetch and install dependencies!
* Portage on Gentoo/Linux (portage::libhandy)
* Nimble for nimlang (nimble::zip >1.3)
* Cargo for rust (cargo::base64 0.13.0)
* Zypper on openSUSE (zypper::libsfml2 2.5)

### Package management features

Expand Down
54 changes: 54 additions & 0 deletions xmake/modules/detect/tools/find_rpm.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author ruki, Lingfeng Fu
-- @file find_rpm.lua
--

-- imports
import("lib.detect.find_program")
import("lib.detect.find_programver")

-- find rpm
--
-- @param opt the argument options, e.g. {version = true}
--
-- @return program, version
--
-- @code
--
-- local rpm = find_rpm()
-- local rpm, version = find_rpm({version = true})
--
-- @endcode
--
function main(opt)

-- init options
opt = opt or {}

-- find program
local program = find_program(opt.program or "rpm", opt)

-- find program version
local version = nil
if program and opt and opt.version then
version = find_programver(program, opt)
end

-- ok?
return program, version
end
54 changes: 54 additions & 0 deletions xmake/modules/detect/tools/find_zypper.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author ruki, Lingfeng Fu
-- @file find_zypper.lua
--

-- imports
import("lib.detect.find_program")
import("lib.detect.find_programver")

-- find zypper
--
-- @param opt the argument options, e.g. {version = true}
--
-- @return program, version
--
-- @code
--
-- local zypper = find_zypper()
-- local zypper, version = find_zypper({version = true})
--
-- @endcode
--
function main(opt)

-- init options
opt = opt or {}

-- find program
local program = find_program(opt.program or "zypper", opt)

-- find program version
local version = nil
if program and opt and opt.version then
version = find_programver(program, opt)
end

-- ok?
return program, version
end
1 change: 1 addition & 0 deletions xmake/modules/package/manager/install_package.lua
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function _install_package(manager_name, package_name, opt)
table.insert(managers, "pacman")
table.insert(managers, "portage")
table.insert(managers, "brew")
table.insert(managers, "zypper")
elseif is_host("macosx") then
table.insert(managers, "vcpkg")
table.insert(managers, "brew")
Expand Down
154 changes: 154 additions & 0 deletions xmake/modules/package/manager/zypper/find_package.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author ruki, Lingfeng Fu
-- @file find_package.lua
--

-- imports
import("core.base.option")
import("core.project.config")
import("core.project.target")
import("lib.detect.find_tool")
import("package.manager.pkgconfig.find_package", { alias = "find_package_from_pkgconfig" })

-- find package
function _find_package(rpm, name, opt)
if opt.require_version and opt.require_version ~= "latest" then
name = name .. '-' .. opt.require_version:gsub('%.', '_')
end
local result = nil
local pkgconfig_files = {}
local listinfo = try { function()
return os.iorunv(rpm.program, { "-ql", name })
end }
if listinfo then
for _, line in ipairs(listinfo:split('\n', { plain = true })) do
line = line:trim()

-- get includedirs
local pos = line:find("include/", 1, true)
if pos then
-- we need not add includedirs, gcc/clang will use /usr/ as default sysroot
result = result or {}
end

-- get pc files
if line:find("/pkgconfig/", 1, true) and line:endswith(".pc") then
table.insert(pkgconfig_files, line)
end

-- get linkdirs and links
if line:endswith(".a") or line:endswith(".so") then
result = result or {}
result.links = result.links or {}
result.linkdirs = result.linkdirs or {}
result.libfiles = result.libfiles or {}
table.insert(result.linkdirs, path.directory(line))
table.insert(result.links, target.linkname(path.filename(line), { plat = opt.plat }))
table.insert(result.libfiles, path.join(path.directory(line), path.filename(line)))
end
end
end

-- we iterate over each pkgconfig file to extract the required data
local foundpc = false
local pcresult = { includedirs = {}, linkdirs = {}, links = {} }
for _, pkgconfig_file in ipairs(pkgconfig_files) do
local pkgconfig_dir = path.directory(pkgconfig_file)
local pkgconfig_name = path.basename(pkgconfig_file)
local pcinfo = find_package_from_pkgconfig(pkgconfig_name, { configdirs = pkgconfig_dir, linkdirs = linkdirs })

-- the pkgconfig file has been parse successfully
if pcinfo then
for _, includedir in ipairs(pcinfo.includedirs) do
table.insert(pcresult.includedirs, includedir)
end
for _, linkdir in ipairs(pcinfo.linkdirs) do
table.insert(pcresult.linkdirs, linkdir)
end
for _, link in ipairs(pcinfo.links) do
table.insert(pcresult.links, link)
end
-- version should be the same if a pacman package contains multiples .pc
pcresult.version = pcinfo.version
foundpc = true
end
end
if foundpc == true then
pcresult.includedirs = table.unique(pcresult.includedirs)
pcresult.linkdirs = table.unique(pcresult.linkdirs)
pcresult.links = table.reverse_unique(pcresult.links)
result = pcresult
end

-- meta/alias package? e.g. libboost_headers-devel -> libboost_headers1_82_0-devel
-- @see https://github.com/xmake-io/xmake/issues/1786
if not result then
local statusinfo = try { function()
return os.iorunv(rpm.program, { "-qR", name })
end }
if statusinfo then
for _, line in ipairs(statusinfo:split("\n", { plain = true })) do
-- parse depends, e.g. Depends: libboost1.74-dev
if not line:startswith("rpmlib(") then
local depends = line
result = _find_package(rpm, depends, opt)
if result then
return result
end
end
end
end
end

-- remove repeat
if result then
if result.links then
result.links = table.unique(result.links)
end
if result.linkdirs then
result.linkdirs = table.unique(result.linkdirs)
end
if result.includedirs then
result.includedirs = table.unique(result.includedirs)
end
end
return result
end

-- find package using the rpm package manager
--
-- @param name the package name
-- @param opt the options, e.g. {verbose = true, version = "1.12.0")
--
function main(name, opt)

-- check
opt = opt or {}
if not is_host(opt.plat) or os.arch() ~= opt.arch then
return
end

-- find rpm
local rpm = find_tool("rpm")
if not rpm then
return
end

-- find package
return _find_package(rpm, name, opt)
end
65 changes: 65 additions & 0 deletions xmake/modules/package/manager/zypper/install_package.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author ruki, Lingfeng Fu
-- @file install_package.lua
--

-- imports
import("core.base.option")
import("lib.detect.find_tool")
import("privilege.sudo")

-- install package
--
-- @param name the package name
-- @param opt the options, e.g. {verbose = true, apt = "the package name"}
--
-- @return true or false
--
function main(name, opt)

-- init options
opt = opt or {}
if opt.require_version and opt.require_version ~= "latest" then
name = name .. '-' .. opt.require_version:gsub('%.', '_')
end

-- find apt
local zypper = find_tool("zypper")
if not zypper then
raise("apt not found!")
end

-- init argv
local argv = { "install", "-y", opt.zypper or name }

-- install package directly if the current user is root
if os.isroot() then
os.vrunv(zypper.program, argv)
-- install with administrator permission?
elseif sudo.has() then

-- install it if be confirmed
local description = format("try installing %s with administrator permission", name)
local confirm = utils.confirm({ default = true, description = description })
if confirm then
sudo.vrunv(zypper.program, argv)
end
else
raise("cannot get administrator permission!")
end
end
Loading