diff options
| author | ruki <[email protected]> | 2020-02-19 23:06:29 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-02-19 12:38:56 +0800 |
| commit | ed49fcb8e77087a12b01cae2bb7841a75a25b0fc (patch) | |
| tree | 25877850c5751989bf46251afc57c3495f7ea223 | |
| parent | e630b2edcccc8fd988f630959ac0cda5933251da (diff) | |
support cross-compilation for autotools
| -rw-r--r-- | xmake/actions/build/main.lua | 5 | ||||
| -rw-r--r-- | xmake/actions/clean/main.lua | 3 | ||||
| -rw-r--r-- | xmake/modules/package/tools/autoconf.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/private/action/trybuild/autotools.lua | 123 | ||||
| -rw-r--r-- | xmake/modules/private/action/trybuild/cmake.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/private/action/trybuild/meson.lua | 72 |
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 + + |
