Skip to content

Commit

Permalink
Merge pull request #5335 from xmake-io/install
Browse files Browse the repository at this point in the history
Improve installation
  • Loading branch information
waruqi authored Jul 23, 2024
2 parents 45852e6 + 56ca5ad commit d4364ef
Show file tree
Hide file tree
Showing 35 changed files with 1,187 additions and 912 deletions.
8 changes: 8 additions & 0 deletions tests/actions/install/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Xmake cache
.xmake/
build/

# MacOS Cache
.DS_Store


5 changes: 5 additions & 0 deletions tests/actions/install/src/foo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "foo.h"

int add(int a, int b) {
return a + b;
}
17 changes: 17 additions & 0 deletions tests/actions/install/src/foo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifdef __cplusplus
extern "C" {
#endif

#if defined(_WIN32)
# define __export __declspec(dllexport)
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
# define __export __attribute__((visibility("default")))
#else
# define __export
#endif

__export int add(int a, int b);

#ifdef __cplusplus
}
#endif
Empty file.
7 changes: 7 additions & 0 deletions tests/actions/install/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "foo.h"
#include <iostream>

int main(int argc, char** argv) {
std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
return 0;
}
10 changes: 10 additions & 0 deletions tests/actions/install/test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function main(t)
if is_host("windows", "linux", "macosx") and os.arch():startswith("x") then
os.vrun("xmake -y")
os.vrun("xmake run app")
os.vrun("xmake install -o build/usr")
if not is_host("linux") then -- TODO, change rpath has been not supported yet on linux.
os.vrun("./build/usr/app/bin/app" .. (is_host("windows") and ".exe" or ""))
end
end
end
27 changes: 27 additions & 0 deletions tests/actions/install/xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
add_rules("mode.debug", "mode.release")

set_version("1.0.1", {soname = true})

add_requires("libzip", {system = false, configs = {shared = true}})

target("foo")
set_kind("shared")
add_files("src/foo.cpp")
add_packages("libzip", {public = true})
add_headerfiles("src/foo.h", {public = true})
add_installfiles("src/foo.txt", {prefixdir = "assets", public = true})
set_prefixdir("/", {libdir = "foo_lib"})

target("app")
set_kind("binary")
add_deps("foo")
add_files("src/main.cpp")
set_prefixdir("app", {libdir = "app_lib"})
add_rpathdirs("@loader_path/../app_lib", {installonly = true})

includes("@builtin/xpack")

xpack("test")
add_targets("app")
set_formats("zip")

12 changes: 8 additions & 4 deletions xmake/actions/clean/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,19 @@ end

-- clean target
function _clean(targetname)

-- clean the given target
if targetname then
local target = project.target(targetname)
_clean_target(target)
else
_clean_targets(project.ordertargets())
end
end

-- remove the configure directory if remove all
-- clean configuration cache
function _clean_configs()
if option.get("all") then
-- we need to close it first after removing file lock
project.filelock():close()
remove_files(config.directory())
end
end
Expand Down Expand Up @@ -142,7 +144,6 @@ function _try_clean()
end
end

-- main
function main()

-- try cleaning it using third-party buildsystem if xmake.lua not exists
Expand Down Expand Up @@ -176,6 +177,9 @@ function main()
-- unlock the whole project
project.unlock()

-- we must call it after unlocking project because it will remove project lockfile
_clean_configs()

-- leave project directory
os.cd(oldir)
end
2 changes: 0 additions & 2 deletions xmake/actions/install/install.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,11 @@ function main(targetname, group_pattern)
local targets = {}
if targetname and not targetname:startswith("__") then
local target = project.target(targetname)
table.join2(targets, target:orderdeps())
table.insert(targets, target)
else
for _, target in ipairs(project.ordertargets()) do
local group = target:get("group")
if (target:is_default() and not group_pattern) or targetname == "__all" or (group_pattern and group and group:match(group_pattern)) then
table.join2(targets, target:orderdeps())
table.insert(targets, target)
end
end
Expand Down
21 changes: 6 additions & 15 deletions xmake/actions/install/install_admin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,30 @@ import("core.project.project")
import("core.platform.platform")
import("install")

-- install
function main(targetname, group_pattern, installdir, prefix)

