summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-02-19 23:06:29 +0800
committerruki <[email protected]>2020-02-19 12:38:56 +0800
commited49fcb8e77087a12b01cae2bb7841a75a25b0fc (patch)
tree25877850c5751989bf46251afc57c3495f7ea223
parente630b2edcccc8fd988f630959ac0cda5933251da (diff)
support cross-compilation for autotools
-rw-r--r--xmake/actions/build/main.lua5
-rw-r--r--xmake/actions/clean/main.lua3
-rw-r--r--xmake/modules/package/tools/autoconf.lua4
-rw-r--r--xmake/modules/private/action/trybuild/autotools.lua123
-rw-r--r--xmake/modules/private/action/trybuild/cmake.lua4
-rw-r--r--xmake/modules/private/action/trybuild/meson.lua72
6 files changed, 206 insertions, 5 deletions
diff --git a/xmake/actions/build/main.lua b/xmake/actions/build/main.lua
index 2918bb95f..a38ebb7c1 100644
--- a/xmake/actions/build/main.lua
+++ b/xmake/actions/build/main.lua
@@ -24,6 +24,7 @@ import("core.base.task")
import("core.project.config")
import("core.project.project")
import("core.platform.platform")
+import("core.platform.environment")
import("build")
import("build_files")
import("cleaner")
@@ -54,7 +55,7 @@ function _try_build()
raise("unknown build tool: %s", trybuild)
end
else
- for _, name in ipairs({"msbuild", "xcodebuild", "cmake", "autotools", "make"}) do
+ for _, name in ipairs({"msbuild", "xcodebuild", "cmake", "autotools", "meson", "make"}) do
tool = import("private.action.trybuild." .. name, {anonymous = true})
configfile = tool.detect()
if configfile then
@@ -69,7 +70,9 @@ function _try_build()
if not trybuild then
task.run("config", {target = targetname, trybuild = trybuild_detected})
end
+ environment.enter("toolchains")
tool.build()
+ environment.leave("toolchains")
end
end
diff --git a/xmake/actions/clean/main.lua b/xmake/actions/clean/main.lua
index db2341ab6..f8dabc81a 100644
--- a/xmake/actions/clean/main.lua
+++ b/xmake/actions/clean/main.lua
@@ -26,6 +26,7 @@ import("core.project.config")
import("core.base.global")
import("core.project.project")
import("core.platform.platform")
+import("core.platform.environment")
import("private.action.clean.remove_files")
-- do clean target
@@ -225,7 +226,9 @@ function _try_clean()
-- try cleaning it
if configfile and tool and trybuild then
+ environment.enter("toolchains")
tool.clean()
+ environment.leave("toolchains")
end
end
diff --git a/xmake/modules/package/tools/autoconf.lua b/xmake/modules/package/tools/autoconf.lua
index a93bb6a80..3dbc7853a 100644
--- a/xmake/modules/package/tools/autoconf.lua
+++ b/xmake/modules/package/tools/autoconf.lua
@@ -29,7 +29,7 @@ function _get_configs(package, configs)
table.insert(configs, "--prefix=" .. package:installdir())
-- add host for cross-complation
- if not configs.host and not package:is_plat(os.host()) then
+ if not configs.host and not package:is_plat(os.subhost()) then
if package:is_plat("iphoneos") then
local triples =
{
@@ -71,7 +71,7 @@ end
-- get the build environments
function buildenvs(package)
local envs = {}
- if package:is_plat(os.host()) then
+ if package:is_plat(os.subhost()) then
local cflags = table.join(table.wrap(package:config("cxflags")), package:config("cflags"))
local cxxflags = table.join(table.wrap(package:config("cxflags")), package:config("cxxflags"))
envs.CFLAGS = table.concat(cflags, ' ')
diff --git a/xmake/modules/private/action/trybuild/autotools.lua b/xmake/modules/private/action/trybuild/autotools.lua
index 505054404..cbb36a166 100644
--- a/xmake/modules/private/action/trybuild/autotools.lua
+++ b/xmake/modules/private/action/trybuild/autotools.lua
@@ -21,6 +21,7 @@
-- imports
import("core.base.option")
import("core.project.config")
+import("core.platform.platform")
import("lib.detect.find_file")
-- get build directory
@@ -33,6 +34,115 @@ function _get_artifacts_dir()
return path.absolute(path.join(_get_buildir(), "artifacts"))
end
+-- get the build environment
+function _get_buildenv(key)
+ local value = config.get(key)
+ if value == nil then
+ value = platform.get(key, config.plat())
+ end
+ if value == nil then
+ value = platform.tool(key, config.plat())
+ end
+ return value
+end
+
+-- get the build environments
+function _get_buildenvs()
+ local envs = {}
+ if is_plat(os.subhost()) then
+ local cflags = table.join(table.wrap(config.get("cxflags")), config.get("cflags"))
+ local cxxflags = table.join(table.wrap(config.get("cxflags")), config.get("cxxflags"))
+ envs.CFLAGS = table.concat(cflags, ' ')
+ envs.CXXFLAGS = table.concat(cxxflags, ' ')
+ envs.ASFLAGS = table.concat(table.wrap(config.get("asflags")), ' ')
+ else
+ local cflags = table.join(table.wrap(_get_buildenv("cxflags")), _get_buildenv("cflags"))
+ local cxxflags = table.join(table.wrap(_get_buildenv("cxflags")), _get_buildenv("cxxflags"))
+ envs.CC = _get_buildenv("cc")
+ envs.AS = _get_buildenv("as")
+ envs.AR = _get_buildenv("ar")
+ envs.LD = _get_buildenv("ld")
+ envs.LDSHARED = _get_buildenv("sh")
+ envs.CPP = _get_buildenv("cpp")
+ envs.RANLIB = _get_buildenv("ranlib")
+ envs.CFLAGS = table.concat(cflags, ' ')
+ envs.CXXFLAGS = table.concat(cxxflags, ' ')
+ envs.ASFLAGS = table.concat(table.wrap(_get_buildenv("asflags")), ' ')
+ envs.ARFLAGS = table.concat(table.wrap(_get_buildenv("arflags")), ' ')
+ envs.LDFLAGS = table.concat(table.wrap(_get_buildenv("ldflags")), ' ')
+ envs.SHFLAGS = table.concat(table.wrap(_get_buildenv("shflags")), ' ')
+ if #envs.ARFLAGS == 0 then
+ if envs.AR and envs.AR:endswith("ar") then
+ envs.ARFLAGS = "-cr"
+ end
+ end
+ if is_plat("mingw") then
+ -- fix linker error, @see https://github.com/xmake-io/xmake/issues/574
+ -- libtool: line 1855: lib: command not found
+ envs.ARFLAGS = nil
+ local ld = envs.LD
+ if ld then
+ if ld:endswith("x86_64-w64-mingw32-g++") then
+ envs.LD = path.join(path.directory(ld), "x86_64-w64-mingw32-ld")
+ elseif ld:endswith("i686-w64-mingw32-g++") then
+ envs.LD = path.join(path.directory(ld), "i686-w64-mingw32-ld")
+ end
+ end
+ end
+ end
+ if option.get("verbose") then
+ print(envs)
+ end
+ return envs
+end
+
+-- get configs
+function _get_configs(artifacts_dir)
+
+ -- add prefix
+ local configs = {}
+ table.insert(configs, "--prefix=" .. artifacts_dir)
+
+ -- add host for cross-complation
+ if not is_plat(os.subhost()) then
+ if is_plat("iphoneos") then
+ local triples =
+ {
+ arm64 = "aarch64-apple-darwin",
+ arm64e = "aarch64-apple-darwin",
+ armv7 = "armv7-apple-darwin",
+ armv7s = "armv7s-apple-darwin",
+ i386 = "i386-apple-darwin",
+ x86_64 = "x86_64-apple-darwin"
+ }
+ table.insert(configs, "--host=" .. (triples[config.arch()] or triples.arm64))
+ elseif is_plat("android") then
+ -- @see https://developer.android.com/ndk/guides/other_build_systems#autoconf
+ local triples =
+ {
+ ["armv5te"] = "arm-linux-androideabi",
+ ["armv7-a"] = "arm-linux-androideabi",
+ ["arm64-v8a"] = "aarch64-linux-android",
+ i386 = "i686-linux-android",
+ x86_64 = "x86_64-linux-android",
+ mips = "mips-linux-android",
+ mips64 = "mips64-linux-android"
+ }
+ table.insert(configs, "--host=" .. (triples[config.arch()] or triples["armv7-a"]))
+ elseif is_plat("mingw") then
+ local triples =
+ {
+ i386 = "i686-w64-mingw32",
+ x86_64 = "x86_64-w64-mingw32"
+ }
+ table.insert(configs, "--host=" .. (triples[config.arch()] or triples.i386))
+ else
+ raise("autotools: unknown platform(%s)!", config.plat())
+ end
+ end
+ return configs
+end
+
-- detect build-system and configuration file
function detect()
return find_file("configure", os.curdir()) or find_file("configure.ac", os.curdir())
@@ -70,7 +180,18 @@ function build()
-- do configure
if not find_file("[mM]akefile", os.curdir()) then
- os.execv("./configure", "--prefix=" .. artifacts_dir)
+ local argv = {}
+ for name, value in pairs(_get_configs(artifacts_dir)) do
+ value = tostring(value):trim()
+ if value ~= "" then
+ if type(name) == "number" then
+ table.insert(argv, value)
+ else
+ table.insert(argv, "--" .. name .. "=" .. value)
+ end
+ end
+ end
+ os.execv("./configure", argv, {envs = _get_buildenvs()})
end
-- do build
diff --git a/xmake/modules/private/action/trybuild/cmake.lua b/xmake/modules/private/action/trybuild/cmake.lua
index 6308df5d2..287b8aefc 100644
--- a/xmake/modules/private/action/trybuild/cmake.lua
+++ b/xmake/modules/private/action/trybuild/cmake.lua
@@ -22,6 +22,7 @@
import("core.base.option")
import("core.project.config")
import("lib.detect.find_file")
+import("lib.detect.find_tool")
-- get build directory
function _get_buildir()
@@ -66,6 +67,7 @@ function build()
os.cd(_get_buildir())
-- generate makefile
+ local cmake = assert(find_tool("cmake"), "cmake not found!")
local configfile = find_file("[mM]akefile", os.curdir()) or (is_plat("windows") and find_file("*.sln", os.curdir()))
if not configfile then
local argv = {"-DCMAKE_INSTALL_PREFIX=" .. artifacts_dir, "-DDCMAKE_INSTALL_LIBDIR=" .. path.join(artifacts_dir, "lib")}
@@ -74,7 +76,7 @@ function build()
table.insert(argv, "x64")
end
table.insert(argv, '..')
- os.execv("cmake", argv)
+ os.execv(cmake.program, argv)
end
-- do build
diff --git a/xmake/modules/private/action/trybuild/meson.lua b/xmake/modules/private/action/trybuild/meson.lua
new file mode 100644
index 000000000..17982e190
--- /dev/null
+++ b/xmake/modules/private/action/trybuild/meson.lua
@@ -0,0 +1,72 @@
+--!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-2020, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file meson.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.project.config")
+import("lib.detect.find_file")
+import("lib.detect.find_tool")
+
+-- get build directory
+function _get_buildir()
+ return config.buildir() or "build"
+end
+
+-- get artifacts directory
+function _get_artifacts_dir()
+ return path.absolute(path.join(_get_buildir(), "artifacts"))
+end
+
+-- detect build-system and configuration file
+function detect()
+ return find_file("meson.build", os.curdir())
+end
+
+-- do clean
+function clean()
+ local buildir = _get_buildir()
+ if os.isdir(buildir) then
+ end
+end
+
+-- do build
+function build()
+
+ -- get artifacts directory
+ local artifacts_dir = _get_artifacts_dir()
+ if not os.isdir(artifacts_dir) then
+ os.mkdir(artifacts_dir)
+ end
+ os.cd(_get_buildir())
+
+ -- generate makefile
+ local meson = assert(find_tool("meson"), "meson not found!")
+ local configfile = nil
+ if not configfile then
+ local argv = {"--prefix=" .. artifacts_dir}
+ table.insert(argv, _get_buildir())
+ os.execv("meson", argv)
+ end
+
+ cprint("output to ${bright}%s", artifacts_dir)
+ cprint("${bright}build ok!")
+end
+
+