local verbose = option.get("verbose")
if group_pattern and #group_pattern == 0 then
group_pattern = nil
end
if installdir and #installdir == 0 then
installdir = nil
end

-- enter project directory
os.cd(project.directory())

-- load config
config.load()

-- load platform
platform.load(config.plat())

-- save the current option and push a new option context
option.save()

-- preserve verbose option
option.set("verbose", verbose)

-- pass installdir to option
if installdir then
option.set("installdir", installdir)
end

-- pass prefix to option
if prefix then
option.set("prefix", prefix)
end

-- install target
install(targetname, group_pattern)

-- restore the previous option context
option.restore()
end
5 changes: 4 additions & 1 deletion xmake/actions/install/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ function main()
if sudo.has() and option.get("admin") then

-- install target with administrator permission
sudo.execl(path.join(os.scriptdir(), "install_admin.lua"), {targetname or (option.get("all") and "__all" or "__def"), group_pattern, option.get("installdir"), option.get("prefix")})
sudo.execl(path.join(os.scriptdir(), "install_admin.lua"), {
targetname or (option.get("all") and "__all" or "__def"),
group_pattern or "", option.get("installdir") or "",
option.get("prefix")})
cprint("${color.success}install ok!")
ok = true
end
Expand Down
5 changes: 4 additions & 1 deletion xmake/actions/uninstall/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ function main()
if sudo.has() and option.get("admin") then

-- uninstall target with administrator permission
sudo.execl(path.join(os.scriptdir(), "uninstall_admin.lua"), {targetname or "__all", option.get("installdir"), option.get("prefix")})
sudo.execl(path.join(os.scriptdir(), "uninstall_admin.lua"), {
targetname or "__all",
option.get("installdir") or "",
option.get("prefix")})

-- trace
cprint("${color.success}uninstall ok!")
Expand Down
2 changes: 0 additions & 2 deletions xmake/actions/uninstall/uninstall.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,11 @@ function main(targetname)
local targets = {}
if targetname and not targetname:startswith("__") then
local target = project.target(targetname)
table.join2(targets, target:orderdeps())
table.insert(targets, target)
else
for _, target in ipairs(project.ordertargets()) do
local group = target:get("group")
if (target:is_default() and not group_pattern) or targetname == "__all" or (group_pattern and group and group:match(group_pattern)) then
table.join2(targets, target:orderdeps())
table.insert(targets, target)
end
end
Expand Down
18 changes: 3 additions & 15 deletions xmake/actions/uninstall/uninstall_admin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,27 @@ import("core.project.project")
import("core.platform.platform")
import("uninstall")

-- uninstall
function main(targetname, installdir, prefix)

local verbose = option.get("verbose")
if installdir and #installdir == 0 then
installdir = nil
end

-- enter project directory
os.cd(project.directory())

-- load config
config.load()

-- load platform
platform.load(config.plat())

-- save the current option and push a new option context
option.save()

-- preserve verbose option
option.set("verbose", verbose)

-- pass installdir to option
if installdir then
option.set("installdir", installdir)
end

-- pass prefix to option
if prefix then
option.set("prefix", prefix)
end

-- uninstall target
uninstall(targetname ~= "__all" and targetname or nil)

-- restore the previous option context
option.restore()
end
2 changes: 1 addition & 1 deletion xmake/core/base/os.lua
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ function os.rm(filepath, opt)
return false, errors
end
if opt.emptydirs then
ok, errors = os._rm_empty_parentdirs(filepath)
ok, errors = os._rm_empty_parentdirs(_filepath)
if not ok then
return false, errors
end
Expand Down
4 changes: 4 additions & 0 deletions xmake/core/project/policy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ function policy.policies()
["build.sanitizer.leak"] = {description = "Enable leak sanitizer for c/c++ building.", type = "boolean"},
-- Enable undefined sanitizer for c/c++ building.
["build.sanitizer.undefined"] = {description = "Enable undefined sanitizer for c/c++ building.", type = "boolean"},
-- Enable build rpath
["build.rpath"] = {description = "Enable build rpath.", default = true, type = "boolean"},
-- Enable C++ modules for C++ building, even if no .mpp is involved in the compilation
["build.c++.modules"] = {description = "Enable C++ modules for C++ building.", type = "boolean"},
-- Enable std module
Expand Down Expand Up @@ -96,6 +98,8 @@ function policy.policies()
["windows.manifest.uac.ui"] = {description = "Enable windows manifest UAC.", type = "boolean"},
-- Automatically build before running
["run.autobuild"] = {description = "Automatically build before running.", type = "boolean"},
-- Enable install rpath
["install.rpath"] = {description = "Enable install rpath.", default = true, type = "boolean"},
-- Preprocessor configuration for ccache/distcc, we can disable linemarkers to speed up preprocess
["preprocessor.linemarkers"] = {description = "Enable linemarkers for preprocessor.", default = true, type = "boolean"},
-- Preprocessor configuration for ccache/distcc, we can disable it to avoid cache object file with __DATE__, __TIME__
Expand Down
63 changes: 50 additions & 13 deletions xmake/core/project/target.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1623,20 +1623,56 @@ function _instance:rundir()
return baseoption.get("workdir") or self:get("rundir") or path.directory(self:targetfile())
end

-- get install directory
function _instance:installdir()
-- get prefix directory
function _instance:prefixdir()
return self:get("prefixdir")
end

-- get the installed binary directory
function _instance:bindir()
local bindir = self:extraconf("prefixdir", self:prefixdir(), "bindir")
if bindir == nil then
bindir = "bin"
end
return self:installdir(bindir)
end

-- get the installed library directory
function _instance:libdir()
local libdir = self:extraconf("prefixdir", self:prefixdir(), "libdir")
if libdir == nil then
libdir = "lib"
end
return self:installdir(libdir)
end

-- get it from the cache
-- get the installed include directory
function _instance:includedir()
local includedir = self:extraconf("prefixdir", self:prefixdir(), "includedir")
if includedir == nil then
includedir = "include"
end
return self:installdir(includedir)
end

-- get install directory
function _instance:installdir(...)
opt = opt or {}
local installdir = baseoption.get("installdir")
if not installdir then

-- DESTDIR: be compatible with https://www.gnu.org/prep/standards/html_node/DESTDIR.html
installdir = self:get("installdir") or os.getenv("INSTALLDIR") or os.getenv("PREFIX") or os.getenv("DESTDIR") or platform.get("installdir")
if installdir then
installdir = installdir:trim()
end
end
return installdir
if installdir then
local prefixdir = self:prefixdir()
if prefixdir then
installdir = path.join(installdir, prefixdir)
end
return path.normalize(path.join(installdir, ...))
end
end

-- get package directory
Expand Down Expand Up @@ -2000,7 +2036,7 @@ end
-- get the header files
function _instance:headerfiles(outputdir, opt)
opt = opt or {}
local headerfiles = self:get("headerfiles")
local headerfiles = self:get("headerfiles", opt) or {}
-- add_headerfiles("src/*.h", {install = false})
-- @see https://github.com/xmake-io/xmake/issues/2577
if opt.installonly then
Expand All @@ -2016,13 +2052,12 @@ function _instance:headerfiles(outputdir, opt)
return
end

local headerdir = outputdir
if not headerdir then
if self:installdir() then
headerdir = path.join(self:installdir(), "include")
if not outputdir then
if self:includedir() then
outputdir = self:includedir()
end
end
return match_copyfiles(self, "headerfiles", headerdir, {copyfiles = headerfiles})
return match_copyfiles(self, "headerfiles", outputdir, {copyfiles = headerfiles})
end

-- get the configuration files
Expand All @@ -2036,8 +2071,9 @@ function _instance:configfiles(outputdir)
end

-- get the install files
function _instance:installfiles(outputdir)
return match_copyfiles(self, "installfiles", outputdir or self:installdir())
function _instance:installfiles(outputdir, opt)
local installfiles = self:get("installfiles", opt) or {}
return match_copyfiles(self, "installfiles", outputdir or self:installdir(), {copyfiles = installfiles})
end

-- get the extra files
Expand Down Expand Up @@ -2737,6 +2773,7 @@ function target.apis()
, "target.set_runargs"
, "target.set_exceptions"
, "target.set_encodings"
, "target.set_prefixdir"
-- target.add_xxx
, "target.add_deps"
, "target.add_rules"
Expand Down
Loading

0 comments on commit d4364ef

Please sign in to comment.