From cdcf953259aee5e7e1a06855ddbedbaabf585bc9 Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 14 Jan 2016 09:19:14 +0800 Subject: rename script directory to core --- core/src/xmake/machine.c | 2 +- xmake/core/_xmake_main.lua | 50 + xmake/core/action/_build.lua | 120 ++ xmake/core/action/_clean.lua | 106 ++ xmake/core/action/_config.lua | 215 +++ xmake/core/action/_create.lua | 173 +++ xmake/core/action/_debug.lua | 89 ++ xmake/core/action/_global.lua | 104 ++ xmake/core/action/_install.lua | 224 +++ xmake/core/action/_lua.lua | 168 +++ xmake/core/action/_man.lua | 89 ++ xmake/core/action/_package.lua | 365 +++++ xmake/core/action/_run.lua | 179 +++ xmake/core/action/_uninstall.lua | 160 +++ xmake/core/action/action.lua | 190 +++ xmake/core/base/clean.lua | 192 +++ xmake/core/base/compiler.lua | 574 ++++++++ xmake/core/base/config.lua | 395 ++++++ xmake/core/base/global.lua | 246 ++++ xmake/core/base/install.lua | 143 ++ xmake/core/base/io.lua | 324 +++++ xmake/core/base/linker.lua | 386 +++++ xmake/core/base/main.lua | 179 +++ xmake/core/base/makefile.lua | 417 ++++++ xmake/core/base/option.lua | 650 +++++++++ xmake/core/base/os.lua | 237 ++++ xmake/core/base/package.lua | 314 +++++ xmake/core/base/path.lua | 72 + xmake/core/base/project.lua | 1469 ++++++++++++++++++++ xmake/core/base/rule.lua | 300 ++++ xmake/core/base/string.lua | 115 ++ xmake/core/base/table.lua | 99 ++ xmake/core/base/template.lua | 77 + xmake/core/base/uninstall.lua | 104 ++ xmake/core/base/utils.lua | 258 ++++ xmake/core/module/os.lua | 46 + xmake/core/module/path.lua | 25 + xmake/core/module/project.lua | 73 + xmake/core/module/string.lua | 24 + xmake/core/module/utils.lua | 24 + xmake/core/platform/android/android.lua | 120 ++ xmake/core/platform/android/prober.lua | 269 ++++ xmake/core/platform/iphoneos/iphoneos.lua | 141 ++ xmake/core/platform/iphoneos/package.lua | 76 + xmake/core/platform/iphoneos/prober.lua | 310 +++++ .../platform/iphonesimulator/iphonesimulator.lua | 138 ++ xmake/core/platform/iphonesimulator/prober.lua | 308 ++++ xmake/core/platform/linux/install.lua | 182 +++ xmake/core/platform/linux/linux.lua | 103 ++ xmake/core/platform/linux/prober.lua | 198 +++ xmake/core/platform/linux/uninstall.lua | 134 ++ xmake/core/platform/macosx/install.lua | 182 +++ xmake/core/platform/macosx/macosx.lua | 140 ++ xmake/core/platform/macosx/prober.lua | 307 ++++ xmake/core/platform/macosx/uninstall.lua | 134 ++ xmake/core/platform/mingw/mingw.lua | 93 ++ xmake/core/platform/mingw/prober.lua | 207 +++ xmake/core/platform/platform.lua | 385 +++++ xmake/core/platform/watchos/package.lua | 76 + xmake/core/platform/watchos/prober.lua | 310 +++++ xmake/core/platform/watchos/watchos.lua | 141 ++ xmake/core/platform/watchsimulator/prober.lua | 308 ++++ .../platform/watchsimulator/watchsimulator.lua | 138 ++ xmake/core/platform/windows/prober.lua | 300 ++++ xmake/core/platform/windows/tools/cl.lua | 139 ++ xmake/core/platform/windows/tools/lib.lua | 138 ++ xmake/core/platform/windows/tools/link.lua | 128 ++ xmake/core/platform/windows/tools/ml.lua | 132 ++ xmake/core/platform/windows/tools/nmake.lua | 74 + xmake/core/platform/windows/windows.lua | 144 ++ xmake/core/tools/ar.lua | 114 ++ xmake/core/tools/cat.lua | 43 + xmake/core/tools/clang++.lua | 38 + xmake/core/tools/clang.lua | 38 + xmake/core/tools/cp.lua | 44 + xmake/core/tools/dispatcher.lua | 80 ++ xmake/core/tools/echo.lua | 44 + xmake/core/tools/g++.lua | 38 + xmake/core/tools/gas-preprocessor.pl | 1025 ++++++++++++++ xmake/core/tools/gcc.lua | 192 +++ xmake/core/tools/make.lua | 82 ++ xmake/core/tools/mkdir.lua | 46 + xmake/core/tools/mv.lua | 43 + xmake/core/tools/rm.lua | 46 + xmake/core/tools/rmdir.lua | 46 + xmake/core/tools/swiftc.lua | 117 ++ xmake/core/tools/tools.lua | 222 +++ xmake/core/tools/verbose.lua | 47 + xmake/scripts/_xmake_main.lua | 48 - xmake/scripts/action/_build.lua | 120 -- xmake/scripts/action/_clean.lua | 106 -- xmake/scripts/action/_config.lua | 215 --- xmake/scripts/action/_create.lua | 173 --- xmake/scripts/action/_debug.lua | 89 -- xmake/scripts/action/_global.lua | 104 -- xmake/scripts/action/_install.lua | 224 --- xmake/scripts/action/_lua.lua | 168 --- xmake/scripts/action/_man.lua | 89 -- xmake/scripts/action/_package.lua | 365 ----- xmake/scripts/action/_run.lua | 179 --- xmake/scripts/action/_uninstall.lua | 160 --- xmake/scripts/action/action.lua | 190 --- xmake/scripts/base/clean.lua | 192 --- xmake/scripts/base/compiler.lua | 574 -------- xmake/scripts/base/config.lua | 395 ------ xmake/scripts/base/global.lua | 246 ---- xmake/scripts/base/install.lua | 143 -- xmake/scripts/base/io.lua | 324 ----- xmake/scripts/base/linker.lua | 386 ----- xmake/scripts/base/main.lua | 179 --- xmake/scripts/base/makefile.lua | 417 ------ xmake/scripts/base/option.lua | 650 --------- xmake/scripts/base/os.lua | 237 ---- xmake/scripts/base/package.lua | 314 ----- xmake/scripts/base/path.lua | 72 - xmake/scripts/base/project.lua | 1469 -------------------- xmake/scripts/base/rule.lua | 300 ---- xmake/scripts/base/string.lua | 115 -- xmake/scripts/base/table.lua | 99 -- xmake/scripts/base/template.lua | 77 - xmake/scripts/base/uninstall.lua | 104 -- xmake/scripts/base/utils.lua | 258 ---- xmake/scripts/module/os.lua | 46 - xmake/scripts/module/path.lua | 25 - xmake/scripts/module/project.lua | 73 - xmake/scripts/module/string.lua | 24 - xmake/scripts/module/utils.lua | 24 - xmake/scripts/platform/android/android.lua | 120 -- xmake/scripts/platform/android/prober.lua | 269 ---- xmake/scripts/platform/iphoneos/iphoneos.lua | 141 -- xmake/scripts/platform/iphoneos/package.lua | 76 - xmake/scripts/platform/iphoneos/prober.lua | 310 ----- .../platform/iphonesimulator/iphonesimulator.lua | 138 -- xmake/scripts/platform/iphonesimulator/prober.lua | 308 ---- xmake/scripts/platform/linux/install.lua | 182 --- xmake/scripts/platform/linux/linux.lua | 103 -- xmake/scripts/platform/linux/prober.lua | 198 --- xmake/scripts/platform/linux/uninstall.lua | 134 -- xmake/scripts/platform/macosx/install.lua | 182 --- xmake/scripts/platform/macosx/macosx.lua | 140 -- xmake/scripts/platform/macosx/prober.lua | 307 ---- xmake/scripts/platform/macosx/uninstall.lua | 134 -- xmake/scripts/platform/mingw/mingw.lua | 93 -- xmake/scripts/platform/mingw/prober.lua | 207 --- xmake/scripts/platform/platform.lua | 385 ----- xmake/scripts/platform/watchos/package.lua | 76 - xmake/scripts/platform/watchos/prober.lua | 310 ----- xmake/scripts/platform/watchos/watchos.lua | 141 -- xmake/scripts/platform/watchsimulator/prober.lua | 308 ---- .../platform/watchsimulator/watchsimulator.lua | 138 -- xmake/scripts/platform/windows/prober.lua | 300 ---- xmake/scripts/platform/windows/tools/cl.lua | 139 -- xmake/scripts/platform/windows/tools/lib.lua | 138 -- xmake/scripts/platform/windows/tools/link.lua | 128 -- xmake/scripts/platform/windows/tools/ml.lua | 132 -- xmake/scripts/platform/windows/tools/nmake.lua | 74 - xmake/scripts/platform/windows/windows.lua | 144 -- xmake/scripts/tools/ar.lua | 114 -- xmake/scripts/tools/cat.lua | 43 - xmake/scripts/tools/clang++.lua | 38 - xmake/scripts/tools/clang.lua | 38 - xmake/scripts/tools/cp.lua | 44 - xmake/scripts/tools/dispatcher.lua | 80 -- xmake/scripts/tools/echo.lua | 44 - xmake/scripts/tools/g++.lua | 38 - xmake/scripts/tools/gas-preprocessor.pl | 1025 -------------- xmake/scripts/tools/gcc.lua | 192 --- xmake/scripts/tools/make.lua | 82 -- xmake/scripts/tools/mkdir.lua | 46 - xmake/scripts/tools/mv.lua | 43 - xmake/scripts/tools/rm.lua | 46 - xmake/scripts/tools/rmdir.lua | 46 - xmake/scripts/tools/swiftc.lua | 117 -- xmake/scripts/tools/tools.lua | 222 --- xmake/scripts/tools/verbose.lua | 47 - 175 files changed, 16736 insertions(+), 16734 deletions(-) create mode 100644 xmake/core/_xmake_main.lua create mode 100644 xmake/core/action/_build.lua create mode 100644 xmake/core/action/_clean.lua create mode 100644 xmake/core/action/_config.lua create mode 100644 xmake/core/action/_create.lua create mode 100644 xmake/core/action/_debug.lua create mode 100644 xmake/core/action/_global.lua create mode 100644 xmake/core/action/_install.lua create mode 100644 xmake/core/action/_lua.lua create mode 100644 xmake/core/action/_man.lua create mode 100644 xmake/core/action/_package.lua create mode 100644 xmake/core/action/_run.lua create mode 100644 xmake/core/action/_uninstall.lua create mode 100644 xmake/core/action/action.lua create mode 100644 xmake/core/base/clean.lua create mode 100644 xmake/core/base/compiler.lua create mode 100644 xmake/core/base/config.lua create mode 100644 xmake/core/base/global.lua create mode 100644 xmake/core/base/install.lua create mode 100644 xmake/core/base/io.lua create mode 100644 xmake/core/base/linker.lua create mode 100644 xmake/core/base/main.lua create mode 100644 xmake/core/base/makefile.lua create mode 100644 xmake/core/base/option.lua create mode 100644 xmake/core/base/os.lua create mode 100644 xmake/core/base/package.lua create mode 100644 xmake/core/base/path.lua create mode 100644 xmake/core/base/project.lua create mode 100644 xmake/core/base/rule.lua create mode 100644 xmake/core/base/string.lua create mode 100644 xmake/core/base/table.lua create mode 100644 xmake/core/base/template.lua create mode 100644 xmake/core/base/uninstall.lua create mode 100644 xmake/core/base/utils.lua create mode 100644 xmake/core/module/os.lua create mode 100644 xmake/core/module/path.lua create mode 100644 xmake/core/module/project.lua create mode 100644 xmake/core/module/string.lua create mode 100644 xmake/core/module/utils.lua create mode 100644 xmake/core/platform/android/android.lua create mode 100644 xmake/core/platform/android/prober.lua create mode 100644 xmake/core/platform/iphoneos/iphoneos.lua create mode 100644 xmake/core/platform/iphoneos/package.lua create mode 100644 xmake/core/platform/iphoneos/prober.lua create mode 100644 xmake/core/platform/iphonesimulator/iphonesimulator.lua create mode 100644 xmake/core/platform/iphonesimulator/prober.lua create mode 100644 xmake/core/platform/linux/install.lua create mode 100644 xmake/core/platform/linux/linux.lua create mode 100644 xmake/core/platform/linux/prober.lua create mode 100644 xmake/core/platform/linux/uninstall.lua create mode 100644 xmake/core/platform/macosx/install.lua create mode 100644 xmake/core/platform/macosx/macosx.lua create mode 100644 xmake/core/platform/macosx/prober.lua create mode 100644 xmake/core/platform/macosx/uninstall.lua create mode 100644 xmake/core/platform/mingw/mingw.lua create mode 100644 xmake/core/platform/mingw/prober.lua create mode 100644 xmake/core/platform/platform.lua create mode 100644 xmake/core/platform/watchos/package.lua create mode 100644 xmake/core/platform/watchos/prober.lua create mode 100644 xmake/core/platform/watchos/watchos.lua create mode 100644 xmake/core/platform/watchsimulator/prober.lua create mode 100644 xmake/core/platform/watchsimulator/watchsimulator.lua create mode 100644 xmake/core/platform/windows/prober.lua create mode 100644 xmake/core/platform/windows/tools/cl.lua create mode 100644 xmake/core/platform/windows/tools/lib.lua create mode 100644 xmake/core/platform/windows/tools/link.lua create mode 100644 xmake/core/platform/windows/tools/ml.lua create mode 100644 xmake/core/platform/windows/tools/nmake.lua create mode 100644 xmake/core/platform/windows/windows.lua create mode 100644 xmake/core/tools/ar.lua create mode 100644 xmake/core/tools/cat.lua create mode 100644 xmake/core/tools/clang++.lua create mode 100644 xmake/core/tools/clang.lua create mode 100644 xmake/core/tools/cp.lua create mode 100644 xmake/core/tools/dispatcher.lua create mode 100644 xmake/core/tools/echo.lua create mode 100644 xmake/core/tools/g++.lua create mode 100755 xmake/core/tools/gas-preprocessor.pl create mode 100644 xmake/core/tools/gcc.lua create mode 100644 xmake/core/tools/make.lua create mode 100644 xmake/core/tools/mkdir.lua create mode 100644 xmake/core/tools/mv.lua create mode 100644 xmake/core/tools/rm.lua create mode 100644 xmake/core/tools/rmdir.lua create mode 100644 xmake/core/tools/swiftc.lua create mode 100644 xmake/core/tools/tools.lua create mode 100644 xmake/core/tools/verbose.lua delete mode 100644 xmake/scripts/_xmake_main.lua delete mode 100644 xmake/scripts/action/_build.lua delete mode 100644 xmake/scripts/action/_clean.lua delete mode 100644 xmake/scripts/action/_config.lua delete mode 100644 xmake/scripts/action/_create.lua delete mode 100644 xmake/scripts/action/_debug.lua delete mode 100644 xmake/scripts/action/_global.lua delete mode 100644 xmake/scripts/action/_install.lua delete mode 100644 xmake/scripts/action/_lua.lua delete mode 100644 xmake/scripts/action/_man.lua delete mode 100644 xmake/scripts/action/_package.lua delete mode 100644 xmake/scripts/action/_run.lua delete mode 100644 xmake/scripts/action/_uninstall.lua delete mode 100644 xmake/scripts/action/action.lua delete mode 100644 xmake/scripts/base/clean.lua delete mode 100644 xmake/scripts/base/compiler.lua delete mode 100644 xmake/scripts/base/config.lua delete mode 100644 xmake/scripts/base/global.lua delete mode 100644 xmake/scripts/base/install.lua delete mode 100644 xmake/scripts/base/io.lua delete mode 100644 xmake/scripts/base/linker.lua delete mode 100644 xmake/scripts/base/main.lua delete mode 100644 xmake/scripts/base/makefile.lua delete mode 100644 xmake/scripts/base/option.lua delete mode 100644 xmake/scripts/base/os.lua delete mode 100644 xmake/scripts/base/package.lua delete mode 100644 xmake/scripts/base/path.lua delete mode 100644 xmake/scripts/base/project.lua delete mode 100644 xmake/scripts/base/rule.lua delete mode 100644 xmake/scripts/base/string.lua delete mode 100644 xmake/scripts/base/table.lua delete mode 100644 xmake/scripts/base/template.lua delete mode 100644 xmake/scripts/base/uninstall.lua delete mode 100644 xmake/scripts/base/utils.lua delete mode 100644 xmake/scripts/module/os.lua delete mode 100644 xmake/scripts/module/path.lua delete mode 100644 xmake/scripts/module/project.lua delete mode 100644 xmake/scripts/module/string.lua delete mode 100644 xmake/scripts/module/utils.lua delete mode 100644 xmake/scripts/platform/android/android.lua delete mode 100644 xmake/scripts/platform/android/prober.lua delete mode 100644 xmake/scripts/platform/iphoneos/iphoneos.lua delete mode 100644 xmake/scripts/platform/iphoneos/package.lua delete mode 100644 xmake/scripts/platform/iphoneos/prober.lua delete mode 100644 xmake/scripts/platform/iphonesimulator/iphonesimulator.lua delete mode 100644 xmake/scripts/platform/iphonesimulator/prober.lua delete mode 100644 xmake/scripts/platform/linux/install.lua delete mode 100644 xmake/scripts/platform/linux/linux.lua delete mode 100644 xmake/scripts/platform/linux/prober.lua delete mode 100644 xmake/scripts/platform/linux/uninstall.lua delete mode 100644 xmake/scripts/platform/macosx/install.lua delete mode 100644 xmake/scripts/platform/macosx/macosx.lua delete mode 100644 xmake/scripts/platform/macosx/prober.lua delete mode 100644 xmake/scripts/platform/macosx/uninstall.lua delete mode 100644 xmake/scripts/platform/mingw/mingw.lua delete mode 100644 xmake/scripts/platform/mingw/prober.lua delete mode 100644 xmake/scripts/platform/platform.lua delete mode 100644 xmake/scripts/platform/watchos/package.lua delete mode 100644 xmake/scripts/platform/watchos/prober.lua delete mode 100644 xmake/scripts/platform/watchos/watchos.lua delete mode 100644 xmake/scripts/platform/watchsimulator/prober.lua delete mode 100644 xmake/scripts/platform/watchsimulator/watchsimulator.lua delete mode 100644 xmake/scripts/platform/windows/prober.lua delete mode 100644 xmake/scripts/platform/windows/tools/cl.lua delete mode 100644 xmake/scripts/platform/windows/tools/lib.lua delete mode 100644 xmake/scripts/platform/windows/tools/link.lua delete mode 100644 xmake/scripts/platform/windows/tools/ml.lua delete mode 100644 xmake/scripts/platform/windows/tools/nmake.lua delete mode 100644 xmake/scripts/platform/windows/windows.lua delete mode 100644 xmake/scripts/tools/ar.lua delete mode 100644 xmake/scripts/tools/cat.lua delete mode 100644 xmake/scripts/tools/clang++.lua delete mode 100644 xmake/scripts/tools/clang.lua delete mode 100644 xmake/scripts/tools/cp.lua delete mode 100644 xmake/scripts/tools/dispatcher.lua delete mode 100644 xmake/scripts/tools/echo.lua delete mode 100644 xmake/scripts/tools/g++.lua delete mode 100755 xmake/scripts/tools/gas-preprocessor.pl delete mode 100644 xmake/scripts/tools/gcc.lua delete mode 100644 xmake/scripts/tools/make.lua delete mode 100644 xmake/scripts/tools/mkdir.lua delete mode 100644 xmake/scripts/tools/mv.lua delete mode 100644 xmake/scripts/tools/rm.lua delete mode 100644 xmake/scripts/tools/rmdir.lua delete mode 100644 xmake/scripts/tools/swiftc.lua delete mode 100644 xmake/scripts/tools/tools.lua delete mode 100644 xmake/scripts/tools/verbose.lua diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c index ead646ea9..6b61be5ae 100755 --- a/core/src/xmake/machine.c +++ b/core/src/xmake/machine.c @@ -350,7 +350,7 @@ tb_int_t xm_machine_main(xm_machine_ref_t machine, tb_int_t argc, tb_char_t** ar if (!xm_machine_main_get_program_directory(impl, path, sizeof(path))) return -1; // append the main script path - tb_strcat(path, "/scripts/_xmake_main.lua"); + tb_strcat(path, "/core/_xmake_main.lua"); // exists this script? if (!tb_file_info(path, tb_null)) diff --git a/xmake/core/_xmake_main.lua b/xmake/core/_xmake_main.lua new file mode 100644 index 000000000..49fbb0105 --- /dev/null +++ b/xmake/core/_xmake_main.lua @@ -0,0 +1,50 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _xmake_main.lua +-- + +-- init namespace: xmake +xmake = xmake or {} +xmake._ARGV = _ARGV +xmake._HOST = _HOST +xmake._ARCH = _ARCH +xmake._NULDEV = _NULDEV +xmake._VERSION = _VERSION +xmake._PROGRAM_DIR = _PROGRAM_DIR +xmake._PROJECT_DIR = _PROJECT_DIR +xmake._CORE_DIR = _PROGRAM_DIR .. "/core" +xmake._PACKAGES_DIR = _PROGRAM_DIR .. "/packages" +xmake._TEMPLATES_DIR = _PROGRAM_DIR .. "/templates" +xmake._PROJECT_FILE = "xmake.lua" +xmake._OPTIONS = {} +xmake._CONFIGS = {} + +-- init package path +package.path = xmake._CORE_DIR .. "/?.lua;" .. package.path + +-- load modules +local main = require("base/main") + +-- the main function +function _xmake_main() + + -- done main + return main.done() +end diff --git a/xmake/core/action/_build.lua b/xmake/core/action/_build.lua new file mode 100644 index 000000000..bf660eab5 --- /dev/null +++ b/xmake/core/action/_build.lua @@ -0,0 +1,120 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _build.lua +-- + +-- define module: _build +local _build = _build or {} + +-- load modules +local rule = require("base/rule") +local utils = require("base/utils") +local clean = require("base/clean") +local config = require("base/config") +local project = require("base/project") +local makefile = require("base/makefile") + +-- need access to the given file? +function _build.need(name) + + -- check + assert(name) + + -- the accessors + local accessors = { config = true, global = true, project = true, platform = true } + + -- need it? + return accessors[name] +end + +-- done +function _build.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- the target name + local target_name = options.target + + -- check target + if not project.checktarget(target_name) then + return false + end + + -- rebuild it? + if options.rebuild or config.get("__rebuild") then + clean.remove(target_name, "build") + -- update it? + elseif options.update then + clean.remove(target_name, "targets") + end + + -- clear rebuild mark and save configure to file + if config.get("__rebuild") then + + -- clear it + config.set("__rebuild", nil) + + -- save the configure + if not config.save() then + -- error + utils.error("update configure failed!") + end + end + + -- check makefile + if not os.isfile(rule.makefile()) then + + -- make the configure file for the given target + if not project.makeconf(options.target) then + -- error + utils.error("make configure failed!") + return false + end + + -- make makefile + if not makefile.make() then + -- error + utils.error("make makefile failed!") + return false + end + end + + -- build target for makefile + if not makefile.build(target_name) then + -- error + print("") + if options.verbose then + io.cat(rule.logfile()) + else + io.tail(rule.logfile(), 32) + end + utils.error("build target: %s failed!\n", target_name) + return false + end + + -- ok + print("build ok!") + return true +end + +-- return module: _build +return _build diff --git a/xmake/core/action/_clean.lua b/xmake/core/action/_clean.lua new file mode 100644 index 000000000..677ff2470 --- /dev/null +++ b/xmake/core/action/_clean.lua @@ -0,0 +1,106 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _clean.lua +-- + +-- define module: _clean +local _clean = _clean or {} + +-- load modules +local clean = require("base/clean") +local config = require("base/config") +local project = require("base/project") +local utils = require("base/utils") +local platform = require("platform/platform") + +-- need access to the given file? +function _clean.need(name) + + -- check + assert(name) + + -- the accessors + local accessors = { global = true, config = true, project = true, platform = true } + + -- need it? + return accessors[name] +end + +-- done +function _clean.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- check target + if not project.checktarget(options.target) then + return false + end + + -- clean the current target + if not clean.remove(options.target, utils.ifelse(options.all, "all", "build")) then + return false + end + + -- trace + print("clean ok!") + + -- ok + return true +end + +-- the menu +function _clean.menu() + + return { + -- xmake c + shortname = 'c' + + -- usage + , usage = "xmake clean|c [options] [target]" + + -- description + , description = "Remove all binary and temporary files." + + -- options + , options = + { + {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + , {} + , {'a', "all", "k", nil, "Clean all auto-generated files by xmake." } + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", "all", "Clean for the given target." } + } + } +end + +-- return module: _clean +return _clean diff --git a/xmake/core/action/_config.lua b/xmake/core/action/_config.lua new file mode 100644 index 000000000..a883b0499 --- /dev/null +++ b/xmake/core/action/_config.lua @@ -0,0 +1,215 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _config.lua +-- + +-- define module: _config +local _config = _config or {} + +-- load modules +local utils = require("base/utils") +local config = require("base/config") +local project = require("base/project") +local makefile = require("base/makefile") +local platform = require("platform/platform") + +-- need access to the given file? +function _config.need(name) + + -- check + assert(name) + + -- the accessors + local accessors = { config = true, global = true, project = true, platform = true } + + -- need it? + return accessors[name] +end + +-- done +function _config.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- check target + if not project.checktarget(options.target) then + return false + end + + -- trace + print("configure ...") + + -- save the configure + if not config.save() then + -- error + utils.error("save configure failed!") + return false + end + + -- make the configure file for the given target + if not project.makeconf(options.target) then + -- error + utils.error("make configure failed!") + return false + end + + -- make makefile + if not makefile.make() then + -- error + utils.error("make makefile failed!") + return false + end + + -- dump configure + config.dump() + + -- trace + print("configure ok!") + + -- ok + return true +end + +-- the menu +function _config.menu() + + return { + -- xmake f + shortname = 'f' + + -- usage + , usage = "xmake config|f [options] [target]" + + -- description + , description = "Configure the project." + + -- options + , options = + { + {'c', "clean", "k", nil, "Clean the cached configure and configure all again." } + + , {} + , {'p', "plat", "kv", xmake._HOST, "Compile for the given platform." + , function () + local descriptions = {} + local plats = platform.plats() + if plats then + for i, plat in ipairs(plats) do + descriptions[i] = " - " .. plat + end + end + return descriptions + end } + , {'a', "arch", "kv", "auto", "Compile for the given architecture." + , function () + local descriptions = {} + local plats = platform.plats() + if plats then + for i, plat in ipairs(plats) do + descriptions[i] = " - " .. plat .. ":" + local archs = platform.archs(plat) + if archs then + for _, arch in ipairs(archs) do + descriptions[i] = descriptions[i] .. " " .. arch + end + end + end + end + return descriptions + end } + , {'m', "mode", "kv", "release", "Compile for the given mode." + , " - debug" + , " - release" + , " - profile" } + , {'k', "kind", "kv", "static", "Compile for the given target kind." + , " - static" + , " - shared" + , " - binary" } + , {nil, "host", "kv", xmake._HOST, "The current host environment." } + + -- the options for project + , function () return project.menu() end + + , {} + , {nil, "make", "kv", "auto", "Set the make path." } + , {nil, "ccache", "kv", "auto", "Enable or disable the c/c++ compiler cache." } + + , {} + , {nil, "cross", "kv", nil, "The cross toolchains prefix" + , ".e.g" + , " - i386-mingw32-" + , " - arm-linux-androideabi-" } + , {nil, "toolchains", "kv", nil, "The cross toolchains directory" } + + , {} + , {nil, "cc", "kv", nil, "The C Compiler" } + , {nil, "cxx", "kv", nil, "The C++ Compiler" } + , {nil, "cflags", "kv", nil, "The C Compiler Flags" } + , {nil, "cxflags", "kv", nil, "The C/C++ compiler Flags" } + , {nil, "cxxflags", "kv", nil, "The C++ Compiler Flags" } + + , {} + , {nil, "as", "kv", nil, "The Assembler" } + , {nil, "asflags", "kv", nil, "The Assembler Flags" } + + , {} + , {nil, "sc", "kv", nil, "The Swift Compiler" } + , {nil, "scflags", "kv", nil, "The Swift Compiler Flags" } + + , {} + , {nil, "ld", "kv", nil, "The Linker" } + , {nil, "ldflags", "kv", nil, "The Binary Linker Flags" } + + , {} + , {nil, "ar", "kv", nil, "The Static Library Linker" } + , {nil, "arflags", "kv", nil, "The Static Library Linker Flags" } + + , {} + , {nil, "sh", "kv", nil, "The Shared Library Linker" } + , {nil, "shflags", "kv", nil, "The Shared Library Linker Flags" } + + -- the options for all platforms + , function () return platform.menu("config") end + + , {} + , {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + , {'o', "buildir", "kv", "build", "Set the build directory." } + + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", "all", "Configure for the given target." } + } + } +end + +-- return module: _config +return _config diff --git a/xmake/core/action/_create.lua b/xmake/core/action/_create.lua new file mode 100644 index 000000000..840631f65 --- /dev/null +++ b/xmake/core/action/_create.lua @@ -0,0 +1,173 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _create.lua +-- + +-- define module: _create +local _create = _create or {} + +-- load modules +local utils = require("base/utils") +local template = require("base/template") + +-- need access to the given file? +function _create.need(name) + + -- no accessors + return false +end + +-- done +function _create.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- the target name + local targetname = options.target or options.name or path.basename(xmake._PROJECT_DIR) or "demo" + + -- trace + utils.printf("create %s ...", targetname) + + -- the language + local language = options.language + if not language then + utils.error("no language!") + return false + end + + -- the template id + local templateid = tonumber(options.template) + if type(templateid) ~= "number" then + utils.error("invalid template id: %s!", options.template) + return false + end + + -- load all templates for the given language + local templates = template.loadall(language) + + -- load the template module + local module = nil + if templates then module = templates[templateid] end + if not module then + utils.error("invalid template id: %s!", options.template) + return false + end + + -- enter the template directory + if not module._DIRECTORY or not os.cd(module._DIRECTORY) then + -- error + utils.error("not found template id: %s!", options.template) + return false + end + + -- check the template project + if not os.isdir("project") then + -- errors + utils.error("the template project not exists!") + return false + end + + -- ensure the project directory + if not os.isdir(xmake._PROJECT_DIR) then + os.mkdir(xmake._PROJECT_DIR) + end + + -- copy the project files + local ok, errors = os.cp("project/*", xmake._PROJECT_DIR) + if not ok then + -- errors + utils.error(errors) + return false + end + + -- done the template files + if not module.done(targetname, xmake._PROJECT_DIR, xmake._PACKAGES_DIR) then + utils.error("update the template failed!") + return false + end + + -- trace + utils.printf("create %s ok!", targetname) + + -- ok + return true +end + +-- the menu +function _create.menu() + + return { + -- usage + usage = "xmake create [options] [target]" + + -- description + , description = "Create a new project." + + -- options + , options = + { + {'n', "name", "kv", nil, "The project name." } + , {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } + , {'P', "project", "kv", nil, "Create from the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + , {'l', "language", "kv", "c", "The project language" + , function () + local descriptions = {} + local languages = template.languages() + for _, language in ipairs(languages) do + table.insert(descriptions, " - " .. language) + end + return descriptions + end } + , {'t', "template", "kv", "1", "Select the project template id of the given language." + , function () + local descriptions = {} + local languages = template.languages() + for _, language in ipairs(languages) do + table.insert(descriptions, string.format(" - language: %s", language)) + local templates = template.loadall(language) + if templates then + for i, template in ipairs(templates) do + table.insert(descriptions, string.format(" %d. %s", i, utils.ifelse(template.description, template.description, "The Unknown Project"))) + end + end + end + return descriptions + end } + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", nil, "Create the given target." + , "Uses the project name as target if not exists." } + } + } +end + +-- return module: _create +return _create diff --git a/xmake/core/action/_debug.lua b/xmake/core/action/_debug.lua new file mode 100644 index 000000000..c84d78073 --- /dev/null +++ b/xmake/core/action/_debug.lua @@ -0,0 +1,89 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _debug.lua +-- + +-- define module: _debug +local _debug = _debug or {} + +-- load modules +local utils = require("base/utils") +local config = require("base/config") +local platform = require("platform/platform") + +-- need access to the given file? +function _debug.need(name) + + -- check + assert(name) + + -- the accessors + local accessors = { config = true, global = true, project = true, platform = true } + + -- need it? + return accessors[name] +end + +-- done +function _debug.done() + + -- TODO + print("not implement!") + + -- ok + return true +end + +-- the menu +function _debug.menu() + + return { + -- xmake d + shortname = 'd' + + -- usage + , usage = "xmake debug|d [options] [target]" + + -- description + , description = "Debug target." + + -- options + , options = + { + {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } + , {'P', "project", "kv", nil, "Create from the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", nil, "Debug a given target" } + } + } +end + +-- return module: _debug +return _debug diff --git a/xmake/core/action/_global.lua b/xmake/core/action/_global.lua new file mode 100644 index 000000000..a8fffa0bc --- /dev/null +++ b/xmake/core/action/_global.lua @@ -0,0 +1,104 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _global.lua +-- + +-- define module: _global +local _global = _global or {} + +-- load modules +local utils = require("base/utils") +local global = require("base/global") +local platform = require("platform/platform") + +-- need access to the given file? +function _global.need(name) + + -- check + assert(name) + + -- the accessors + local accessors = { global = true } + + -- need it? + return accessors[name] +end + +-- done +function _global.done() + + -- probe the global platform configure + if not platform.probe(true) then + return false + end + + -- clear up the global configure + global.clearup() + + -- save the global configure + if not global.save() then + -- error + utils.error("save configure failed!") + return false + end + + -- dump global + global.dump() + + -- ok + print("configure ok!") + return true +end + +-- the menu +function _global.menu() + + return { + -- xmake g + shortname = 'g' + + -- usage + , usage = "xmake global|g [options] [target]" + + -- description + , description = "Configure the global options for xmake." + + -- options + , options = + { + {'c', "clean", "k", nil, "Clean the cached configure and configure all again." } + , {nil, "make", "kv", "auto", "Set the make path." } + , {nil, "ccache", "kv", "auto", "Enable or disable the c/c++ compiler cache." + , " --ccache=[y|n]" } + + , {} + -- the options for all platforms + , function () return platform.menu("global") end + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + } + } +end + +-- return module: _global +return _global diff --git a/xmake/core/action/_install.lua b/xmake/core/action/_install.lua new file mode 100644 index 000000000..28ef3650d --- /dev/null +++ b/xmake/core/action/_install.lua @@ -0,0 +1,224 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _install.lua +-- + +-- define module: _install +local _install = _install or {} + +-- load modules +local utils = require("base/utils") +local config = require("base/config") +local global = require("base/global") +local install = require("base/install") +local package = require("base/package") +local project = require("base/project") +local platform = require("platform/platform") + +-- need access to the given file? +function _install.need(name) + + -- no accessors + return false +end + +-- make configure for the given target +function _install._makeconf(configs, target_name, target) + + -- check + assert(configs and target_name and target) + + -- init configs for targets + configs[target_name] = configs[target_name] or {} + local configs_target = configs[target_name] + + -- save the install script + local installscript = target.installscript + if type(installscript) == "string" and os.isfile(installscript) then + local script, errors = loadfile(installscript) + if script then + installscript = script() + if type(installscript) == "table" and installscript.main then + installscript = installscript.main + end + else + utils.error(errors) + return false + end + end + if target.installscript and type(installscript) ~= "function" then + utils.error("invalid install script!") + return false + end + configs_target.installscript = installscript + + -- ok + return true +end + +-- package target +function _install._package(target_name) + + -- get the target name + if not target_name or target_name == "all" then + target_name = "" + end + + -- package it + if os.execute(string.format("xmake p -P %s -f %s %s", xmake._PROJECT_DIR, xmake._PROJECT_FILE, target_name)) ~= 0 then + return false + end + + -- ok + return true +end + +-- done +function _install.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- trace + print("install: ...") + + -- load the global configure first + global.load() + + -- enter the project directory + if not os.cd(xmake._PROJECT_DIR) then + -- errors + utils.error("not found project: %s!", xmake._PROJECT_DIR) + return false + end + + -- package the given target first + if not _install._package(options.target) then + -- errors + utils.error("package: failed!") + return false + end + + -- load the package configure + local configs, errors = package.load() + if not configs then + -- errors + utils.error(errors) + return false + end + + -- reload configure + local errors = config.reload() + if errors then + -- error + utils.error(errors) + return false + end + + -- make the platform configure + if not platform.make() then + utils.error("make platform configure: %s failed!", config.get("plat")) + return false + end + + -- reload project + local errors = project.reload() + if errors then + -- error + utils.error(errors) + return false + end + + -- update the outputdir + for _, target in pairs(configs) do + target.outputdir = options.installdir + end + + -- the targets + local targets = project.targets() + assert(targets) + + -- make configure for the given target + if target_name and target_name ~= "all" then + if not _install._makeconf(configs, target_name, targets[target_name]) then + utils.error("make target configure: %s failed!", target_name) + return false + end + else + for target_name, target in pairs(targets) do + if not _install._makeconf(configs, target_name, target) then + utils.error("make target configure: %s failed!", target_name) + return false + end + end + end + + -- done install + if not install.done(configs) then + -- errors + utils.error("install: failed!") + return false + end + + -- trace + print("install: ok!") + + -- ok + return true +end + +-- the menu +function _install.menu() + + return { + -- xmake i + shortname = 'i' + + -- usage + , usage = "xmake install|i [options] [target]" + + -- description + , description = "Package and install the project binary files." + + -- options + , options = + { + {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + , {'o', "installdir", "kv", nil, "Set the install directory." } + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", "all", "Install the given target." } + } + } +end + +-- return module: _install +return _install diff --git a/xmake/core/action/_lua.lua b/xmake/core/action/_lua.lua new file mode 100644 index 000000000..e342d82e7 --- /dev/null +++ b/xmake/core/action/_lua.lua @@ -0,0 +1,168 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _lua.lua +-- + +-- define module: _lua +local _lua = _lua or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local string = require("base/string") +local tools = require("tools/tools") +local platform = require("platform/platform") + +-- need access to the given file? +function _lua.need(name) + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- do not load config if be not given -f or -P options + if options.file == nil and options.project == nil then + return false + end + + -- patch target for loading config ok + options.target = "all" + + -- the accessors + local accessors = { config = true, global = true, platform = true } + + -- need it? + return accessors[name] +end + +-- done +function _lua.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- no script? + if not options.script then + return false + end + + -- the arguments + local arguments = options.arguments or {} + if type(arguments) ~= "table" then + arguments = {} + end + + -- is string script? + if options.string then + + -- trace + utils.verbose("script: %s", options.script) + + -- load and run string + local script = loadstring(options.script) + if script then + return script(arguments) + end + else + -- attempt to load script from the given file if exists + local file = options.script + if not path.is_absolute(file) then + file = path.absolute(file) + end + + -- attempt to load script from the tools directory + if not os.isfile(file) then + file = tools.find(options.script, xmake._CORE_DIR .. "/tools") + end + + -- load and run the script file + if os.isfile(file) then + + -- load script + local script = loadfile(file) + if script then + + -- load module + local module = script() + if module then + + -- init module + if module.init then + module:init(options.script) + end + + -- done module + return module:main(arguments) + end + end + end + end + + -- failed + utils.error("cannot run this script: %s", options.script) + return false +end + +-- the menu +function _lua.menu() + + return { + -- xmake l + shortname = 'l' + + -- usage + , usage = "xmake lua|l [options] [script] [arguments]" + + -- description + , description = "Run the lua script." + + -- options + , options = + { + {'f', "file", "kv", nil, "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + + , {} + , {'s', "string", "k", nil, "Run the lua string script." } + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "script", "v", nil, "Run the given lua script." + , " - The script name from the xmake tool directory" + , " - The script file" + , " - The script string" } + , {nil, "arguments", "vs", nil, "The script arguments" } + } + } +end + +-- return module: _lua +return _lua diff --git a/xmake/core/action/_man.lua b/xmake/core/action/_man.lua new file mode 100644 index 000000000..feb70dd92 --- /dev/null +++ b/xmake/core/action/_man.lua @@ -0,0 +1,89 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _man.lua +-- + +-- define module: _man +local _man = _man or {} + +-- load modules +local utils = require("base/utils") +local config = require("base/config") +local platform = require("platform/platform") + +-- need access to the given file? +function _man.need(name) + + -- check + assert(name) + + -- the accessors + local accessors = { config = true, global = true, project = true } + + -- need it? + return accessors[name] +end + +-- done +function _man.done() + + -- TODO + print("not implement!") + + -- ok + return true +end + +-- the menu +function _man.menu() + + return { + -- xmake m + shortname = 'm' + + -- usage + , usage = "xmake man|m [options] [target]" + + -- description + , description = "Create a project man." + + -- options + , options = + { + {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } + , {'P', "project", "kv", nil, "Create from the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", "all", "Create man for the given target" } + } + } +end + +-- return module: _man +return _man diff --git a/xmake/core/action/_package.lua b/xmake/core/action/_package.lua new file mode 100644 index 000000000..e39604a33 --- /dev/null +++ b/xmake/core/action/_package.lua @@ -0,0 +1,365 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _package.lua +-- + +-- define module: _package +local _package = _package or {} + +-- load modules +local rule = require("base/rule") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local global = require("base/global") +local string = require("base/string") +local project = require("base/project") +local package = require("base/package") +local platform = require("platform/platform") + +-- need access to the given file? +function _package.need(name) + + -- no accessors + return false +end + +-- configure target for the given architecture +function _package._config(arch, target_name) + + -- need not configure it + if not arch then return true end + + -- done the command + return os.execute(string.format("xmake f -P %s -f %s -a %s %s", xmake._PROJECT_DIR, xmake._PROJECT_FILE, arch, target_name)) == 0; +end + +-- build target for the given architecture +function _package._build(arch, target_name) + + -- get the target name + if not target_name or target_name == "all" then + target_name = "" + end + + -- configure it first + if not _package._config(arch, target_name) then return false end + + -- build it + if os.execute(string.format("xmake -P %s %s", xmake._PROJECT_DIR, target_name)) ~= 0 then + -- errors + utils.error("build failed!") + return false + end + + -- ok + return true +end + +-- backup the target files +function _package._backup(rootdir, filepath) + + -- the relative file path + if filepath and path.is_absolute(filepath) then + filepath = path.relative(filepath, xmake._PROJECT_DIR) + end + + -- not exists? return it directly + if not filepath or not os.isfile(filepath) then return end + + -- the backup file + local backupfile = string.format("%s/%s", rootdir, filepath) + + -- backup it + local ok, errors = os.cp(filepath, backupfile) + if not ok then + -- errors + utils.error(errors) + return + end + + -- ok + return filepath +end + +-- make configure for the given target +function _package._makeconf(target_name, target) + + -- check + assert(target_name and target) + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- the configs + local configs = _package._CONFIGS + assert(configs) + + -- the architecture + local arch = config.get("arch") + if not arch then return false end + + -- init configs for targets + configs[target_name] = configs[target_name] or {} + local configs_target = configs[target_name] + + -- init configs for architectures + configs_target.archs = configs_target.archs or {} + + -- init configs for architecture + configs_target.archs[arch] = configs_target.archs[arch] or {} + local configs_arch = configs_target.archs[arch] + + -- save name + configs_target.name = target_name + + -- save kind + configs_target.kind = target.kind + + -- save the output directory + configs_target.outputdir = options.outputdir or config.get("buildir") + + -- save the header files + configs_target.headers = target.headers + + -- save the target directory + configs_arch.targetdir = rule.backupdir(target_name, arch) + + -- save the config file + configs_arch.config_h = _package._backup(configs_arch.targetdir, rule.config_h(target)) + + -- save the target file + configs_arch.targetfile = _package._backup(configs_arch.targetdir, rule.targetfile(target_name, target)) + + -- save the package script + local packagescript = target.packagescript + if type(packagescript) == "string" and os.isfile(packagescript) then + local script, errors = loadfile(packagescript) + if script then + packagescript = script() + if type(packagescript) == "table" and packagescript.main then + packagescript = packagescript.main + end + else + utils.error(errors) + return false + end + end + if target.packagescript and type(packagescript) ~= "function" then + utils.error("invalid package script!") + return false + end + configs_target.packagescript = packagescript + + -- ok + return true +end + +-- load configure for the given target +function _package._loadconf(target_name) + + -- reload configure + local errors = config.reload() + if errors then + -- error + utils.error(errors) + return false + end + + -- make the platform configure + if not platform.make() then + utils.error("make platform configure: %s failed!", config.get("plat")) + return false + end + + -- reload project + local errors = project.reload() + if errors then + -- error + utils.error(errors) + return false + end + + -- the targets + local targets = project.targets() + assert(targets) + + -- make configure for the given target + if target_name and target_name ~= "all" then + if not _package._makeconf(target_name, targets[target_name]) then + utils.error("make target configure: %s failed!", target_name) + return false + end + else + for target_name, target in pairs(targets) do + if not _package._makeconf(target_name, target) then + utils.error("make target configure: %s failed!", target_name) + return false + end + end + end + + -- ok + return true +end + +-- build target for all architectures +function _package._build_all(archs, target_name) + + -- exists the given architectures? + if archs then + + -- split all architectures + archs = archs:split(",") + if not archs then return false end + + -- build for all architectures + for _, arch in ipairs(archs) do + + -- trim it + arch = arch:trim() + + -- build it + if not _package._build(arch, target_name) then return false end + + -- load configure + if not _package._loadconf(target_name) then return false end + + end + + -- build for single architecture + else + + -- build it + if not _package._build(nil, target_name) then return false end + + -- load configure + if not _package._loadconf(target_name) then return false end + + end + + -- ok + return true +end + +-- done +function _package.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- trace + print("package: ...") + + -- init configs + _package._CONFIGS = _package._CONFIGS or {} + local configs = _package._CONFIGS + + -- load the global configure first + global.load() + + -- enter the project directory + if not os.cd(xmake._PROJECT_DIR) then + -- errors + utils.error("not found project: %s!", xmake._PROJECT_DIR) + return false + end + + -- build the given target first for all architectures + if not _package._build_all(options.archs, options.target) then + -- errors + utils.error("build package failed!") + return false + end + + -- done package + if not package.done(configs) then + -- errors + utils.error("package: failed!") + return false + end + + -- trace + print("package: ok!") + + -- ok + return true +end + +-- the menu +function _package.menu() + + return { + -- xmake p + shortname = 'p' + + -- usage + , usage = "xmake package|p [options] [target]" + + -- description + , description = "Package target." + + -- options + , options = + { + {'a', "archs", "kv", nil, "Package multiple given architectures." + , " .e.g --archs=\"armv7, arm64\" or -a i386" + , "" + , function () + local descriptions = {} + local plats = platform.plats() + if plats then + for i, plat in ipairs(plats) do + descriptions[i] = " - " .. plat .. ":" + local archs = platform.archs(plat) + if archs then + for _, arch in ipairs(archs) do + descriptions[i] = descriptions[i] .. " " .. arch + end + end + end + end + return descriptions + end } + + , {} + , {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } + , {'P', "project", "kv", nil, "Create from the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + , {'o', "outputdir", "kv", nil, "Set the output directory." } + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", "all", "Package a given target" } + } + } +end + +-- return module: _package +return _package diff --git a/xmake/core/action/_run.lua b/xmake/core/action/_run.lua new file mode 100644 index 000000000..64649fcb8 --- /dev/null +++ b/xmake/core/action/_run.lua @@ -0,0 +1,179 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _run.lua +-- + +-- define module: _run +local _run = _run or {} + +-- load modules +local rule = require("base/rule") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local project = require("base/project") +local platform = require("platform/platform") + +-- need access to the given file? +function _run.need(name) + + -- check + assert(name) + + -- the accessors + local accessors = { config = true, global = true, project = true, platform = true } + + -- need it? + return accessors[name] +end + +-- done +function _run.done() + + -- the options + local options = xmake._OPTIONS + assert(options and xmake._PROJECT_DIR) + + -- the target name + local name = options.target + if not name then + -- error + utils.error("no runable target!") + return false + end + + -- the arguments + local arguments = options.arguments or {} + if type(arguments) ~= "table" then + arguments = {} + end + + -- the targets + local targets = project.targets() + if not targets or not targets[name] then + -- error + utils.error("not found target: %s!", name) + return false + end + + -- the target + local target = targets[name] + + -- the target file + local targetfile = rule.targetfile(name, target) + if targetfile and not path.is_absolute(targetfile) then + targetfile = path.absolute(targetfile, xmake._PROJECT_DIR) + end + + -- load the run script + local runscript = target.runscript + if type(runscript) == "string" and os.isfile(runscript) then + local script, errors = loadfile(runscript) + if script then + runscript = script() + if type(runscript) == "table" and runscript.main then + runscript = runscript.main + end + else + utils.error(errors) + return false + end + end + + -- run script + if runscript ~= nil then + if type(runscript) == "function" then + + -- make passed target + local target_passed = {} + target_passed.name = name + target_passed.arguments = arguments + target_passed.targetfile = targetfile + + -- run it + local ok = runscript(target_passed) + if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end + else + utils.error("invalid run script!") + return false + end + end + + -- not executale? + if not target.kind or type(target.kind) ~= "string" or target.kind ~= "binary" then + -- error + utils.error("the target %s is not executale!", name) + return false + end + + -- check the target file + if not targetfile and not os.isfile(targetfile) then + -- error + utils.error("not found target file: %s!", targetfile) + return false + end + + -- done + local ok = os.execute(string.format("%s %s", targetfile, table.concat(arguments, " "))) + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- the menu +function _run.menu() + + return { + -- xmake r + shortname = 'r' + + -- usage + , usage = "xmake run|r [options] [target] [arguments]" + + -- description + , description = "Run the project target." + + -- options + , options = + { + {'d', "debug", "k", nil, "Run and debug the given target." } + , {nil, "debugger", "kv", "auto", "Set the debugger path." } + + , {} + , {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", nil, "Run the given target." } + , {nil, "arguments", "vs", nil, "The target arguments" } + } + } +end + +-- return module: _run +return _run diff --git a/xmake/core/action/_uninstall.lua b/xmake/core/action/_uninstall.lua new file mode 100644 index 000000000..8f82907d6 --- /dev/null +++ b/xmake/core/action/_uninstall.lua @@ -0,0 +1,160 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file _uninstall.lua +-- + +-- define module: _uninstall +local _uninstall = _uninstall or {} + +-- load modules +local utils = require("base/utils") +local config = require("base/config") +local global = require("base/global") +local install = require("base/install") +local uninstall = require("base/uninstall") +local package = require("base/package") +local project = require("base/project") +local platform = require("platform/platform") + +-- need access to the given file? +function _uninstall.need(name) + + -- no accessors + return false +end + +-- package target +function _uninstall._package(target_name) + + -- get the target name + if not target_name or target_name == "all" then + target_name = "" + end + + -- package it + if os.execute(string.format("xmake p -P %s -f %s %s", xmake._PROJECT_DIR, xmake._PROJECT_FILE, target_name)) ~= 0 then + return false + end + + -- ok + return true +end + + +-- done +function _uninstall.done() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- trace + print("uninstall: ...") + + -- load the global configure first + global.load() + + -- enter the project directory + if not os.cd(xmake._PROJECT_DIR) then + -- errors + utils.error("not found project: %s!", xmake._PROJECT_DIR) + return false + end + + -- load the install configure + local configs, errors = install.load() + if not configs then + -- errors + utils.error(errors) + return false + end + + -- reload configure + local errors = config.reload() + if errors then + -- error + utils.error(errors) + return false + end + + -- make the platform configure + if not platform.make() then + utils.error("make platform configure: %s failed!", config.get("plat")) + return false + end + + -- reload project + local errors = project.reload() + if errors then + -- error + utils.error(errors) + return false + end + + -- done uninstall + if not uninstall.done(configs) then + -- errors + utils.error("uninstall: failed!") + return false + end + + -- trace + print("uninstall: ok!") + + -- ok + return true +end + +-- the menu +function _uninstall.menu() + + return { + -- xmake u + shortname = 'u' + + -- usage + , usage = "xmake uninstall|u [options] [target]" + + -- description + , description = "Uninstall the project binary files." + + -- options + , options = + { + {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + + , {} + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", "all", "Install the given target." } + } + } +end + +-- return module: _uninstall +return _uninstall diff --git a/xmake/core/action/action.lua b/xmake/core/action/action.lua new file mode 100644 index 000000000..96e51b5d8 --- /dev/null +++ b/xmake/core/action/action.lua @@ -0,0 +1,190 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file action.lua +-- + +-- define module: action +local action = action or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local global = require("base/global") +local config = require("base/config") +local project = require("base/project") +local platform = require("platform/platform") + +-- load the given action +function action._load(name) + + -- load the given action + return require("action/_" .. name) +end + +-- load the project file +function action._load_project() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- enter the project directory + if not os.cd(xmake._PROJECT_DIR) then + -- error + return string.format("not found project: %s!", xmake._PROJECT_DIR) + end + + -- check the project file + if not os.isfile(xmake._PROJECT_FILE) then + return string.format("not found the project file: %s", xmake._PROJECT_FILE) + end + + -- init the build directory + if options.buildir and path.is_absolute(options.buildir) then + options.buildir = path.relative(options.buildir, xmake._PROJECT_DIR) + end + + -- xmake config or marked as "reconfig"? + if options._ACTION == "config" or config._RECONFIG then + + -- probe the current project + project.probe() + + -- clear up the configure + config.clearup() + + end + + -- load the project + return project.load() +end + +-- done the given action +function action.done(name) + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- load the given action + local _action = action._load(name) + if not _action then return false end + + -- load the global configure first + if _action.need("global") then global.load() end + + -- load the project configure + if _action.need("config") then + local errors = config.load() + if errors then + -- error + utils.error(errors) + return false + end + end + + -- probe the platform + if _action.need("platform") and (options._ACTION == "config" or config._RECONFIG) then + if not platform.probe(false) then + return false + end + end + + -- merge the default options + for k, v in pairs(options._DEFAULTS) do + if nil == options[k] then options[k] = v end + end + + -- make the platform configure + if _action.need("platform") and not platform.make() then + utils.error("make platform configure: %s failed!", config.get("plat")) + return false + end + + -- load the project file + if _action.need("project") then + local errors = action._load_project() + if errors then + -- error + utils.error(errors) + return false + end + end + + -- reconfig it first if marked as "reconfig" + if _action.need("config") and config._RECONFIG then + + -- config it + local _action_config = action._load("config") + if not _action_config or not _action_config.done() then + -- error + utils.error("reconfig failed for the changed host!") + return false + end + end + + -- done the given action + return _action.done() +end + +-- list the all actions +function action.list() + + -- find all action scripts + local list = {} + local files = os.match(xmake._CORE_DIR .. "/action/_*.lua") + if files then + for _, file in ipairs(files) do + local name = path.basename(file) + if name and name ~= "_build" then + table.insert(list, name:sub(2)) + end + end + end + + -- ok? + return list +end + +-- get the all action menus +function action.menu() + + -- get all actions + local menus = {} + local actions = action.list() + for _, name in ipairs(actions) do + + -- load action + local a = action._load(name) + if a and a.menu then + local m = a.menu() + if m then + menus[name] = m + end + end + end + + -- ok? + return menus +end + +-- return module: action +return action diff --git a/xmake/core/base/clean.lua b/xmake/core/base/clean.lua new file mode 100644 index 000000000..9fbb3258a --- /dev/null +++ b/xmake/core/base/clean.lua @@ -0,0 +1,192 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file clean.lua +-- + +-- define module: clean +local clean = clean or {} + +-- load modules +local os = require("base/os") +local rule = require("base/rule") +local utils = require("base/utils") +local config = require("base/config") +local project = require("base/project") + +-- remove the given files or directories +function clean._remove(filedirs) + + -- empty? + if not filedirs then return true end + + -- wrap it first + filedirs = utils.wrap(filedirs) + for _, filedir in ipairs(filedirs) do + + -- exists? remove it + if os.exists(filedir) then + -- remove it + local ok, errors = os.rm(filedir) + if not ok then + -- error + utils.error(errors) + return false + end + end + end + + -- ok + return true +end + +-- remove the given target name +function clean._remove_target(target_name, target, mode, buildir) + + -- check + assert(target_name and target) + + -- remove the target file + if not clean._remove(rule.targetfile(target_name, target, buildir)) then + return false + end + + -- not only remove target file? + if mode ~= "targets" then + + -- remove the object files + if not clean._remove(rule.objectfiles(target_name, target, rule.sourcefiles(target), buildir)) then + return false + end + + -- remove the header files + local _, dstheaders = rule.headerfiles(target) + if not clean._remove(dstheaders) then + return false + end + + -- remove the config.h file + if mode == "all" and target.config_h then + + -- translate file path + local config_h = nil + if not path.is_absolute(target.config_h) then + config_h = path.absolute(target.config_h, xmake._PROJECT_DIR) + else + config_h = path.translate(target.config_h) + end + if not clean._remove(config_h) then + return false + end + end + end + + -- ok + return true +end + +-- remove the given target and all dependent targets +function clean._remove_target_and_deps(target_name, mode, buildir) + + -- the targets + local targets = project.targets() + assert(targets) + + -- the target + local target = targets[target_name] + assert(target) + + -- remove the target + if not clean._remove_target(target_name, target, mode, buildir) then + return false + end + + -- exists the dependent targets? + if target.deps then + local deps = utils.wrap(target.deps) + for _, dep in ipairs(deps) do + if not clean._remove_target_and_deps(dep, mode, buildir) then return false end + end + end + + -- ok + return true +end + +-- remove the target and object files for the given target +-- +-- mode: +-- all +-- build +-- targets +-- +function clean.remove(target_name, mode) + + -- the build directory + local buildir = config.get("buildir") + assert(buildir and mode) + + -- the target name + if target_name and target_name ~= "all" then + -- remove target + if not clean._remove_target_and_deps(target_name, mode, buildir) then return false end + else + + -- the targets + local targets = project.targets() + assert(targets) + + -- remove targets + for target_name, target in pairs(targets) do + if not clean._remove_target(target_name, target, mode, buildir) then return false end + end + end + + -- remove all + if mode == "all" then + + -- remove makefile + if not clean._remove(rule.makefile()) then + return false + end + + -- remove the configure directory + if not clean._remove(config.directory()) then + return false + end + + -- remove the log file + if not clean._remove(rule.logfile()) then + return false + end + + -- remove build directory if be empty + local buildir = config.get("buildir") + if os.isdir(buildir) then + os.rm(buildir, true) + end + + end + + -- ok + return true +end + +-- return module: clean +return clean diff --git a/xmake/core/base/compiler.lua b/xmake/core/base/compiler.lua new file mode 100644 index 000000000..a64f8bae0 --- /dev/null +++ b/xmake/core/base/compiler.lua @@ -0,0 +1,574 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file compiler.lua +-- + +-- define module: compiler +local compiler = compiler or {} + +-- load modules +local io = require("base/io") +local path = require("base/path") +local rule = require("base/rule") +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local config = require("base/config") +local tools = require("tools/tools") +local platform = require("platform/platform") + +-- map gcc flag to the given compiler flag +function compiler._mapflag(module, flag) + + -- check + assert(module.mapflags and flag) + + -- attempt to map it directly + local flag_mapped = module.mapflags[flag] + if flag_mapped and type(flag_mapped) == "string" then + return flag_mapped + end + + -- find and replace it using pattern + for k, v in pairs(module.mapflags) do + local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) + if type(v) == "function" then + return v(module, w) + else + return v + end + end) + if flag_mapped and count ~= 0 then + return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil) + end + end + + -- return it directly + return flag +end + +-- map gcc flags to the given compiler flags +function compiler._mapflags(module, flags) + + -- check + assert(module) + + -- wrap flags first + flags = utils.wrap(flags) + + -- need not map flags? return it directly + if not module.mapflags then + return flags + end + + -- map flags + local flags_mapped = {} + for _, flag in pairs(flags) do + -- map it + local flag_mapped = compiler._mapflag(module, flag) + if flag_mapped then + table.insert(flags_mapped, flag_mapped) + end + end + + -- ok? + return flags_mapped +end + +-- get the compiler flags from names +function compiler._getflags(module, names, flags) + + -- check + assert(flags) + + -- the mapped flags + local flags_mapped = {} + + -- wrap it first + names = utils.wrap(names) + for _, name in ipairs(names) do + table.join2(flags_mapped, compiler._mapflags(module, flags[name])) + end + + -- get it + return flags_mapped +end + +-- add flags from the compiler +function compiler._addflags_from_compiler(module, flags, flagnames, kind) + + -- check + assert(module and flags and flagnames) + + -- done + for _, flagname in ipairs(flagnames) do + + -- add compiler.xxflags + table.join2(flags, module, module[flagname]) + + -- add compiler.kind.xxflags + if kind ~= nil and module[kind] ~= nil then + table.join2(flags, module, module[kind][flagname]) + end + end +end + +-- add flags from the configure +function compiler._addflags_from_config(module, flags, flagnames) + + -- check + assert(module and flags and flagnames) + + -- done + for _, flagname in ipairs(flagnames) do + table.join2(flags, config.get(flagname)) + end +end + +-- add flags from the platform +function compiler._addflags_from_platform(module, flags, flagnames) + + -- check + assert(module and flags and flagnames) + + -- add flags + for _, flagname in ipairs(flagnames) do + table.join2(flags, compiler._mapflags(module, platform.get(flagname))) + end + + -- add the includedirs flags + if module.flag_includedir then + for _, includedir in ipairs(utils.wrap(platform.get("includedirs"))) do + table.join2(flags, module:flag_includedir(includedir)) + end + end + + -- add the defines flags + if module.flag_define then + for _, define in ipairs(utils.wrap(platform.get("defines"))) do + table.join2(flags, module:flag_define(define)) + end + end + + -- append the undefines flags + if module.flag_undefine then + for _, undefine in ipairs(utils.wrap(platform.get("undefines"))) do + table.join2(flags, module:flag_undefine(undefine)) + end + end +end + + +-- add flags from the target +function compiler._addflags_from_target(module, flags, flagnames, target) + + -- check + assert(module and flags and flagnames and target) + + -- add the target flags from the current project + for _, flagname in ipairs(flagnames) do + table.join2(flags, compiler._mapflags(module, target[flagname])) + end + + -- add the symbols flags from the current project + table.join2(flags, compiler._getflags(module, target.symbols, { debug = "-g" + , hidden = "-fvisibility=hidden" + })) + + -- add the warning flags from the current project + table.join2(flags, compiler._getflags(module, target.warnings, { none = "-w" + , less = "-W1" + , more = "-W3" + , all = "-Wall" + , error = "-Werror" + })) + + -- add the optimize flags from the current project + table.join2(flags, compiler._getflags(module, target.optimize, { none = "-O0" + , fast = "-O1" + , faster = "-O2" + , fastest = "-O3" + , smallest = "-Os" + , aggressive = "-Ofast" + })) + + -- add the vector extensions flags from the current project + table.join2(flags, compiler._getflags(module, target.vectorexts, { mmx = "-mmmx" + , sse = "-msse" + , sse2 = "-msse2" + , sse3 = "-msse3" + , ssse3 = "-mssse3" + , avx = "-mavx" + , avx2 = "-mavx2" + , neon = "-mfpu=neon" + })) + + -- add the language flags from the current project + local languages = {} + for _, flagname in ipairs(flagnames) do + if flagname == "cflags" or flagname == "mflags" then + table.join2(languages, { ansi = "-ansi" + , c89 = "-std=c89" + , gnu89 = "-std=gnu89" + , c99 = "-std=c99" + , gnu99 = "-std=gnu99" + , c11 = "-std=c11" + , gnu11 = "-std=gnu11" + }) + elseif flagname == "cxxflags" or flagname == "mxxflags" then + table.join2(languages, { cxx98 = "-std=c++98" + , gnuxx98 = "-std=gnu++98" + , cxx11 = "-std=c++11" + , gnuxx11 = "-std=gnu++11" + , cxx14 = "-std=c++14" + , gnuxx14 = "-std=gnu++14" + }) + end + end + table.join2(flags, compiler._getflags(module, target.languages, languages)) + + -- add the includedirs flags from the current project + if module.flag_includedir then + for _, includedir in ipairs(utils.wrap(target.includedirs)) do + table.join2(flags, module:flag_includedir(includedir)) + end + end + + -- add the defines flags from the current project + if module.flag_define then + for _, define in ipairs(utils.wrap(target.defines)) do + table.join2(flags, module:flag_define(define)) + end + end + + -- append the undefines flags from the current project + if module.flag_undefine then + for _, undefine in ipairs(utils.wrap(target.undefines)) do + table.join2(flags, module:flag_undefine(undefine)) + end + end + + -- the options + if target.options then + for _, name in ipairs(utils.wrap(target.options)) do + + -- get option if be enabled + local opt = nil + if config.get(name) then opt = config.get("__" .. name) end + if nil ~= opt then + + -- add the flags from the option + compiler._addflags_from_target(module, flags, flagnames, opt) + + -- append the defines flags + if opt.defines_if_ok and module.flag_define then + local defines = utils.wrap(opt.defines_if_ok) + for _, define in ipairs(defines) do + table.join2(flags, module:flag_define(define)) + end + end + + -- append the undefines flags + if opt.undefines_if_ok and module.flag_undefine then + local undefines = utils.wrap(opt.undefines_if_ok) + for _, undefine in ipairs(undefines) do + table.join2(flags, module:flag_undefine(undefine)) + end + end + end + end + end +end + +-- add flags from the option +function compiler._addflags_from_option(module, flags, flagnames, opt) + + -- check + assert(module and flags and flagnames and opt) + + -- add the flags from the option + compiler._addflags_from_target(module, flags, flagnames, opt) + +end + +-- get the flag names from the given compiler name +function compiler._flagnames(name) + + -- check + assert(name) + + -- the flag names + local flagnames = nil + if name == "cc" then flagnames = { "cxflags", "cflags" } + elseif name == "cxx" then flagnames = { "cxflags", "cxxflags" } + elseif name == "mm" then flagnames = { "mxflags", "mflags" } + elseif name == "mxx" then flagnames = { "mxflags", "mxxflags" } + elseif name == "as" then flagnames = { "asflags" } + elseif name == "sc" then flagnames = { "scflags" } + else + -- error + utils.error("unknown compiler: %s", name) + return + end + + -- ok + return flagnames +end + +-- get the compiler kind from the source file type +function compiler._kind(srcfile) + + -- get the source file type + local filetype = path.extension(srcfile) + if not filetype then + return nil + end + + -- get the lower file type + filetype = filetype:lower() + + -- get the compiler kind + local kind = nil + if filetype == ".c" then kind = "cc" + elseif filetype == ".cpp" or filetype == ".cc" then kind = "cxx" + elseif filetype == ".m" then kind = "mm" + elseif filetype == ".mm" then kind = "mxx" + elseif filetype == ".s" or filetype == ".asm" then kind = "as" + elseif filetype == ".swift" then kind = "sc" + end + + -- ok + return kind +end + +-- make the compile command for option +function compiler._make_for_option(module, opt, srcfile, objfile, logfile) + + -- check + assert(module and opt) + + -- the flag names + local flagnames = compiler._flagnames(module._KIND) + assert(flagnames) + + -- init flags + local flags = {} + + -- add flags from the configure + compiler._addflags_from_config(module, flags, flagnames) + + -- add flags from the option + compiler._addflags_from_option(module, flags, flagnames, opt) + + -- add flags from the platform + compiler._addflags_from_platform(module, flags, flagnames) + + -- add flags from the compiler + compiler._addflags_from_compiler(module, flags, flagnames) + + -- remove repeat + flags = utils.unique(flags) + + -- execute the compile command + return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile) +end + +-- get the compiler from the given source file +function compiler.get(srcfile) + + -- get the compiler kind + local kind = compiler._kind(srcfile) + if not kind then + return nil, string.format("unknown source file: %s", srcfile) + end + + -- get compiler from the source file type + local module = tools.get(kind) + if module then + + -- invalid compiler + if not module.command_compile then + return nil, string.format("invalid compiler for %s", kind) + end + + -- save kind + module._KIND = kind + else + return nil, string.format("unknown compiler for %s", kind) + end + + -- ok? + return module +end + +-- make the compile command +function compiler.make(module, target, srcfile, objfile, logfile) + + -- check + assert(module and target) + + -- the flag names + local flagnames = compiler._flagnames(module._KIND) + assert(flagnames) + + -- init flags + local flags = {} + + -- add flags from the configure + compiler._addflags_from_config(module, flags, flagnames) + + -- add flags from the target + compiler._addflags_from_target(module, flags, flagnames, target) + + -- add flags from the platform + compiler._addflags_from_platform(module, flags, flagnames) + + -- add flags from the compiler + compiler._addflags_from_compiler(module, flags, flagnames, target.kind) + + -- remove repeat + flags = utils.unique(flags) + + -- make the compile command + return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile) +end + +-- check include for the project option +function compiler.check_include(opt, include, srcpath, objpath) + + -- check + assert(opt and srcpath and objpath) + + -- open the checking source file + local srcfile = io.openmk(srcpath) + if not srcfile then return end + + -- make include + if include then + srcfile:write(string.format("#include <%s>\n\n", include)) + end + + -- make the main function header + srcfile:write("int main(int argc, char** argv)\n") + srcfile:write("{\n") + srcfile:write(" return 0;\n") + srcfile:write("}\n") + + -- exit this file + srcfile:close() + + -- get the compiler + local module = compiler.get(srcpath) + if not module then return end + + -- execute the compile command + return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) +end + +-- check function for the project option +function compiler.check_function(opt, interface, srcpath, objpath) + + -- check + assert(opt and interface) + + -- open the checking source file + local srcfile = io.openmk(srcpath) + if not srcfile then return end + + -- get the compiler + local module = compiler.get(srcpath) + if not module then return end + + -- make includes + local includes = nil + if module._KIND == "cc" then includes = opt.cincludes + elseif module._KIND == "cxx" then includes = opt.cxxincludes + end + if includes then + for _, include in ipairs(utils.wrap(includes)) do + srcfile:write(string.format("#include <%s>\n", include)) + end + srcfile:write("\n") + end + + -- make the main function header + srcfile:write("int main(int argc, char** argv)\n") + srcfile:write("{\n") + + -- make interfaces + srcfile:write(string.format(" volatile void* p%s = (void*)&%s;\n\n", interface, interface)) + + -- make the main function tailer + srcfile:write(" return 0;\n") + srcfile:write("}\n") + + -- exit this file + srcfile:close() + + -- execute the compile command + return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) +end + +-- check typedef for the project option +function compiler.check_typedef(opt, typedef, srcpath, objpath) + + -- check + assert(opt and typedef) + + -- open the checking source file + local srcfile = io.openmk(srcpath) + if not srcfile then return end + + -- get the compiler + local module = compiler.get(srcpath) + if not module then return end + + -- make includes + local includes = nil + if module._KIND == "cc" then includes = opt.cincludes + elseif module._KIND == "cxx" then includes = opt.cxxincludes + end + if includes then + for _, include in ipairs(utils.wrap(includes)) do + srcfile:write(string.format("#include <%s>\n", include)) + end + srcfile:write("\n") + end + + -- make the main function header + srcfile:write("int main(int argc, char** argv)\n") + srcfile:write("{\n") + + -- make interfaces + srcfile:write(string.format(" typedef %s __type_xxx;\n\n", typedef)) + + -- make the main function tailer + srcfile:write(" return 0;\n") + srcfile:write("}\n") + + -- exit this file + srcfile:close() + + -- execute the compile command + return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) +end + +-- return module: compiler +return compiler diff --git a/xmake/core/base/config.lua b/xmake/core/base/config.lua new file mode 100644 index 000000000..3cea6a652 --- /dev/null +++ b/xmake/core/base/config.lua @@ -0,0 +1,395 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file config.lua +-- + +-- define module: config +local config = config or {} + +-- load modules +local io = require("base/io") +local os = require("base/os") +local utils = require("base/utils") +local option = require("base/option") +local global = require("base/global") + +-- make configure for the current target +function config._make(configs) + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- init current target configure + local current = {} + + -- get configs from the default configure + if configs._DEFAULTS then + for k, v in pairs(configs._DEFAULTS) do + if type(v) ~= "string" or v ~= "auto" then current[k] = v end + end + end + + -- get configs from the global configure + if global._CURRENT then + for k, v in pairs(global._CURRENT) do + current[k] = v + end + end + + -- get configs from all targets + for k, v in pairs(configs) do + if type(k) == "string" and not k:find("^_%u+") then + current[k] = v + end + end + + -- get configs from the current target + if configs._TARGETS and current.target ~= "all" then + + -- get the target config + local target_config = configs._TARGETS[current.target] + if target_config then + + -- merge it + for k, v in pairs(target_config) do + current[k] = v + end + end + end + + -- ok? + return current +end + +-- get the configure file +function config._file() + + -- get it + return config.directory() .. "/xmake.conf" +end + +-- need configure? +function config._need(name) + return name and name ~= "target" and name ~= "file" and name ~= "project" and name ~= "verbose" and name ~= "clean" +end + +-- get the current target scope +function config._target() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- check + local configs = config._CONFIGS + assert(configs) + + -- the target name + local name = options.target or options._DEFAULTS.target + assert(name and type(name) == "string") + + -- for all targets? + if name == "all" then + return configs + elseif configs._TARGETS then + -- get it + return configs._TARGETS[name] + end +end + +-- get the given configure from the current +function config.get(name) + + -- the configure has been not loaded + if not config._CURRENT then return end + + -- get it + return config._CURRENT[name] +end + +-- set the given configure to the current +function config.set(name, value) + + -- check + assert(config._CURRENT and name) + + -- get the current target + local target = config._target() + assert(target) + + -- set it to the current target configure for saving to file + target[name] = value + + -- set it to the current configure + config._CURRENT[name] = value +end + +-- the given configure need probe automatically +function config.auto(name) + + -- the configs + local configs = config._CONFIGS + assert(configs) + + -- need probe it automatically? + if configs._DEFAULTS then + local value = configs._DEFAULTS[name] + if value then + if type(value) == "string" and value == "auto" then + return true + end + end + end + + -- need not probe it if have been setted manually + if config._CURRENT and nil ~= config._CURRENT[name] then + return false + end + + -- attempt to probe it if not exists + return true +end + +-- get the configure directory +function config.directory() + + -- the directory + local dir = xmake._PROJECT_DIR .. "/.xmake" + + -- create it directly first if not exists + if not os.isdir(dir) then + assert(os.mkdir(dir)) + end + + -- get it + return dir +end + +-- save xmake.conf +function config.save() + + -- the configs + local configs = config._CONFIGS + assert(configs) + + -- save to the configure file + return io.save(config._file(), configs) +end + +function config.load() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- check + assert(option._MENU) + assert(option._MENU.config) + + -- the target name + local name = options.target or options._DEFAULTS.target + if not name then + return "no given target name!" + end + + -- does not clean the cached configure? + if not options.clean then + + -- load and execute the xmake.xconf + local filepath = config._file() + if os.isfile(filepath) then + + -- load the configure file + local configs, errors = io.load(filepath) + + -- exists local configures? + if configs then + + -- save configs + config._CONFIGS = configs + + -- make the current target configs + local current = config._make(configs) + + -- clear configs and mark as "rebuild" and "reconfig" if the host has been changed + if (current and current.host ~= xmake._HOST) then + + -- clear configs and mark as "rebuild" + config._CONFIGS = { __rebuild = true } + + -- mark as "reconfig" if the current action is not "config" + if options._ACTION ~= "config" then + config._RECONFIG = true + end + end + + -- clear configs and mark as "rebuild" if the plat has been changed + if current and current.plat and options.plat and current.plat ~= options.plat then + + -- clear configs and mark as "rebuild" + config._CONFIGS = { __rebuild = true } + end + + -- mark as "rebuild" if the arch has been changed + if current and current.arch and options.arch and current.arch ~= options.arch then + + -- mark as "rebuild" + config._CONFIGS.__rebuild = true + end + + -- mark as "rebuild" if the mode has been changed + if current and current.mode and options.mode and current.mode ~= options.mode then + + -- mark as "rebuild" + config._CONFIGS.__rebuild = true + end + elseif errors then + -- error + utils.error(errors) + end + end + end + + -- init configs if not exists + if not config._CONFIGS then + -- clear configs and mark as "rebuild" + config._CONFIGS = { __rebuild = true } + + -- mark as "reconfig" if the current action is not "config" + if options._ACTION ~= "config" then + config._RECONFIG = true + end + end + + -- the configs + local configs = config._CONFIGS + + -- mark as "rebuild" if clean the cached configure + if options.clean then + configs.__rebuild = true + end + + -- init the defaults + local defaults = nil + if not configs._DEFAULTS then + if config._RECONFIG then defaults = option.defaults("config") + elseif options._ACTION == "config" then defaults = options._DEFAULTS + end + if defaults then + for k, v in pairs(defaults) do + + -- check + assert(type(k) == "string") + + -- skip some options + if config._need(k) then + + -- save the default option + configs._DEFAULTS = configs._DEFAULTS or {} + configs._DEFAULTS[k] = v + end + end + end + end + defaults = configs._DEFAULTS + + -- init targets + configs._TARGETS = configs._TARGETS or {} + if name ~= "all" then + configs._TARGETS[name] = configs._TARGETS[name] or {} + end + + -- get the current target scope + local target = config._target() + assert(target and type(target) == "table") + + -- merge xmake._OPTIONS to target + if options._ACTION == "config" then + for k, v in pairs(options) do + + -- check + assert(type(k) == "string") + + -- skip some options + if not k:startswith("_") and config._need(k) then + + -- save the option to the target + target[k] = v + + -- remove it from the defaults, because we have setted it manually + if defaults then defaults[k] = nil end + end + end + end + + -- make the current config + config._CURRENT = config._make(config._CONFIGS) +end + +-- clear up and remove all auto values +function config.clearup() + + -- clear up the current configure + local current = config._CURRENT + if current then + for k, v in pairs(current) do + if type(v) == "string" and v == "auto" then + current[k] = nil + end + end + end + + -- clear up the current target configure + local target = config._target() + if target then + for k, v in pairs(target) do + if type(v) == "string" and v == "auto" then + target[k] = nil + end + end + end + +end + +-- reload configure +function config.reload() + + -- clear the old configure + config._CURRENT = nil + config._CONFIGS = nil + + -- load it + return config.load() +end + +-- dump the current configure +function config.dump() + + -- check + assert(config._CURRENT) + + -- dump + utils.dump(config._CURRENT, "__%w*", "configure") + +end + +-- return module: config +return config diff --git a/xmake/core/base/global.lua b/xmake/core/base/global.lua new file mode 100644 index 000000000..0017590c6 --- /dev/null +++ b/xmake/core/base/global.lua @@ -0,0 +1,246 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file global.lua +-- + +-- define module: global +local global = global or {} + +-- load modules +local io = require("base/io") +local os = require("base/os") +local utils = require("base/utils") +local option = require("base/option") + +-- make configure +function global._make() + + -- the configs + local configs = global._CONFIGS + assert(configs) + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- init current global configure + global._CURRENT = global._CURRENT or {} + local current = global._CURRENT + + -- make current global configure + for k, v in pairs(configs) do + if type(k) == "string" and not k:find("^_%u+") then + current[k] = v + end + end +end + +-- get the configure file +function global._file() + + -- get it + return global.directory() .. "/xmake.conf" +end + +-- need configure? +function global._need(name) + return name and name ~= "verbose" and name ~= "clean" +end + +-- get the given configure from the current +function global.get(name) + + -- check + assert(global._CURRENT) + + -- the value + local value = global._CURRENT[name] + if value and value == "auto" then + value = nil + end + + -- get it + return value +end + +-- set the given configure to the current +function global.set(name, value) + + -- check + assert(global._CURRENT and global._CONFIGS) + assert(name and value and type(value) ~= "table") + + -- set it to the current configure + global._CURRENT[name] = value + + -- set it to the configure for saving to file + global._CONFIGS[name] = value + +end + +-- get the global configure directory +function global.directory() + + -- the directory + local dir = path.translate("~/.xmake") + + -- create it directly first if not exists + if not os.isdir(dir) then + assert(os.mkdir(dir)) + end + + -- get it + return dir +end + +-- save xmake.conf +function global.save() + + -- the configs + local configs = global._CONFIGS + assert(configs) + + -- save to the configure file + return io.save(global._file(), configs) +end + +-- load xmake.conf +function global.load() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- check + assert(option._MENU) + assert(option._MENU.global) + + -- get all configure names + local i = 1 + local configures = {} + for _, o in ipairs(option._MENU.global.options) do + local name = o[2] + if global._need(name) then + configures[i] = name + i = i + 1 + end + end + + -- does not clean the cached configure? + if not options.clean then + + -- load and execute the xmake.conf + local filepath = global._file() + if os.isfile(filepath) then + + -- load the configure file + local configs, errors = io.load(filepath) + + -- exists local configures? + if configs then + -- save configs + global._CONFIGS = configs + elseif errors then + -- error + utils.error(errors) + end + end + end + + -- init configs + global._CONFIGS = global._CONFIGS or {} + local configs = global._CONFIGS + + -- xmake global? + if options._ACTION == "global" then + + -- merge xmake._OPTIONS to the global configure + for k, v in pairs(options) do + + -- check + assert(type(k) == "string") + + -- need configure it? + if not k:startswith("_") and global._need(k) then + configs[k] = v + end + end + + -- merge the default global configure options to the global configure + local defaults = options._DEFAULTS + if defaults then + for k, v in pairs(defaults) do + + -- check + assert(type(k) == "string") + + -- need configure it? + if global._need(k) then + + -- save the default option + if nil == configs[k] then + configs[k] = v + end + end + end + end + end + + -- make the current global + global._make() +end + +-- clear up and remove all auto values +function global.clearup() + + -- clear up the current configure + local current = global._CURRENT + if current then + for k, v in pairs(current) do + if v and type(v) and v == "auto" then + current[k] = nil + end + end + end + + -- clear up the configure + local configs = global._CONFIGS + if configs then + for k, v in pairs(configs) do + if v and type(v) and v == "auto" then + configs[k] = nil + end + end + end +end + +-- dump the current configure +function global.dump() + + -- check + assert(global._CURRENT) + + -- dump + utils.dump(global._CURRENT, "__%w*", "configure") + +end + +-- return module: global +return global diff --git a/xmake/core/base/install.lua b/xmake/core/base/install.lua new file mode 100644 index 000000000..9fc41a14a --- /dev/null +++ b/xmake/core/base/install.lua @@ -0,0 +1,143 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file install.lua +-- + +-- define module: install +local install = install or {} + +-- load modules +local os = require("base/os") +local io = require("base/io") +local rule = require("base/rule") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local platform = require("platform/platform") + +-- install target from the project script +function install._done_from_project(target) + + -- check + assert(target) + + -- install it using the project script first + local installscript = target.installscript + if type(installscript) == "function" then + + -- remove it + target.installscript = nil + + -- install it + return installscript(target) + end + + -- continue + return 0 +end + +-- install target from the platform script +function install._done_from_platform(target) + + -- check + assert(target) + + -- the platform install script file + local installscript = nil + local scriptfile = platform.directory() .. "/install.lua" + if os.isfile(scriptfile) then + + -- load the install script + local script, errors = loadfile(scriptfile) + if script then + installscript = script() + if type(installscript) == "table" and installscript.main then + installscript = installscript.main + end + else + utils.error(errors) + end + end + + -- install it + if type(installscript) == "function" then + return installscript(target) + end + + -- continue + return 0 +end + +-- install target from the given target configure +function install._done(target) + + -- check + assert(target) + + -- install it from the project script + local ok = install._done_from_project(target) + if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end + + -- install it from the platform script + local ok = install._done_from_platform(target) + if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end + + -- ok + return true +end + +-- get the configure file +function install._file() + + -- get it + return config.directory() .. "/install.conf" +end + +-- done install from the configure +function install.done(configs) + + -- check + assert(configs) + + -- install targets + for _, target in pairs(configs) do + + -- install it + if not install._done(target) then + -- errors + utils.error("install %s failed!", target.name) + return false + end + + end + + -- save to the configure file + return io.save(install._file(), configs) +end + +-- load the install configure +function install.load() + + -- load it + return io.load(install._file()) +end + +-- return module: install +return install diff --git a/xmake/core/base/io.lua b/xmake/core/base/io.lua new file mode 100644 index 000000000..66b23911a --- /dev/null +++ b/xmake/core/base/io.lua @@ -0,0 +1,324 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file io.lua +-- + +-- define module: io +local io = io or {} + +-- load modules +local path = require("base/path") +local utils = require("base/utils") + +-- save object with the level +function io._save_with_level(file, object, level) + + -- save string + if type(object) == "string" then + file:write(string.format("%q", object)) + -- save boolean + elseif type(object) == "boolean" then + file:write(tostring(object)) + -- save number + elseif type(object) == "number" then + file:write(object) + -- save table + elseif type(object) == "table" then + + -- save head + file:write("\n") + for l = 1, level do + file:write(" ") + end + file:write("{\n") + + -- save body + local i = 0 + for k, v in pairs(object) do + + -- save spaces and separator + for l = 1, level do + file:write(" ") + end + + file:write(utils.ifelse(i == 0, " ", ", ")) + + -- save key + if type(k) == "string" then + file:write(string.format("[%q]", k), " = ") + end + + -- save value + if not io._save_with_level(file, v, level + 1) then + return false + end + + -- save newline + file:write("\n") + i = i + 1 + end + + -- save tail + for l = 1, level do + file:write(" ") + end + file:write("}\n") + else + -- error + utils.error("invalid object type: %s", type(object)) + return false + end + + -- ok + return true +end + +-- save object to given file +function io._save(file, object) + + -- save it + return io._save_with_level(file, object, 0) +end + +-- create directory and open a writable file +function io.openmk(filepath) + + -- check + assert(filepath) + + -- get the file directory + local dir = path.directory(filepath) + + -- ensure the file directory + if not os.isdir(dir) then os.mkdir(dir) end + + -- open it + return io.open(filepath, "w") +end + +-- read all data from file +function io.readall(filepath) + + -- open file + local file = io.open(filepath, "r") + if not file then + -- error + return nil, string.format("open %s failed!", filepath) + end + + -- read all + local data = file:read("*all") + + -- exit file + file:close() + + -- ok? + return data +end + +-- write all data to file +function io.writall(filepath, data) + + -- open file + local file = io.open(filepath, "w") + if not file then + -- error + return false, string.format("open %s failed!", filepath) + end + + -- write all + file:write(data) + + -- exit file + file:close() + + -- ok? + return true +end + +-- save object the the given filepath +function io.save(filepath, object) + + -- open the file + local file = io.openmk(filepath) + if not file then + -- error + return false, string.format("open %s failed!", filepath) + end + + -- save object to file + if not io._save(file, object) then + -- error + file:close() + return false, string.format("save %s failed!", filepath) + end + + -- close file + file:close() + + -- ok + return true +end + +-- load object from the given file +function io.load(filepath) + + -- open the file + local file = io.open(filepath, "r") + if not file then + -- error + return nil, string.format("open %s failed!", filepath) + end + + -- load data + local result = nil + local errors = nil + local data = file:read("*all") + if data and type(data) == "string" then + + -- load script + local script, errs = loadstring("return " .. data) + if script then + + -- load object + local ok, object = pcall(script) + if ok and object then + result = object + elseif object then + -- error + errors = object + else + -- error + errors = string.format("load %s failed!", filepath) + end + -- errors + else errors = errs end + end + + -- close file + file:close() + + -- ok? + return result, errors +end + +-- gsub the given file and return replaced data +function io.gsub(filepath, pattern, replace) + + -- read all data from file + local data, errors = io.readall(filepath) + if not data then return nil, 0, errors end + + -- replace it + local count = 0 + if type(data) == "string" then + data, count = data:gsub(pattern, replace) + else + return nil, 0, string.format("data is not string!") + end + + -- replace ok? + if count ~= 0 then + -- write all data to file + local ok, errors = io.writall(filepath, data) + if not ok then return nil, 0, errors end + end + + -- ok + return data, count +end + +-- cat the given file +function io.cat(filepath, linecount) + + -- open file + local file = io.open(filepath, "r") + if file then + + -- show file + local count = 1 + for line in file:lines() do + + -- show line + print(line) + + -- end? + if linecount and count >= linecount then + break + end + + -- update the line count + count = count + 1 + end + + -- exit file + file:close() + end +end + +-- tail the given file +function io.tail(filepath, linecount) + + -- open file + local file = io.open(filepath, "r") + if file then + + -- read lines + local lines = {} + for line in file:lines() do + table.insert(lines, line) + end + + -- tail lines + local tails = {} + if #lines ~= 0 then + local count = 1 + for index = #lines, 1, -1 do + + -- show line + table.insert(tails, lines[index]) + + -- end? + if linecount and count >= linecount then + break + end + + -- update the line count + count = count + 1 + end + end + + -- show tails + if #tails ~= 0 then + for index = #tails, 1, -1 do + + -- show tail + print(tails[index]) + + end + end + + -- exit file + file:close() + end +end + +-- return module: io +return io diff --git a/xmake/core/base/linker.lua b/xmake/core/base/linker.lua new file mode 100644 index 000000000..9a0388757 --- /dev/null +++ b/xmake/core/base/linker.lua @@ -0,0 +1,386 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file linker.lua +-- + +-- define module: linker +local linker = linker or {} + +-- load modules +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local config = require("base/config") +local compiler = require("base/compiler") +local tools = require("tools/tools") +local platform = require("platform/platform") + +-- map gcc flag to the given linker flag +function linker._mapflag(module, flag) + + -- check + assert(module.mapflags and flag) + + -- attempt to map it directly + local flag_mapped = module.mapflags[flag] + if flag_mapped and type(flag_mapped) == "string" then + return flag_mapped + end + + -- find and replace it using pattern + for k, v in pairs(module.mapflags) do + local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) + if type(v) == "function" then + return v(module, w) + else + return v + end + end) + if flag_mapped and count ~= 0 then + return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil) + end + end + + -- return it directly + return flag +end + +-- map gcc flags to the given linker flags +function linker._mapflags(module, flags) + + -- check + assert(module) + + -- wrap flags first + flags = utils.wrap(flags) + + -- need not map flags? return it directly + if not module.mapflags then + return flags + end + + -- map flags + local flags_mapped = {} + for _, flag in pairs(flags) do + -- map it + local flag_mapped = linker._mapflag(module, flag) + if flag_mapped then + table.insert(flags_mapped, flag_mapped) + end + end + + -- ok? + return flags_mapped +end + +-- get the linker flags from names +function linker._getflags(module, names, flags) + + -- check + assert(flags) + + -- the mapped flags + local flags_mapped = {} + + -- wrap it first + names = utils.wrap(names) + for _, name in ipairs(names) do + table.join2(flags_mapped, linker._mapflags(module, flags[name])) + end + + -- get it + return flags_mapped +end + + +-- add flags from the links +function linker._addflags_from_links(module, flags, links) + + -- check + assert(module and flags and links) + + -- done + if module.flag_link then + for _, link in ipairs(utils.wrap(links)) do + table.join2(flags, module:flag_link(link)) + end + end +end + +-- add flags from the linker +function linker._addflags_from_linker(module, flags, flagname) + + -- check + assert(module and flags and flagname) + + -- done + table.join2(flags, module[flagname]) +end + +-- add flags from the compiler +function linker._addflags_from_compiler(module, flags, flagname, srcfiles) + + -- check + assert(module and flags and flagname) + + -- add the flags for compiler + local flags_for_compiler = {} + if srcfiles then + for _, srcfile in ipairs(utils.wrap(srcfiles)) do + + -- get the compiler + local c, errors = compiler.get(srcfile) + if not c then + -- error + utils.error(errors) + return + end + + -- add flags + table.join2(flags_for_compiler, c[flagname]) + end + end + + -- done + table.join2(flags, utils.unique(flags_for_compiler)) +end + +-- add flags from the configure +function linker._addflags_from_config(module, flags, flagname) + + -- check + assert(module and flags and flagname) + + -- done + table.join2(flags, config.get(flagname)) +end + +-- add flags from the platform +function linker._addflags_from_platform(module, flags, flagname) + + -- check + assert(module and flags and flagname) + + -- add flags + table.join2(flags, linker._mapflags(module, platform.get(flagname))) + + -- add the linkdirs flags + if module.flag_linkdir then + for _, linkdir in ipairs(utils.wrap(platform.get("linkdirs"))) do + table.join2(flags, module:flag_linkdir(linkdir)) + end + end + + -- add the links flags + if module.flag_link then + for _, link in ipairs(utils.wrap(platform.get("links"))) do + table.join2(flags, module:flag_link(link)) + end + end +end + +-- add flags from the target +function linker._addflags_from_target(module, flags, flagname, target) + + -- check + assert(module and flags and flagname and target) + + -- add the target flags from the current project + table.join2(flags, linker._mapflags(module, target[flagname])) + + -- add the linkdirs flags from the current project + if module.flag_linkdir then + for _, linkdir in ipairs(utils.wrap(target.linkdirs)) do + table.join2(flags, module:flag_linkdir(linkdir)) + end + end + + -- add the links flags from the current project + if module.flag_link then + for _, link in ipairs(utils.wrap(target.links)) do + table.join2(flags, module:flag_link(link)) + end + end + + -- the options + if target.options then + for _, name in ipairs(utils.wrap(target.options)) do + + -- get option if be enabled + local opt = nil + if config.get(name) then opt = config.get("__" .. name) end + if nil ~= opt then + + -- add the flags from the option + table.join2(flags, linker._mapflags(module, opt[flagname])) + + -- add the linkdirs flags from the option + if module.flag_linkdir then + for _, linkdir in ipairs(utils.wrap(opt.linkdirs)) do + table.join2(flags, module:flag_linkdir(linkdir)) + end + end + + -- add the links flags from the option + if module.flag_link then + for _, link in ipairs(utils.wrap(opt.links)) do + table.join2(flags, module:flag_link(link)) + end + end + end + end + end + + -- add the flags from the configure + table.join2(flags, linker._mapflags(module, config.get(flagname))) + + -- add the strip flags from the current project + table.join2(flags, linker._getflags(module, target.strip, { debug = "-S" + , all = "-s" + })) +end + +-- add flags from the option +function linker._addflags_from_option(module, flags, flagname, opt) + + -- check + assert(module and flags and flagname and opt) + + -- append the option flags + table.join2(flags, linker._mapflags(module, opt[flagname])) + + -- append the linkdirs flags + if opt.linkdirs and module.flag_linkdir then + for _, linkdir in ipairs(utils.wrap(opt.linkdirs)) do + table.join2(flags, module:flag_linkdir(linkdir)) + end + end +end + +-- get the linker from the given kind +function linker.get(kind) + + -- check + assert(kind) + + -- get the linker name from the kind + local name = nil + if kind == "binary" then name = "ld" + elseif kind == "static" then name = "ar" + elseif kind == "shared" then name = "sh" + else return end + + -- get it + local module = tools.get(name) + + -- invalid linker? + if module and not module.command_link then + return + end + + -- ok? + return module +end + +-- make the link command +function linker.make(module, target, srcfiles, objfiles, targetfile, logfile) + + -- check + assert(module and target) + + -- the target kind + local kind = target.kind or "" + + -- the flag name + local flagname = nil + if kind == "binary" then flagname = "ldflags" + elseif kind == "static" then flagname = "arflags" + elseif kind == "shared" then flagname = "shflags" + else + -- error + utils.error("unknown type for linker: %s", kind) + return + end + + -- init flags + local flags = {} + + -- add flags from the configure + linker._addflags_from_config(module, flags, flagname) + + -- add flags from the target + linker._addflags_from_target(module, flags, flagname, target) + + -- add flags from the platform + linker._addflags_from_platform(module, flags, flagname) + + -- add flags from the compiler + linker._addflags_from_compiler(module, flags, flagname, srcfiles) + + -- add flags from the linker + linker._addflags_from_linker(module, flags, flagname) + + -- remove repeat + flags = utils.unique(flags) + + -- make the link command + return module:command_link(table.concat(objfiles, " "), targetfile, table.concat(flags, " "):trim(), logfile) +end + +-- check link for the project option +function linker.check_links(opt, links, sourcefile, objectfile, targetfile) + + -- check + assert(opt and links and objectfile and targetfile) + + -- get the linker + local module = linker.get("binary") + assert(module and module.flag_link) + + -- init flags + local flags = {} + + -- add flags from the configure + linker._addflags_from_config(module, flags, "ldflags") + + -- add flags from the option + linker._addflags_from_option(module, flags, "ldflags", opt) + + -- add flags from the platform + linker._addflags_from_platform(module, flags, "ldflags") + + -- add flags from the links + linker._addflags_from_links(module, flags, links) + + -- add flags from the compiler + linker._addflags_from_compiler(module, flags, "ldflags", sourcefile) + + -- add flags from the linker + linker._addflags_from_linker(module, flags, "ldflags") + + -- remove repeat + flags = utils.unique(flags) + + -- execute the link command + return module:main(module:command_link(objectfile, targetfile, table.concat(flags, " "):trim(), utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) +end + +-- return module: linker +return linker diff --git a/xmake/core/base/main.lua b/xmake/core/base/main.lua new file mode 100644 index 000000000..470815701 --- /dev/null +++ b/xmake/core/base/main.lua @@ -0,0 +1,179 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file main.lua +-- + +-- define module: main +local main = main or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local option = require("base/option") +local action = require("action/action") + +-- init the option menu +local menu = +{ + -- title + title = xmake._VERSION .. ", The Automatic Cross-platform Build Tool" + + -- copyright +, copyright = "Copyright (C) 2015-2016 Ruki Wang, tboox.org\nCopyright (C) 2005-2014 Mike Pall, luajit.org" + + -- build project: xmake +, main = + { + -- usage + usage = "xmake [action] [options] [target]" + + -- description + , description = "Build the project if no given action." + + -- actions + , actions = action.list + + -- options + , options = + { + {'b', "build", "k", nil, "Build project. This is default building mode and optional." } + , {'u', "update", "k", nil, "Only relink and update the binary files." } + , {'r', "rebuild", "k", nil, "Rebuild the project." } + + , {} + , {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } + , {'P', "project", "kv", nil, "Change to the given project directory." + , "Search priority:" + , " 1. The Given Command Argument" + , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" + , " 3. The Current Directory" } + + + , {} + , {'j', "jobs", "kv", nil, "Specifies the number of jobs to build simultaneously" } + , {'v', "verbose", "k", nil, "Print lots of verbose information." } + , {nil, "version", "k", nil, "Print the version number and exit." } + , {'h', "help", "k", nil, "Print this help message and exit." } + + , {} + , {nil, "target", "v", "all", "Build the given target." } + } + } + + -- the actions: xmake [action] +, action.menu + +} + +-- done help +function main._done_help() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- done help + if options.help then + + -- print menu + option.print_menu(options._ACTION) + + -- ok + return true + + -- done version + elseif options.version then + + -- print title + if option._MENU.title then + print(option._MENU.title) + end + + -- print copyright + if option._MENU.copyright then + print(option._MENU.copyright) + end + + -- ok + return true + end +end + +-- done option +function main._done_option() + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- done help? + if main._done_help() then + return true + end + + -- done action + return action.done(options._ACTION or "build") +end + +-- the init function for main +function main._init() + + -- init the project directory + local projectdir = option.find(xmake._ARGV, "project", "P") or xmake._PROJECT_DIR + if projectdir and not path.is_absolute(projectdir) then + projectdir = path.absolute(projectdir) + elseif projectdir then + projectdir = path.translate(projectdir) + end + xmake._PROJECT_DIR = projectdir + assert(projectdir) + + -- init the xmake.lua file path + local projectfile = option.find(xmake._ARGV, "file", "f") or xmake._PROJECT_FILE + if projectfile and not path.is_absolute(projectfile) then + projectfile = path.absolute(projectfile, projectdir) + end + xmake._PROJECT_FILE = projectfile + assert(projectfile) +end + +-- the main function +function main.done() + + -- init + main._init() + + -- init option + if not option.init(xmake._ARGV, menu) then + return -1 + end + + -- done option + if not main._done_option() then + return -1 + end + + -- ok + return 0 +end + +-- return module: main +return main diff --git a/xmake/core/base/makefile.lua b/xmake/core/base/makefile.lua new file mode 100644 index 000000000..826310d1a --- /dev/null +++ b/xmake/core/base/makefile.lua @@ -0,0 +1,417 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file makefile.lua +-- + +-- define module: makefile +local makefile = makefile or {} + +-- load modules +local io = require("base/io") +local os = require("base/os") +local rule = require("base/rule") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local project = require("base/project") +local linker = require("base/linker") +local compiler = require("base/compiler") +local tools = require("tools/tools") +local platform = require("platform/platform") + +-- make object for the *.[o|obj] source file +function makefile._make_object_for_object(file, target, srcfile, objfile) + + -- get the source file type + local filetype = path.extension(srcfile) + if not filetype then return false end + + -- get the lower file type + filetype = filetype:lower() + + -- not object file? + if filetype ~= ".o" and filetype ~= ".obj" then return false end + + -- get mode + local mode = config.get("mode") + if mode then + mode = "." .. mode + else + mode = "" + end + + -- make command + local cmd = string.format("xmake l cp %s %s", srcfile, objfile) + + -- make head + file:write(string.format("%s:", objfile)) + + -- make dependence + file:write(string.format(" %s\n", srcfile)) + + -- make body + file:write(string.format("\t@echo inserting%s %s\n", mode, srcfile)) + file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) + file:write(string.format("\t@%s\n", cmd)) + + -- make tail + file:write("\n") + + -- ok + return true +end + +-- make object for the *.[a|lib] source file +function makefile._make_object_for_static(file, target, srcfile, objfile) + + -- get the source file type + local filetype = path.extension(srcfile) + if not filetype then return false end + + -- get the lower file type + filetype = filetype:lower() + + -- not static file? + if filetype ~= ".a" and filetype ~= ".lib" then return false end + + -- get mode + local mode = config.get("mode") + if mode then + mode = "." .. mode + else + mode = "" + end + + -- make command + local cmd = string.format("xmake l -P %s -f %s dispatcher ex extract %s %s > %s 2>&1", xmake._PROJECT_DIR, xmake._PROJECT_FILE, srcfile:encode(), objfile:encode(), makefile._LOGFILE) + + -- make head + file:write(string.format("%s:", objfile)) + + -- make dependence + file:write(string.format(" %s\n", srcfile)) + + -- make body + file:write(string.format("\t@echo inserting%s %s\n", mode, srcfile)) + file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) + file:write(string.format("\t@xmake l rmdir %s\n", path.directory(objfile))) + file:write(string.format("\t@%s\n", cmd)) + + -- make tail + file:write("\n") + + -- ok + return true +end + +-- make the object to the makefile +function makefile._make_object(file, target, srcfile, objfile) + + -- check + assert(file and target and srcfile and objfile) + + -- make object for the *.o/obj source file + if makefile._make_object_for_object(file, target, srcfile, objfile) then + return true + elseif makefile._make_object_for_static(file, target, srcfile, objfile) then + return true + end + + -- get the compiler + local c, errors = compiler.get(srcfile) + if not c then + -- error + utils.error(errors) + return false + end + + -- get mode + local mode = config.get("mode") + if mode then + mode = "." .. mode + else + mode = "" + end + + -- get ccache + local ccache = platform.tool("ccache") + + -- make command + local cmd = compiler.make(c, target, srcfile, objfile, makefile._LOGFILE) + if ccache then + cmd = ccache:append(cmd, " ") + end + + -- make head + file:write(string.format("%s:", objfile)) + + -- make dependence + file:write(string.format(" %s\n", srcfile)) + + -- make body + file:write(string.format("\t@echo %scompiling%s %s\n", utils.ifelse(ccache, "ccache ", ""), mode, srcfile)) + file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) + file:write(string.format("\t@xmake l mkdir %s\n", path.directory(objfile))) + file:write(string.format("\t@%s\n", cmd)) + + -- make tail + file:write("\n") + + -- ok + return true +end + +-- make all objects of the given target to the makefile +function makefile._make_objects(file, target, srcfiles, objfiles) + + -- check + assert(file and target and srcfiles and objfiles) + + -- make all objects + local i = 1 + for _, objfile in ipairs(objfiles) do + + -- make object + if not makefile._make_object(file, target, srcfiles[i], objfile) then + return false + end + + -- next + i = i + 1 + end + + -- ok + return true +end + +-- make the given target to the makefile +function makefile._make_target(file, name, target) + + -- check + assert(file and name and target and target.kind) + + -- get source and object files + local srcfiles = rule.sourcefiles(target) + local objfiles = rule.objectfiles(name, target, srcfiles) + assert(srcfiles and objfiles) + + -- get source and destinate header files + local srcheaders, dstheaders = rule.headerfiles(target) + + -- get target file + local targetfile = rule.targetfile(name, target) + assert(targetfile) + + -- get the targets + local targets = project.targets() + assert(targets) + + -- get the linker from the given kind + local l = linker.get(target.kind) + if not l then + utils.error("cannot get linker with kind: %s", target.kind) + return false + end + + -- make head + file:write(string.format("%s: %s\n", name, targetfile)) + file:write(string.format("%s:", targetfile)) + + -- make dependence for the dependent targets + if target.deps then + + -- get all dependent target + local deps = utils.wrap(target.deps) + for _, dep in ipairs(deps) do + + -- the dependent target + local deptarget = targets[dep] + if not deptarget then + utils.error("the dependent target: %s is invalid!", dep) + return false + end + + -- get the dependent target file + local depfile = rule.targetfile(dep, deptarget) + assert(depfile) + + -- add dependence + file:write(" " .. depfile) + end + end + + -- make dependence for objects + for _, objfile in ipairs(objfiles) do + file:write(" " .. objfile) + end + + -- make dependence end + file:write("\n") + + -- get mode + local mode = config.get("mode") + if mode then + mode = "." .. mode + else + mode = "" + end + + -- make the command + local cmd = linker.make(l, target, srcfiles, objfiles, targetfile, makefile._LOGFILE) + + -- the verbose + local verbose = cmd:encode() + -- too long? + if verbose and #verbose > 256 then + verbose = linker.make(l, target, srcfiles, {rule.filename("*", "object")}, targetfile) + verbose = verbose:encode() + end + + -- make body + file:write(string.format("\t@echo linking%s %s\n", mode, path.filename(targetfile))) + file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", verbose)) + file:write(string.format("\t@xmake l mkdir %s\n", path.directory(targetfile))) + file:write(string.format("\t@%s\n", cmd)) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + file:write(string.format("\t@xmake l cp %s %s\n", srcheader, dstheader)) + end + i = i + 1 + end + end + + -- make tail + file:write("\n") + + -- make objects for this target + return makefile._make_objects(file, target, srcfiles, objfiles) +end + +-- make all targets to the makefile +function makefile._make_targets(file) + + -- check + assert(file) + + -- get all project targets + local targets = project.targets() + if not targets then + -- error + utils.error("not found target in this project!") + return false + end + + -- make all first + local all = "" + for name, _ in pairs(targets) do + -- append the target name to all + all = all .. " " .. name + end + file:write(string.format("all: %s\n\n", all)) + file:write(string.format(".PHONY: all %s\n\n", all)) + + -- make it for all targets + for name, target in pairs(targets) do + -- make target + if not makefile._make_target(file, name, target) then + -- error + utils.error("failed to make target %s to makefile!", name) + return false + end + + -- append the target name to all + all = all .. " " .. name + end + + -- ok + return true +end + +-- make makefile in the build directory +function makefile.make() + + -- get the build directory + local buildir = config.get("buildir") + assert(buildir) + + -- init the log file + local logfile = rule.logfile() + if logfile and os.isfile(logfile) then + os.rmfile(logfile) + end + + -- save the log file + makefile._LOGFILE = logfile + assert(logfile) + + -- open the makefile + local path = rule.makefile() + local file = io.openmk(path) + if not file then + -- error + utils.error("open %s failed!", path) + return false + end + + -- make all targets to the makefile + if not makefile._make_targets(file) then + + -- error + utils.error("save %s failed!", path) + + -- close the makefile + file:close() + + -- remove the makefile + os.rm(path) + + -- failed + return false + end + + -- close the makefile + file:close() + + -- ok + return true +end + +-- build target +function makefile.build(target) + + -- check + assert(target and type(target) == "string") + + -- load make + local make = tools.get("make") + if not make then + utils.error("not found the make command!") + return false + end + + -- done make + return make:main(rule.makefile(), target) +end + +-- return module: makefile +return makefile diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua new file mode 100644 index 000000000..1c8c35573 --- /dev/null +++ b/xmake/core/base/option.lua @@ -0,0 +1,650 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file option.lua +-- + +-- define module: option +local option = option or {} + +-- load modules +local utils = require("base/utils") +local table = require("base/table") + +-- save the option menu +function option._save_menu(menu) + + -- translate the action menus if exists function + local submenus_all = {} + for k, submenu in pairs(menu) do + if type(submenu) == "function" then + local _submenus = submenu() + if _submenus then + for k, m in pairs(_submenus) do + submenus_all[k] = m + end + end + else + submenus_all[k] = submenu + end + end + table.copy2(menu, submenus_all) + + -- translate the actions of the main menu if exists function + if menu.main and type(menu.main.actions) == "function" then + menu.main.actions = menu.main.actions() + end + + -- translate it if exists function in the option menu + for _, submenu in pairs(menu) do + + -- exits options? + if submenu.options then + + -- translate options + local options_all = {} + for _, option in ipairs(submenu.options) do + + -- this option is function? translate it + if type(option) == "function" then + local _options = option() + if _options then + for _, o in ipairs(_options) do + table.insert(options_all, o) + end + end + else + table.insert(options_all, option) + end + end + + -- update the options + submenu.options = options_all + end + end + + -- save menu + option._MENU = menu + +end + +-- init the option +function option.init(argv, menu) + + -- check + assert(argv and menu) + + -- the main menu + local main = menu.main + assert(main) + + -- init _OPTIONS + xmake._OPTIONS = {} + xmake._OPTIONS._DEFAULTS = {} + + -- save menu + option._save_menu(menu) + + -- parse _ARGV to _OPTIONS + local _iter, _s, _k = ipairs(argv) + while true do + + -- the idx and arg + local idx, arg = _iter(_s, _k) + + -- end? + _k = idx + if idx == nil then break end + + -- parse key and value + local key, value + local i = arg:find("=", 1, true) + + -- key=value? + if i then + key = arg:sub(1, i - 1) + value = arg:sub(i + 1) + -- only key? + else + key = arg + value = true + end + + -- --key? + local prefix = 0 + if key:startswith("--") then + key = key:sub(3) + prefix = 2 + -- -k? + elseif key:startswith("-") then + key = key:sub(2) + prefix = 1 + end + + -- check key + if prefix and #key == 0 then + + -- invalid option + print("invalid option: " .. arg) + + -- print menu + option.print_menu(xmake._OPTIONS._ACTION) + + -- failed + return false + end + + -- --key=value or -k value or -k? + if prefix ~= 0 then + + -- find this option + local opt = nil + for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do + + -- check + assert(o) + + -- --key? + if prefix == 2 and key == o[2] then + opt = o + break + -- k? + elseif prefix == 1 and key == o[1] then + opt = o + break + end + end + + -- not found? + if not opt then + + -- invalid option + print("invalid option: " .. arg) + + -- print menu + option.print_menu(xmake._OPTIONS._ACTION) + + -- failed + return false + end + + -- -k value? continue to get the value + if prefix == 1 and opt[3] == "kv" then + + -- get the next idx and arg + idx, arg = _iter(_s, _k) + + -- exists value? + _k = idx + if idx == nil or arg:startswith("-") then + + -- invalid option + print("invalid option: " .. utils.ifelse(idx, arg, key)) + + -- print menu + option.print_menu(xmake._OPTIONS._ACTION) + + -- failed + return false + end + + -- get value + value = arg + end + + -- check mode + if (opt[3] == "k" and type(value) ~= "boolean") or (opt[3] == "kv" and type(value) ~= "string") then + + -- invalid option + print("invalid option: " .. arg) + + -- print menu + option.print_menu(xmake._OPTIONS._ACTION) + + -- failed + return false + end + + -- value is "true" or "false", translate it + if type(value) == "string" then + if value == "true" then value = true + elseif value == "false" then value = false + end + end + + -- save option + xmake._OPTIONS[utils.ifelse(prefix == 1 and opt[2], opt[2], key)] = value + + -- action? + elseif idx == 1 then + + -- find this action + for _, action in ipairs(main.actions) do + + -- check + assert(menu[action]) + + -- ok? + if action == key or menu[action].shortname == key then + -- save this action + xmake._OPTIONS._ACTION = action + break + end + end + + -- not found? + if not xmake._OPTIONS._ACTION or not menu[xmake._OPTIONS._ACTION] then + + -- invalid action + print("invalid action: " .. key) + + -- print the main menu + option.print_main() + + -- failed + return false + + end + + -- value? + else + + -- find a value option with name + local opt = nil + for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do + + -- the mode + local mode = o[3] + + -- the name + local name = o[2] + + -- check + assert(o and ((mode ~= "v" and mode ~= "vs") or name)) + + -- is value and with name? + if mode == "v" and name and not xmake._OPTIONS[name] then + opt = o + break + -- is values and with name? + elseif mode == "vs" and name then + opt = o + break + end + end + + -- ok? save this value with name opt[2] + if opt then + + -- the mode + local mode = opt[3] + + -- the name + local name = opt[2] + + -- save value + if mode == "v" then + xmake._OPTIONS[name] = key + elseif mode == "vs" then + -- the option + local o = xmake._OPTIONS[name] + if not o then + xmake._OPTIONS[name] = {} + o = xmake._OPTIONS[name] + end + + -- append value + table.insert(o, key) + end + else + -- invalid option + print("invalid option: " .. arg) + + -- print menu + option.print_menu(xmake._OPTIONS._ACTION) + + -- failed + return false + end + + end + end + + -- init the default value + for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do + + -- key=value? + if o[3] == "kv" then + + -- the key + local key = o[2] or o[1] + assert(key) + + -- save the default value + xmake._OPTIONS._DEFAULTS[key] = o[4] + -- value with name? + elseif o[3] == "v" and o[2] then + -- save the default value + xmake._OPTIONS._DEFAULTS[o[2]] = o[4] + end + end + + -- ok + return true +end + +-- find the value of a given name from the arguments +-- only for kv mode and need not check it using menu +-- +function option.find(argv, name, shortname) + + -- check + assert(argv and (name or shortname)) + + -- find it + local nextvalue = false + for _, arg in ipairs(argv) do + + -- get this value + if nextvalue then return arg end + + -- --name=value? + if name and arg:startswith("--" .. name) then + + -- get value + local i = arg:find("=", 1, true) + if i then return arg:sub(i + 1) end + + -- -shortname value? + elseif shortname and arg:startswith("-" .. shortname) then + + -- get value + nextvalue = true + end + + end +end + +-- get all default options from the given action +function option.defaults(action) + + -- make defaults + local defaults = {} + + -- init the default value + for _, o in ipairs(option._MENU[action or "main"].options) do + + -- key=value? + if o[3] == "kv" then + + -- the key + local key = o[2] or o[1] + assert(key) + + -- save the default value + defaults[key] = o[4] + -- value with name? + elseif o[3] == "v" and o[2] then + -- save the default value + defaults[o[2]] = o[4] + end + end + + -- ok? + return defaults +end + +-- print the menu +function option.print_menu(action) + + -- no action? print main menu + if not action then + option.print_main() + return + end + + -- the menu + local menu = option._MENU + assert(menu) + + -- the action + action = menu[action] + assert(action) + + -- print title + if menu.title then + print(menu.title) + end + + -- print copyright + if menu.copyright then + print(menu.copyright) + end + + -- print usage + if action.usage then + print("") + print("Usage: " .. action.usage) + end + + -- print description + if action.description then + print("") + print(action.description) + end + + -- print options + if action.options then + option.print_options(action.options) + end +end + +-- print the main menu +function option.print_main() + + -- the menu + local menu = option._MENU + assert(menu) + + -- the main menu + local main = menu.main + assert(main) + + -- print title + if menu.title then + print(menu.title) + end + + -- print copyright + if menu.copyright then + print(menu.copyright) + end + + -- print usage + if main.usage then + print("") + print("Usage: " .. main.usage) + end + + -- print description + if main.description then + print("") + print(main.description) + end + + -- print actions + if main.actions then + + -- print header + print("") + print("Actions: ") + + -- the padding spaces + local padding = 42 + + -- print actions + for _, action in ipairs(main.actions) do + + -- the action menu + local action_menu = menu[action] + + -- init the action info + local action_info = " " + if action_menu and action_menu.shortname then + action_info = action_info .. action_menu.shortname .. ", " + else + action_info = action_info .. " " + end + + -- append the action + action_info = action_info .. action + + if action_menu then + -- append spaces + for i = (#action_info), padding do + action_info = action_info .. " " + end + + -- append the action description + if action_menu.description then + action_info = action_info .. action_menu.description + end + end + + -- print action info + print(action_info) + end + end + + -- print options + if main.options then + option.print_options(main.options) + end +end + +-- print the options menu +function option.print_options(options) + + -- check + assert(options) + + -- print header + print("") + print("Options: ") + + -- the padding spaces + local padding = 42 + + -- print options + for _, option in ipairs(options) do + + -- init the option info + local option_info = "" + + -- append the shortname + local shortname = option[1]; + local name = option[2]; + local mode = option[3]; + if shortname then + option_info = option_info .. " -" .. shortname + if mode == "kv" then + option_info = option_info .. " " .. utils.ifelse(name, name:upper(), "XXX") + end + end + + -- append the name + if name then + if mode == "v" then + option_info = option_info .. " " .. name + else + option_info = option_info .. utils.ifelse(shortname, ", --", " --") .. name + end + if mode == "kv" then + option_info = option_info .. "=" .. name:upper() + end + elseif mode == "v" then + option_info = option_info .. " ..." + end + + -- append spaces + for i = (#option_info), padding do + option_info = option_info .. " " + end + + -- append the option description + local description = option[5] + if description then + option_info = option_info .. description + end + + -- append the default value + local default = option[4] + if default then + option_info = option_info .. " (default: " .. tostring(default) .. ")" + end + + -- print option info + print(option_info) + + -- print more description if exists + for i = 6, 64 do + + -- the description, @note some option may be nil + local description = option[i] + if not description then break end + + -- is function? get results + if type(description) == "function" then + description = description() + end + + -- the description is string? + if type(description) == "string" then + + -- make spaces + local spaces = "" + for i = 0, padding do + spaces = spaces .. " " + end + + -- print this description + print(spaces .. description) + + -- the description is table? + elseif type(description) == "table" then + + -- print all descriptions + for _, v in pairs(description) do + + -- make spaces + local spaces = "" + for i = 0, padding do + spaces = spaces .. " " + end + + -- print this description + print(spaces .. v) + end + end + end + end +end + +-- return module: option +return option diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua new file mode 100644 index 000000000..b08ac3820 --- /dev/null +++ b/xmake/core/base/os.lua @@ -0,0 +1,237 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file os.lua +-- + +-- define module: os +local os = os or {} + +-- load modules +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") + +-- match files or directories +-- +-- @param pattern the search pattern +-- uses "*" to match any part of a file or directory name, +-- uses "**" to recurse into subdirectories. +-- +-- @param findir true: find directory, false: find file +-- @return the result array and count +-- +-- @code +-- local dirs, count = os.match("./src/*", true) +-- local files, count = os.match("./src/**.c") +-- local file = os.match("./src/test.c") +-- @endcode +-- +function os.match(pattern, findir) + + -- get the excludes + local excludes = pattern:match("|.*$") + if excludes then excludes = excludes:split("|") end + + -- translate excludes + if excludes then + local _excludes = {} + for _, exclude in ipairs(excludes) do + exclude = path.translate(exclude) + exclude = exclude:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") + exclude = exclude:gsub("%*%*", "\001") + exclude = exclude:gsub("%*", "\002") + exclude = exclude:gsub("\001", ".*") + exclude = exclude:gsub("\002", "[^/]*") + table.insert(_excludes, exclude) + end + excludes = _excludes + end + + -- translate path and remove some repeat separators + pattern = path.translate(pattern:gsub("|.*$", "")) + + -- get the root directory + local rootdir = pattern + local starpos = pattern:find("%*") + if starpos then + rootdir = rootdir:sub(1, starpos - 1) + end + rootdir = path.directory(rootdir) + + -- is recurse? + local recurse = pattern:find("**", nil, true) + + -- convert pattern to a lua pattern + pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") + pattern = pattern:gsub("%*%*", "\001") + pattern = pattern:gsub("%*", "\002") + pattern = pattern:gsub("\001", ".*") + pattern = pattern:gsub("\002", "[^/]*") + + -- patch "./" for matching ok if root directory is '.' + if rootdir == '.' then + pattern = "./" .. pattern + end + + -- find it + return os.find(rootdir, pattern, recurse, findir, excludes) +end + +-- copy file or directory +function os.cp(src, dst) + + -- check + assert(src and dst) + + -- is file? + if os.isfile(src) then + + -- the destination is directory? append the filename + if os.isdir(dst) then + dst = string.format("%s/%s", dst, path.filename(src)) + end + + -- copy file + if not os.cpfile(src, dst) then + return false, string.format("cannot copy file %s to %s %s", src, dst, os.strerror()) + end + -- is directory? + elseif os.isdir(src) then + -- copy directory + if not os.cpdir(src, dst) then + return false, string.format("cannot copy directory %s to %s %s", src, dst, os.strerror()) + end + -- cp dir/*? + elseif src:find("%*") then + + -- get the root directory + local starpos = src:find("%*") + + -- match all files + local files = os.match((src:gsub("%*+", "**"))) + if files then + for _, file in ipairs(files) do + local dstfile = string.format("%s/%s", dst, file:sub(starpos)) + if not os.cpfile(file, dstfile) then + return false, string.format("cannot copy file %s to %s %s", file, dstfile, os.strerror()) + end + end + end + + -- not exists? + else + return false, string.format("cannot copy file %s, not found this file %s", src, os.strerror()) + end + + -- ok + return true +end + +-- move file or directory +function os.mv(src, dst) + + -- check + assert(src and dst) + + -- exists file or directory? + if os.exists(src) then + -- move file or directory + if not os.rename(src, dst) then + return false, string.format("cannot move %s to %s %s", src, dst, os.strerror()) + end + -- not exists? + else + return false, string.format("cannot move %s to %s, not found this file %s", src, dst, os.strerror()) + end + + -- ok + return true +end + +-- remove file or directory +function os.rm(file_or_dir, emptydir) + + -- check + assert(file_or_dir) + + -- is file? + if os.isfile(file_or_dir) then + -- remove file + if not os.rmfile(file_or_dir) then + return false, string.format("cannot remove file %s %s", file_or_dir, os.strerror()) + end + -- is directory? + elseif os.isdir(file_or_dir) then + -- remove directory + if not os.rmdir(file_or_dir, emptydir) then + return false, string.format("cannot remove directory %s %s", file_or_dir, os.strerror()) + end + -- not exists? + else + return false, string.format("cannot remove file %s, not found this file %s", file_or_dir, os.strerror()) + end + + -- ok + return true +end + +-- change to directory +function os.cd(dir) + + -- check + assert(dir) + + -- change to the previous directory? + if dir == "-" then + -- exists the previous directory? + if os._PREDIR then + dir = os._PREDIR + os._PREDIR = nil + else + -- error + return false, string.format("not found the previous directory %s", os.strerror()) + end + end + + -- is directory? + if os.isdir(dir) then + + -- get the current directory + local current = os.curdir() + + -- change to directory + if not os.chdir(dir) then + return false, string.format("cannot change directory %s %s", dir, os.strerror()) + end + + -- save the previous directory + os._PREDIR = current + + -- not exists? + else + return false, string.format("cannot change directory %s, not found this directory %s", dir, os.strerror()) + end + + -- ok + return true +end + +-- return module: os +return os diff --git a/xmake/core/base/package.lua b/xmake/core/base/package.lua new file mode 100644 index 000000000..ffb1a0d38 --- /dev/null +++ b/xmake/core/base/package.lua @@ -0,0 +1,314 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file package.lua +-- + +-- define module: package +local package = package or {} + +-- load modules +local os = require("base/os") +local io = require("base/io") +local rule = require("base/rule") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local platform = require("platform/platform") + +-- package target for the library file +function package._done_library(target) + + -- check + assert(target and target.name and target.archs) + + -- the output directory + local outputdir = target.outputdir + assert(outputdir) + + -- the plat and mode + local plat = config.get("plat") + local mode = config.get("mode") + assert(plat and mode) + + -- package it + for arch, info in pairs(target.archs) do + + -- check + assert(info.targetdir and info.targetfile) + + -- copy the library file to the output directory + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s.pkg/lib/%s/%s/%s/%s", outputdir, target.name, mode, plat, arch, path.filename(info.targetfile))) + if not ok then + utils.error(errors) + return -1 + end + + -- copy the config.h to the output directory + if info.config_h then + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s.pkg/inc/%s/%s", outputdir, target.name, plat, path.filename(info.config_h))) + if not ok then + utils.error(errors) + return -1 + end + end + end + + -- copy headers + if target.headers then + local srcheaders, dstheaders = rule.headerfiles(target, string.format("%s/%s.pkg/inc", outputdir, target.name)) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + local ok, errors = os.cp(srcheader, dstheader) + if not ok then + utils.error(errors) + return -1 + end + end + i = i + 1 + end + end + end + + -- make xmake.lua + local file = io.open(string.format("%s/%s.pkg/xmake.lua", outputdir, target.name), "w") + if file then + + -- the xmake.lua template content + local template = [[ +-- add [targetname] package +add_option("[targetname]") + + -- show menu + set_option_showmenu(true) + + -- set category + set_option_category("package") + + -- set description + set_option_description("The [targetname] package") + + -- set language: c99, c++11 + set_option_languages("c99", "cxx11") + + -- add defines to config.h if checking ok + add_option_defines_h_if_ok("$(prefix)_PACKAGE_HAVE_[TARGETNAME]") + + -- add links for checking + add_option_links("[targetname]") + + -- add link directories + add_option_linkdirs("lib/$(mode)/$(plat)/$(arch)") + + -- add c includes for checking + add_option_cincludes("[targetname]/[targetname].h") + + -- add include directories + add_option_includedirs("inc/$(plat)", "inc") +]] + + -- save file + file:write((template:gsub("%[targetname%]", target.name):gsub("%[TARGETNAME%]", target.name:upper()))) + + -- exit file + file:close() + end + + -- ok + return 1 +end + +-- package target for the binary file +function package._done_binary(target) + + -- check + assert(target and target.archs) + + -- the output directory + local outputdir = target.outputdir + assert(outputdir) + + -- the count of architectures + local count = 0 + for _, _ in pairs(target.archs) do count = count + 1 end + + -- package it + local ok = nil + local errors = nil + for arch, info in pairs(target.archs) do + + -- check + assert(info.targetdir and info.targetfile) + + -- copy the binary file to the output directory + if count == 1 then + ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", outputdir, path.filename(info.targetfile))) + else + ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", outputdir, rule.filename(path.basename(info.targetfile) .. "_" .. arch, "binary"))) + end + + -- ok? + if not ok then + utils.error(errors) + return -1 + end + end + + -- ok + return 1 +end + +-- package target from the default script +function package._done_from_default(target) + + -- check + assert(target.kind) + + -- the package scripts + local packagescripts = + { + static = package._done_library + , shared = package._done_library + , binary = package._done_binary + } + + -- package it + local packagescript = packagescripts[target.kind] + if packagescript then return packagescript(target) end + + -- continue + return 0 +end + +-- package target from the project script +function package._done_from_project(target) + + -- check + assert(target) + + -- package it using the project script first + local packagescript = target.packagescript + if type(packagescript) == "function" then + + -- remove it + target.packagescript = nil + + -- package it + return packagescript(target) + end + + -- continue + return 0 +end + +-- package target from the platform script +function package._done_from_platform(target) + + -- check + assert(target) + + -- the platform package script file + local packagescript = nil + local scriptfile = platform.directory() .. "/package.lua" + if os.isfile(scriptfile) then + + -- load the package script + local script, errors = loadfile(scriptfile) + if script then + packagescript = script() + if type(packagescript) == "table" and packagescript.main then + packagescript = packagescript.main + end + else + utils.error(errors) + end + end + + -- package it + if type(packagescript) == "function" then + return packagescript(target) + end + + -- continue + return 0 +end + +-- get the configure file +function package._file() + + -- get it + return config.directory() .. "/package.conf" +end + +-- package target from the given target configure +function package._done(target) + + -- check + assert(target) + + -- package it from the project script + local ok = package._done_from_project(target) + if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end + + -- package it from the platform script + local ok = package._done_from_platform(target) + if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end + + -- package it from the default script + local ok = package._done_from_default(target) + if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end + + -- ok + return true +end + +-- done package from the configure +function package.done(configs) + + -- check + assert(configs) + + -- package targets + for _, target in pairs(configs) do + + -- package it + if not package._done(target) then + -- errors + utils.error("package %s failed!", target.name) + return false + end + + end + + -- save to the configure file + return io.save(package._file(), configs) +end + +-- load the package configure +function package.load() + + -- load it + return io.load(package._file()) +end + +-- return module: package +return package diff --git a/xmake/core/base/path.lua b/xmake/core/base/path.lua new file mode 100644 index 000000000..eb35283b2 --- /dev/null +++ b/xmake/core/base/path.lua @@ -0,0 +1,72 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file path.lua +-- + +-- define module: path +local path = path or {} + +-- load modules +local string = require("base/string") + +-- get the directory of the path +function path.directory(p) + local i = p:find_last("[/\\]") + if i then + if i > 1 then i = i - 1 end + return p:sub(1, i) + else + return "." + end +end + +-- get the filename of the path +function path.filename(p) + local i = p:find_last("[/\\]") + if i then + return p:sub(i + 1) + else + return p + end +end + +-- get the basename of the path +function path.basename(p) + local name = path.filename(p) + local i = name:find_last(".", true) + if i then + return name:sub(1, i - 1) + else + return name + end +end + +-- get the file extension of the path: .xxx +function path.extension(p) + local i = p:find_last(".", true) + if i then + return p:sub(i) + else + return "" + end +end + +-- return module: path +return path diff --git a/xmake/core/base/project.lua b/xmake/core/base/project.lua new file mode 100644 index 000000000..51b46afe3 --- /dev/null +++ b/xmake/core/base/project.lua @@ -0,0 +1,1469 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file project.lua +-- + +-- define module: project +local project = project or {} + +-- load modules +local os = require("base/os") +local io = require("base/io") +local rule = require("base/rule") +local path = require("base/path") +local utils = require("base/utils") +local table = require("base/table") +local config = require("base/config") +local linker = require("base/linker") +local compiler = require("base/compiler") +local platform = require("platform/platform") + +-- import module +function project._api_import(env, module) + + -- import + return require("module/" .. module) +end + +-- the current os is belong to the given os? +function project._api_os(env, ...) + + -- get the current os + local os = platform.os() + if not os then return false end + + -- exists this os? + for _, o in ipairs(table.join(...)) do + if o and type(o) == "string" and o == os then + return true + end + end +end + +-- the current mode is belong to the given modes? +function project._api_modes(env, ...) + + -- get the current mode + local mode = config.get("mode") + if not mode then return false end + + -- exists this mode? + for _, m in ipairs(table.join(...)) do + if m and type(m) == "string" and m == mode then + return true + end + end +end + +-- the current platform is belong to the given platforms? +function project._api_plats(env, ...) + + -- get the current platform + local plat = config.get("plat") + if not plat then return false end + + -- exists this platform? and escape '-' + for _, p in ipairs(table.join(...)) do + if p and type(p) == "string" and plat:find(p:gsub("%-", "%%-")) then + return true + end + end +end + +-- the current platform is belong to the given architectures? +function project._api_archs(env, ...) + + -- get the current architecture + local arch = config.get("arch") + if not arch then return false end + + -- exists this architecture? and escape '-' + for _, a in ipairs(table.join(...)) do + if a and type(a) == "string" and arch:find(a:gsub("%-", "%%-")) then + return true + end + end +end + +-- the current kind is belong to the given kinds? +function project._api_kinds(env, ...) + + -- get the current kind + local kind = config.get("kind") + if not kind then return false end + + -- exists this kind? + for _, k in ipairs(table.join(...)) do + if k and type(k) == "string" and k == kind then + return true + end + end +end + +-- enable options? +function project._api_options(env, ...) + + -- some options are enabled? + for _, o in ipairs(table.join(...)) do + if o and type(o) == "string" and config.get(o) then + return true + end + end +end + +-- get all pathes and translate it +function project._api_get_pathes(...) + + -- check + assert(project._CURDIR) + + -- get all pathes + local pathes = table.join(...) + + -- translate the relative path + local results = {} + for _, p in ipairs(pathes) do + if not p:find("^%s-%$%(.-%)") and not path.is_absolute(p) then + table.insert(results, path.relative(path.absolute(p, project._CURDIR), project._PROJECT_DIR)) + else + table.insert(results, p) + end + end + + -- ok? + return results +end + +-- add c function +function project._api_add_cfunc(env, module, alias, links, includes, cfunc) + + -- check + assert(env and cfunc) + + -- make the option name + local name = nil + if module ~= nil then + name = string.format("__%s_%s", module, cfunc) + else + name = string.format("__%s", cfunc) + end + + -- make the option define + local define = nil + if module ~= nil then + define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), utils.ifelse(alias, alias, cfunc:upper())) + else + define = string.format("$(prefix)_HAVE_%s", utils.ifelse(alias, alias, cfunc:upper())) + end + + -- make option + env.add_option(name) + env.set_option_category("cfuncs") + env.add_option_cfuncs(cfunc) + if links then env.add_option_links(links) end + if includes then env.add_option_cincludes(includes) end + env.add_option_defines_h_if_ok(define) + + -- add this option + env.add_options(name) +end + +-- add c functions +function project._api_add_cfuncs(env, module, links, includes, ...) + + -- check + assert(env) + + -- done + for _, cfunc in ipairs({...}) do + + -- check + assert(cfunc) + + -- make the option name + local name = nil + if module ~= nil then + name = string.format("__%s_%s", module, cfunc) + else + name = string.format("__%s", cfunc) + end + + -- make the option define + local define = nil + if module ~= nil then + define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), cfunc:upper()) + else + define = string.format("$(prefix)_HAVE_%s", cfunc:upper()) + end + + -- make option + env.add_option(name) + env.set_option_category("cfuncs") + env.add_option_cfuncs(cfunc) + if links then env.add_option_links(links) end + if includes then env.add_option_cincludes(includes) end + env.add_option_defines_h_if_ok(define) + + -- add this option + env.add_options(name) + end +end + +-- add c++ function +function project._api_add_cxxfunc(env, module, alias, links, includes, cxxfunc) + + -- check + assert(env and cxxfunc) + + -- make the option name + local name = nil + if module ~= nil then + name = string.format("__%s_%s", module, cxxfunc) + else + name = string.format("__%s", cxxfunc) + end + + -- make the option define + local define = nil + if module ~= nil then + define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), utils.ifelse(alias, alias, cxxfunc:upper())) + else + define = string.format("$(prefix)_HAVE_%s", utils.ifelse(alias, alias, cxxfunc:upper())) + end + + -- make option + env.add_option(name) + env.set_option_category("cxxfuncs") + env.add_option_cxxfuncs(cxxfunc) + if links then env.add_option_links(links) end + if includes then env.add_option_cxxincludes(includes) end + env.add_option_defines_h_if_ok(define) + + -- add this option + env.add_options(name) +end + +-- add c++ functions +function project._api_add_cxxfuncs(env, module, links, includes, ...) + + -- check + assert(env and module) + + -- done + for _, cxxfunc in ipairs({...}) do + + -- check + assert(cxxfunc) + + -- make the option name + local name = nil + if module ~= nil then + name = string.format("__%s_%s", module, cxxfunc) + else + name = string.format("__%s", cxxfunc) + end + + -- make the option define + local define = nil + if module ~= nil then + define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), cxxfunc:upper()) + else + define = string.format("$(prefix)_HAVE_%s", cxxfunc:upper()) + end + + -- make option + env.add_option(name) + env.set_option_category("cxxfuncs") + env.add_option_cxxfuncs(cxxfunc) + if links then env.add_option_links(links) end + if includes then env.add_option_cxxincludes(includes) end + env.add_option_defines_h_if_ok(define) + + -- add this option + env.add_options(name) + end +end + +-- add target +function project._api_add_target(env, name) + + -- check + assert(env and name) + + -- the targets + local targets = env._CONFIGS._TARGETS + assert(targets) + + -- init the target scope + targets[name] = targets[name] or {} + + -- switch to this target scope + env._TARGET = targets[name] +end + +-- add option +function project._api_add_option(env, name) + + -- check + assert(env and name) + + -- the options + local options = env._CONFIGS._OPTIONS + assert(options) + + -- init the option scope + options[name] = options[name] or {} + + -- switch to this option scope + env._OPTION = options[name] +end + +-- load all subprojects from the given directories +function project._api_add_subdirs(env, ...) + + -- check + assert(env) + + -- init mtime for files + project._MTIMES = project._MTIMES or {} + + -- save the current project file directory + local curdir = project._CURDIR + + -- get all subdirs + local subdirs = project._api_get_pathes(...) + + -- match all subdirs + local subdirs_matched = {} + for _, subdir in ipairs(subdirs) do + local dirs = os.match(subdir, true) + if dirs then table.join2(subdirs_matched, dirs) end + end + + -- done + for _, subdir in ipairs(subdirs_matched) do + if subdir and type(subdir) == "string" then + + -- the project file + local file = subdir .. "/xmake.lua" + if not path.is_absolute(file) then + file = path.absolute(file, xmake._PROJECT_DIR) + end + + -- update the current project file directory + project._CURDIR = path.directory(file) + + -- load the project script + local script = loadfile(file) + if script then + + -- bind environment + setfenv(script, env) + + -- done the project script + local ok, errors = pcall(script) + if not ok then + utils.error(errors) + assert(false) + end + + -- get mtime of the file + project._MTIMES[path.relative(file, xmake._PROJECT_DIR)] = os.mtime(file) + end + end + end + + -- restore the current project file directory + project._CURDIR = curdir + +end + +-- load all subprojects from the given files +function project._api_add_subfiles(env, ...) + + -- check + assert(env) + + -- init mtime for files + project._MTIMES = project._MTIMES or {} + + -- save the current project file directory + local curdir = project._CURDIR + + -- get all subfiles + local subfiles = project._api_get_pathes(...) + + -- match all subfiles + local subfiles_matched = {} + for _, subfile in ipairs(subfiles) do + local files = os.match(subfile) + if files then table.join2(subfiles_matched, files) end + end + + -- done + for _, file in ipairs(subfiles_matched) do + if file and type(file) == "string" then + + -- the project file + if not path.is_absolute(file) then + file = path.absolute(file, xmake._PROJECT_DIR) + end + + -- update the current project file directory + project._CURDIR = path.directory(file) + + -- load the project script + local script = loadfile(file) + if script then + + -- bind environment + setfenv(script, env) + + -- done the project script + local ok, errors = pcall(script) + if not ok then + utils.error(errors) + assert(false) + end + + -- get mtime of the file + project._MTIMES[path.relative(file, xmake._PROJECT_DIR)] = os.mtime(file) + end + end + end + + -- restore the current project file directory + project._CURDIR = curdir +end + +-- load all packages from the given directories +function project._api_add_pkgdirs(env, ...) + + -- get all directories + local pkgdirs = {} + local dirs = table.join(...) + for _, dir in ipairs(dirs) do + table.insert(pkgdirs, dir .. "/*.pkg") + end + + -- add all packages + project._api_add_subdirs(env, pkgdirs) +end + +-- set configure values +function project._api_set_values(scope, name, ...) + + -- check + assert(scope and name) + + -- update values + scope[name] = {} + table.join2(scope[name], ...) +end + +-- add configure values +function project._api_add_values(scope, name, ...) + + -- check + assert(scope and name) + + -- append values + scope[name] = scope[name] or {} + table.join2(scope[name], ...) +end + +-- set configure pathes +function project._api_set_pathes(scope, name, ...) + + -- check + assert(scope and name) + + -- update pathes + scope[name] = {} + table.join2(scope[name], project._api_get_pathes(...)) +end + +-- add configure pathes +function project._api_add_pathes(scope, name, ...) + + -- check + assert(scope and name) + + -- append pathes + scope[name] = scope[name] or {} + table.join2(scope[name], project._api_get_pathes(...)) +end + +-- filter the configure value +function project._filter(values) + + -- check + assert(values) + + -- filter all + local newvals = {} + for _, v in ipairs(utils.wrap(values)) do + if type(v) == "string" then + v = v:gsub("%$%((.-)%)", function (w) + + -- is upper? + local isupper = false + local c = string.char(w:byte()) + if c >= 'A' and c <= 'Z' then isupper = true end + + -- attempt to get it directly from the configure + local r = config.get(w) + if not r or type(r) ~= "string" then + + -- attempt to get it from the configure and the lower key + w = w:lower() + r = config.get(w) + if not r or type(r) ~= "string" then + + -- get the other keys + if w == "projectdir" then r = xmake._PROJECT_DIR + elseif w == "os" then r = platform.os() + end + end + end + + -- upper? + if r and type(r) == "string" and isupper then + r = r:upper() + end + + -- ok? + return r + end) + end + table.insert(newvals, v) + end + + -- ok? + return newvals +end + +-- make configure for the given target_name +function project._makeconf_for_target(target_name, target) + + -- check + assert(target_name and target) + + -- get the target configure file + local config_h = target.config_h + if not config_h then + return true + end + + -- translate file path + if not path.is_absolute(config_h) then + config_h = path.absolute(config_h, xmake._PROJECT_DIR) + else + config_h = path.translate(config_h) + end + + -- the prefix + local prefix = target.config_h_prefix or (target_name:upper() .. "_CONFIG") + + -- open the file + local file = project._CONFILES[config_h] or io.openmk(config_h) + assert(file) + + -- make the head + if project._CONFILES[config_h] then file:write("\n") end + file:write(string.format("#ifndef %s_H\n", prefix)) + file:write(string.format("#define %s_H\n", prefix)) + file:write("\n") + + -- make version + if target.version then + file:write("// version\n") + file:write(string.format("#define %s_VERSION \"%s\"\n", prefix, target.version)) + local i = 1 + local m = {"MAJOR", "MINOR", "ALTER"} + for v in target.version:gmatch("%d+") do + file:write(string.format("#define %s_VERSION_%s %s\n", prefix, m[i], v)) + i = i + 1 + if i > 3 then break end + end + file:write(string.format("#define %s_VERSION_BUILD %s\n", prefix, os.date("%Y%m%d%H%M", os.time()))) + file:write("\n") + end + + -- make the defines + local defines = {} + if target.defines_h then table.join2(defines, target.defines_h) end + + -- make the undefines + local undefines = {} + if target.undefines_h then table.join2(undefines, target.undefines_h) end + + -- the options + if target.options then + for _, name in ipairs(utils.wrap(target.options)) do + + -- get option if be enabled + local opt = nil + if config.get(name) then opt = config.get("__" .. name) end + if nil ~= opt then + + -- get the option defines + if opt.defines_h_if_ok then table.join2(defines, opt.defines_h_if_ok) end + + -- get the option undefines + if opt.undefines_h_if_ok then table.join2(undefines, opt.undefines_h_if_ok) end + + end + end + end + + -- make the defines + if #defines ~= 0 then + file:write("// defines\n") + for _, define in ipairs(defines) do + file:write(string.format("#define %s 1\n", define:gsub("=", " "):gsub("%$%((.-)%)", function (w) if w == "prefix" then return prefix end end))) + end + file:write("\n") + end + + -- make the undefines + if #undefines ~= 0 then + file:write("// undefines\n") + for _, undefine in ipairs(undefines) do + file:write(string.format("#undef %s\n", undefine:gsub("%$%((.-)%)", function (w) if w == "prefix" then return prefix end end))) + end + file:write("\n") + end + + -- make the tail + file:write("#endif\n") + + -- cache the file + project._CONFILES[config_h] = file + + -- ok + return true +end + +-- make the configure file for the given target and dependents +function project._makeconf_for_target_and_deps(target_name) + + -- the targets + local targets = project.targets() + assert(targets) + + -- the target + local target = targets[target_name] + assert(target) + + -- make configure for the target + if not project._makeconf_for_target(target_name, target) then + return false + end + + -- exists the dependent targets? + if target.deps then + local deps = utils.wrap(target.deps) + for _, dep in ipairs(deps) do + if not project._makeconf_for_target_and_deps(dep) then return false end + end + end + + -- ok + return true +end + +-- make targets from the project file +function project._make_targets(configs) + + -- check + assert(configs and configs._TARGETS) + + -- init + project._TARGETS = project._TARGETS or {} + local targets = project._TARGETS + + -- make all targets + for k, v in pairs(configs._TARGETS) do + targets[k] = v + end + + -- merge the root configures to all targets + for _, target in pairs(targets) do + + -- merge the setted configures + for k, v in pairs(configs._SET) do + if nil == target[k] then + target[k] = v + end + end + + -- merge the added configures + for k, v in pairs(configs._ADD) do + if nil == target[k] then + target[k] = v + else + target[k] = table.join(v, target[k]) + end + end + + -- remove repeat values and unwrap it + for k, v in pairs(target) do + + -- remove repeat first + v = utils.unique(v) + + -- filter values + v = project._filter(v) + + -- unwrap it if be only one + v = utils.unwrap(v) + + -- update it + target[k] = v + end + end + + -- init mtime for the project file + project._MTIMES = project._MTIMES or {} + project._MTIMES[path.relative(xmake._PROJECT_FILE, xmake._PROJECT_DIR)] = os.mtime(xmake._PROJECT_FILE) + + -- get the mtimes for configure + local mtimes_config = config.get("__mtimes") + if mtimes_config then + + -- check for all project files and we need reconfig and rebuild it if them have been modified + for file, mtime in pairs(project._MTIMES) do + + -- modified? reconfig and rebuild it + local mtime_old = mtimes_config[file] + if not mtime_old or mtime > mtime_old then + config._RECONFIG = true + config.set("__rebuild", true) + break + end + end + end + + -- update mtimes + config.set("__mtimes", project._MTIMES) + + -- reconfig it? we need reprobe it + if config._RECONFIG then + project.probe() + config.clearup() + end +end + +-- make option for checking links +function project._make_option_for_checking_links(opt, links, cfile, objectfile, targetfile) + + -- the links string + local links_str = table.concat(utils.wrap(links), ", ") + + -- this links has been checked? + project._CHECKED_LINKS = project._CHECKED_LINKS or {} + if project._CHECKED_LINKS[links_str] then return true end + + -- only for compile a object file + local ok = compiler.check_include(opt, nil, cfile, objectfile) + + -- check link + if ok then ok = linker.check_links(opt, links, cfile, objectfile, targetfile) end + + -- trace + utils.printf("checking for the links %s ... %s", links_str, utils.ifelse(ok, "ok", "no")) + + -- cache the result + project._CHECKED_LINKS[links_str] = ok + + -- ok? + return ok +end + +-- make option for checking cincludes +function project._make_option_for_checking_cincludes(opt, cincludes, cfile, objectfile) + + -- done + for _, cinclude in ipairs(utils.wrap(cincludes)) do + + -- this cinclude has been checked? + project._CHECKED_CINCLUDES = project._CHECKED_CINCLUDES or {} + if project._CHECKED_CINCLUDES[cinclude] then return true end + + -- check cinclude + local ok = compiler.check_include(opt, cinclude, cfile, objectfile) + + -- trace + utils.printf("checking for the c include %s ... %s", cinclude, utils.ifelse(ok, "ok", "no")) + + -- cache the result + project._CHECKED_CINCLUDES[cinclude] = ok + + -- failed + if not ok then return false end + end + + -- ok + return true +end + +-- make option for checking cxxincludes +function project._make_option_for_checking_cxxincludes(opt, cxxincludes, cxxfile, objectfile) + + -- done + for _, cxxinclude in ipairs(utils.wrap(cxxincludes)) do + + -- this cxxinclude has been checked? + project._CHECKED_CXXINCLUDES = project._CHECKED_CXXINCLUDES or {} + if project._CHECKED_CXXINCLUDES[cinclude] then return true end + + -- check cinclude + local ok = compiler.check_include(opt, cxxinclude, cxxfile, objectfile) + + -- trace + utils.printf("checking for the c++ include %s ... %s", cxxinclude, utils.ifelse(ok, "ok", "no")) + + -- cache the result + project._CHECKED_CXXINCLUDES[cxxinclude] = ok + + -- failed + if not ok then return false end + end + + -- ok + return true +end + +-- make option for checking cfunctions +function project._make_option_for_checking_cfuncs(opt, cfuncs, cfile, objectfile, targetfile) + + -- done + for _, cfunc in ipairs(utils.wrap(cfuncs)) do + + -- check function + local ok = compiler.check_function(opt, cfunc, cfile, objectfile) + + -- check link + if ok and opt.links then ok = linker.check_links(opt, opt.links, cfile, objectfile, targetfile) end + + -- trace + utils.printf("checking for the c function %s ... %s", cfunc, utils.ifelse(ok, "ok", "no")) + + -- failed + if not ok then return false end + end + + -- ok + return true +end + +-- make option for checking cxxfunctions +function project._make_option_for_checking_cxxfuncs(opt, cxxfuncs, cxxfile, objectfile, targetfile) + + -- done + for _, cxxfunc in ipairs(utils.wrap(cxxfuncs)) do + + -- check function + local ok = compiler.check_function(opt, cxxfunc, cxxfile, objectfile) + + -- check link + if ok and opt.links then ok = linker.check_links(opt, opt.links, cxxfile, objectfile, targetfile) end + + -- trace + utils.printf("checking for the c++ function %s ... %s", cxxfunc, utils.ifelse(ok, "ok", "no")) + + -- failed + if not ok then return false end + end + + -- ok + return true +end + +-- make option for checking ctypes +function project._make_option_for_checking_ctypes(opt, ctypes, cfile, objectfile, targetfile) + + -- done + for _, ctype in ipairs(utils.wrap(ctypes)) do + + -- check type + local ok = compiler.check_typedef(opt, ctype, cfile, objectfile) + + -- trace + utils.printf("checking for the c type %s ... %s", ctype, utils.ifelse(ok, "ok", "no")) + + -- failed + if not ok then return false end + end + + -- ok + return true +end + +-- make option for checking cxxtypes +function project._make_option_for_checking_cxxtypes(opt, cxxtypes, cxxfile, objectfile, targetfile) + + -- done + for _, cxxtype in ipairs(utils.wrap(cxxtypes)) do + + -- check type + local ok = compiler.check_typedef(opt, cxxtype, cxxfile, objectfile) + + -- trace + utils.printf("checking for the c++ type %s ... %s", cxxtype, utils.ifelse(ok, "ok", "no")) + + -- failed + if not ok then return false end + end + + -- ok + return true +end + +-- make option +function project._make_option(name, opt, cfile, cxxfile, objectfile, targetfile) + + -- remove repeat values and unwrap it + for k, v in pairs(opt) do + + -- remove repeat first + v = utils.unique(v) + + -- filter values + v = project._filter(v) + + -- unwrap it if be only one + v = utils.unwrap(v) + + -- update it + opt[k] = v + end + + -- check links + if opt.links and not project._make_option_for_checking_links(opt, opt.links, cfile, objectfile, targetfile) then return end + + -- check ctypes + if opt.ctypes and not project._make_option_for_checking_ctypes(opt, opt.ctypes, cfile, objectfile, targetfile) then return end + + -- check cxxtypes + if opt.cxxtypes and not project._make_option_for_checking_cxxtypes(opt, opt.cxxtypes, cxxfile, objectfile, targetfile) then return end + + -- check includes and functions + if opt.cincludes or opt.cxxincludes then + + -- check cincludes + if opt.cincludes and not project._make_option_for_checking_cincludes(opt, opt.cincludes, cfile, objectfile) then return end + + -- check cxxincludes + if opt.cxxincludes and not project._make_option_for_checking_cxxincludes(opt, opt.cxxincludes, cxxfile, objectfile) then return end + + -- check cfuncs + if opt.cfuncs and not project._make_option_for_checking_cfuncs(opt, opt.cfuncs, cfile, objectfile, targetfile) then return end + + -- check cxxfuncs + if opt.cxxfuncs and not project._make_option_for_checking_cxxfuncs(opt, opt.cxxfuncs, cxxfile, objectfile, targetfile) then return end + + end + + -- ok + return opt +end + +-- make options from the project file +function project._make_options(configs) + + -- check + assert(configs and configs._OPTIONS) + + -- the source file path + local cfile = os.tmpdir() .. "/__checking.c" + local cxxfile = os.tmpdir() .. "/__checking.cpp" + + -- the object file path + local objectfile = os.tmpdir() .. "/" .. rule.filename("__checking", "object") + + -- the target file path + local targetfile = os.tmpdir() .. "/" .. rule.filename("__checking", "binary") + + -- make all options + for k, v in pairs(configs._OPTIONS) do + + -- this option need be probed automatically? + if config.auto(k) then + + -- make option + local o = project._make_option(k, v, cfile, cxxfile, objectfile, targetfile) + if o then + + -- enable this option + config.set(k, true) + + -- save this option to configure + config.set("__" .. k, o) + + else + + -- disable this option + config.set(k, false) + + -- clear this option to configure + config.set("__" .. k, nil) + + end + + elseif nil == config.get("__" .. k) then + + -- save this option to configure + config.set("__" .. k, v) + end + end + + -- remove files + os.rm(cfile) + os.rm(cxxfile) + os.rm(objectfile) + os.rm(targetfile) + +end + +-- only load options from the the project file +function project._load_options(file) + + -- check + assert(file) + + -- load the project script + local script = loadfile(file) + if not script then + return string.format("load %s failed!", file) + end + + -- set the current project file directory + project._CURDIR = path.directory(file) + + -- bind the new environment + local newenv = {_CONFIGS = {_OPTIONS = {}}} + setmetatable(newenv, {__index = function(tbl, key) + local val = rawget(tbl, key) + if nil == val then val = rawget(_G, key) end + if nil == val then return function(...) end end + return val + end}) + setfenv(script, newenv) + + -- register import + newenv.import = function (module) return project._api_import(newenv, module) end + + -- register interfaces for the condition + newenv.os = function (...) return project._api_os(newenv, ...) end + newenv.kinds = function (...) return project._api_kinds(newenv, ...) end + newenv.modes = function (...) return project._api_modes(newenv, ...) end + newenv.plats = function (...) return project._api_plats(newenv, ...) end + newenv.archs = function (...) return project._api_archs(newenv, ...) end + + -- register interfaces for the option + newenv.set_option = function (...) return project._api_add_option(newenv, ...) end + newenv.add_option = function (...) return project._api_add_option(newenv, ...) end + + -- register interfaces for the subproject files + newenv.add_subdirs = function (...) return project._api_add_subdirs(newenv, ...) end + newenv.add_subfiles = function (...) return project._api_add_subfiles(newenv, ...) end + + -- register interfaces for the functions + newenv.add_cfunc = function (...) return project._api_add_cfunc(newenv, ...) end + newenv.add_cfuncs = function (...) return project._api_add_cfuncs(newenv, ...) end + newenv.add_cxxfunc = function (...) return project._api_add_cxxfunc(newenv, ...) end + newenv.add_cxxfuncs = function (...) return project._api_add_cxxfuncs(newenv, ...) end + + -- register interfaces for the package files + newenv.add_pkgdirs = function (...) return project._api_add_pkgdirs(newenv, ...) end + newenv.add_pkgs = function (...) return project._api_add_subdirs(newenv, ...) end + + -- register interfaces for setting option values + local interfaces = { "enable" + , "showmenu" + , "category" + , "warnings" + , "optimize" + , "languages" + , "description"} + + for _, interface in ipairs(interfaces) do + newenv["set_option_" .. interface] = function (...) return project._api_set_values(newenv._OPTION, interface, ...) end + end + + -- register interfaces for adding option values + interfaces = { "links" + , "cincludes" + , "cxxincludes" + , "cfuncs" + , "cxxfuncs" + , "ctypes" + , "cxxtypes" + , "cflags" + , "cxflags" + , "cxxflags" + , "ldflags" + , "vectorexts" + , "defines" + , "defines_if_ok" + , "defines_h_if_ok" + , "undefines" + , "undefines_if_ok" + , "undefines_h_if_ok"} + + for _, interface in ipairs(interfaces) do + newenv["add_option_" .. interface] = function (...) return project._api_add_values(newenv._OPTION, interface, ...) end + end + + -- register interfaces for adding option pathes + interfaces = { "linkdirs" + , "includedirs"} + + for _, interface in ipairs(interfaces) do + newenv["add_option_" .. interface] = function (...) return project._api_add_pathes(newenv._OPTION, interface, ...) end + end + + -- done the project script + local ok, errors = pcall(script) + if not ok then + return nil, errors + end + + -- get the project configure + return newenv._CONFIGS +end + +-- only load targets from the project file +function project._load_targets(file) + + -- check + assert(file) + + -- load the project script + local script = loadfile(file) + if not script then + return string.format("load %s failed!", file) + end + + -- set the current project file directory + project._CURDIR = path.directory(file) + + -- bind the new environment + local newenv = {_CONFIGS = {_SET = {}, _ADD = {}, _TARGETS = {}}} + setmetatable(newenv, {__index = function(tbl, key) + local val = rawget(tbl, key) + if nil == val then val = rawget(_G, key) end + if nil == val and type(key) == "string" and (key:startswith("add_option") or key:startswith("set_option")) then + return function(...) end + end + return val + end}) + setfenv(script, newenv) + + -- register import + newenv.import = function (module) return project._api_import(newenv, module) end + + -- register interfaces for the condition + newenv.os = function (...) return project._api_os(newenv, ...) end + newenv.kinds = function (...) return project._api_kinds(newenv, ...) end + newenv.modes = function (...) return project._api_modes(newenv, ...) end + newenv.plats = function (...) return project._api_plats(newenv, ...) end + newenv.archs = function (...) return project._api_archs(newenv, ...) end + newenv.options = function (...) return project._api_options(newenv, ...) end + + -- register interfaces for the target + newenv.set_target = function (...) return project._api_add_target(newenv, ...) end + newenv.add_target = function (...) return project._api_add_target(newenv, ...) end + + -- register interfaces for the subproject files + newenv.add_subdirs = function (...) return project._api_add_subdirs(newenv, ...) end + newenv.add_subfiles = function (...) return project._api_add_subfiles(newenv, ...) end + + -- register interfaces for the functions + newenv.add_cfunc = function (...) return project._api_add_cfunc(newenv, ...) end + newenv.add_cfuncs = function (...) return project._api_add_cfuncs(newenv, ...) end + newenv.add_cxxfunc = function (...) return project._api_add_cxxfunc(newenv, ...) end + newenv.add_cxxfuncs = function (...) return project._api_add_cxxfuncs(newenv, ...) end + + -- register interfaces for the package files + newenv.add_pkgdirs = function (...) return project._api_add_pkgdirs(newenv, ...) end + newenv.add_pkgs = function (...) return project._api_add_subdirs(newenv, ...) end + + -- register interfaces for setting values + local interfaces = { "kind" + , "config_h_prefix" + , "version" + , "strip" + , "options" + , "symbols" + , "warnings" + , "optimize" + , "languages" + , "runscript" + , "installscript" + , "packagescript"} + + for _, interface in ipairs(interfaces) do + newenv["set_" .. interface] = function (...) return project._api_set_values(newenv._TARGET or newenv._CONFIGS._SET, interface, ...) end + end + + -- register interfaces for setting pathes + local interfaces = { "headerdir" + , "targetdir" + , "objectdir" + , "config_h"} + + for _, interface in ipairs(interfaces) do + newenv["set_" .. interface] = function (...) return project._api_set_pathes(newenv._TARGET or newenv._CONFIGS._SET, interface, ...) end + end + + -- register interfaces for adding values + interfaces = { "deps" + , "links" + , "cflags" + , "cxflags" + , "cxxflags" + , "mflags" + , "mxflags" + , "mxxflags" + , "ldflags" + , "shflags" + , "options" + , "defines" + , "undefines" + , "defines_h" + , "undefines_h" + , "languages" + , "vectorexts"} + for _, interface in ipairs(interfaces) do + newenv["add_" .. interface] = function (...) return project._api_add_values(newenv._TARGET or newenv._CONFIGS._ADD, interface, ...) end + end + + -- register interfaces for adding pathes + interfaces = { "files" + , "headers" + , "linkdirs" + , "includedirs"} + for _, interface in ipairs(interfaces) do + newenv["add_" .. interface] = function (...) return project._api_add_pathes(newenv._TARGET or newenv._CONFIGS._ADD, interface, ...) end + end + + -- done the project script + local ok, errors = pcall(script) + if not ok then + return nil, errors + end + + -- get the project configure + return newenv._CONFIGS +end + +-- get the current configure for targets +function project.targets() + + -- check + assert(project._TARGETS) + + -- return it + return project._TARGETS +end + +-- probe the project +function project.probe() + + -- load the options from the the project file + local configs, errors = project._load_options(xmake._PROJECT_FILE) + if not configs then + return errors + end + + -- make the options from the the project file + project._make_options(configs) +end + +-- load the project +function project.load() + + -- load the targets from the the project file + local configs, errors = project._load_targets(xmake._PROJECT_FILE) + if not configs then + return errors + end + + -- make the targets from the the project file + project._make_targets(configs) +end + +-- reload the project +function project.reload() + + -- clear it first + project._MTIMES = nil + project._TARGETS = nil + project._CONFILES = nil + project._CURDIR = nil + + -- load it + return project.load() +end + +-- dump the current configure +function project.dump() + + -- check + assert(project._TARGETS) + + -- dump + if xmake._OPTIONS.verbose then + utils.dump(project._TARGETS) + end + +end + +-- make the configure file for the given target +function project.makeconf(target_name) + + -- init files + project._CONFILES = project._CONFILES or {} + + -- the target name + if target_name and target_name ~= "all" then + -- make configure for the target and dependents + if not project._makeconf_for_target_and_deps(target_name) then return false end + else + + -- the targets + local targets = project.targets() + assert(targets) + + -- make configure for the targets + for target_name, target in pairs(targets) do + if not project._makeconf_for_target(target_name, target) then return false end + end + end + + -- exit files + for _, file in pairs(project._CONFILES) do + file:close() + end + project._CONFILES = nil + + -- ok + return true +end + +-- check target +function project.checktarget(target_name) + + -- the targets + local targets = project.targets() + + -- invalid target? + if target_name and target_name ~= "all" and targets and not targets[target_name] then + utils.error("invalid target: %s!", target_name) + return false + elseif not target_name then + utils.error("no target!") + return false + end + + -- ok + return true +end + +-- get the project menu +function project.menu() + + -- attempt to load project configure + local configs = nil + local errors = nil + local projectfile = xmake._PROJECT_FILE + if projectfile and os.isfile(projectfile) then + configs, errors = project._load_options(projectfile) + end + + -- failed? + if not configs then + if errors then utils.error(errors) end + return {} + end + + -- the options + local options = configs._OPTIONS + if not options then return {} end + + -- arrange options by category + local options_by_category = {} + for name, opt in pairs(options) do + + -- make the category + local category = "default" + if opt.category then category = utils.unwrap(opt.category) end + options_by_category[category] = options_by_category[category] or {} + + -- append option to the current category + options_by_category[category][name] = opt + end + + -- make menu by category + local menu = {} + for k, opts in pairs(options_by_category) do + + -- insert options + local first = true + for name, opt in pairs(opts) do + + -- show menu? + if opt.showmenu then + + -- the default value + local default = "auto" + if opt.enable ~= nil then + default = utils.unwrap(opt.enable) + end + + -- is first? + if first then + + -- insert a separator + table.insert(menu, {}) + + -- not first + first = false + end + + -- append it + if opt.description then + table.insert(menu, {nil, name, "kv", default, utils.unwrap(opt.description)}) + else + table.insert(menu, {nil, name, "kv", default, nil}) + end + end + end + end + + -- ok? + return menu +end + +-- return module: project +return project diff --git a/xmake/core/base/rule.lua b/xmake/core/base/rule.lua new file mode 100644 index 000000000..b3dc1825c --- /dev/null +++ b/xmake/core/base/rule.lua @@ -0,0 +1,300 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file rule.lua +-- + +-- define module: rule +local rule = rule or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local table = require("base/table") +local utils = require("base/utils") +local config = require("base/config") +local platform = require("platform/platform") + +-- get the building log file path +function rule.logfile() + + -- the logdir + local logdir = config.get("buildir") or os.tmpdir() + assert(logdir) + + -- get it + return path.translate(logdir .. "/.build.log") +end + +-- get the filename from the given name and kind +function rule.filename(name, kind) + + -- check + assert(name and kind) + + -- get format + local format = platform.format(kind) or {"", ""} + + -- make it + return format[1] .. name .. format[2] +end + +-- get the makefile path +function rule.makefile() + + -- get the build directory + local buildir = config.get("buildir") + assert(buildir) + + -- get it + return path.translate(buildir .. "/makefile") +end + +-- get configure file for the given target +function rule.config_h(target) + + -- get the target configure file + local config_h = target.config_h + if config_h then + -- translate file path + if not path.is_absolute(config_h) then + config_h = path.absolute(config_h, xmake._PROJECT_DIR) + else + config_h = path.translate(config_h) + end + end + + -- ok? + return config_h +end + +-- get the temporary backup directory for package +function rule.backupdir(target_name, arch) + + -- the temporary directory + local tmpdir = os.tmpdir() + assert(tmpdir) + + -- the project name + local project_name = path.basename(xmake._PROJECT_DIR) + assert(project_name) + + -- make it + return string.format("%s/.xmake/%s/pkgfiles/%s/%s", tmpdir, project_name, target_name, arch) +end + +-- get target file for the given target +function rule.targetfile(target_name, target, buildir) + + -- check + assert(target_name and target and target.kind) + + -- the target directory + local targetdir = target.targetdir or buildir or config.get("buildir") + assert(targetdir and type(targetdir) == "string") + + -- the target file name + local filename = rule.filename(target_name, target.kind) + assert(filename) + + -- make the target file path + return targetdir .. "/" .. filename +end + +-- get object files for the given source files +function rule.objectdir(target_name, target, buildir) + + -- check + assert(target_name and target) + + -- the object directory + local objectdir = target.objectdir + if not objectdir then + + -- the build directory + if not buildir then + buildir = config.get("buildir") + end + assert(buildir) + + -- make the default object directory + objectdir = buildir .. "/.objs" + end + + -- ok? + return objectdir +end + +-- get object files for the given source files +function rule.objectfiles(target_name, target, sourcefiles, buildir) + + -- check + assert(target_name and target and sourcefiles) + + -- the object directory + local objectdir = rule.objectdir(target_name, target, buildir) + assert(objectdir and type(objectdir) == "string") + + -- make object files + local i = 1 + local objectfiles = {} + for _, sourcefile in ipairs(sourcefiles) do + + -- translate: [lib]xxx*.[a|lib] => xxx/*.[o|obj] object file + sourcefile = sourcefile:gsub(rule.filename("(%w+)", "static"):gsub("%.", "%%.") .. "$", "%1/*") + + -- make object file + local objectfile = string.format("%s/%s/%s/%s", objectdir, target_name, path.directory(sourcefile), rule.filename(path.basename(sourcefile), "object")) + + -- translate path + -- + -- .e.g + -- + -- src/xxx.c + -- project/xmake.lua + -- build/.objs + -- + -- objectfile: project/build/.objs/xxxx/../../xxx.c will be out of range for objectdir + -- + -- we need replace '..' to '__' in this case + -- + objectfile = (path.translate(objectfile):gsub("%.%.", "__")) + + -- save it + objectfiles[i] = objectfile + i = i + 1 + + end + + -- ok? + return objectfiles +end + +-- get the source files from the given target +function rule.sourcefiles(target) + + -- check + assert(target) + + -- no files? + if not target.files then + return {} + end + + -- wrap files first + local targetfiles = utils.wrap(target.files) + + -- match files + local i = 1 + local sourcefiles = {} + for _, targetfile in ipairs(targetfiles) do + + -- normalize *.[o|obj] filename + targetfile = targetfile:gsub("([%w%*]+)%.obj|", rule.filename("%1|", "object")) + targetfile = targetfile:gsub("([%w%*]+)%.obj$", rule.filename("%1", "object")) + targetfile = targetfile:gsub("([%w%*]+)%.o|", rule.filename("%1|", "object")) + targetfile = targetfile:gsub("([%w%*]+)%.o$", rule.filename("%1", "object")) + + -- normalize [lib]*.[a|lib] filename + targetfile = targetfile:gsub("([%w%*]+)%.lib|", rule.filename("%1|", "static")) + targetfile = targetfile:gsub("([%w%*]+)%.lib$", rule.filename("%1", "static")) + targetfile = targetfile:gsub("lib([%w%*]+)%.a|", rule.filename("%1|", "static")) + targetfile = targetfile:gsub("lib([%w%*]+)%.a$", rule.filename("%1", "static")) + + -- match source files + local files = os.match(targetfile) + if #files == 0 then + utils.warning("cannot match add_files(\"%s\")", targetfile) + end + + -- process source files + for _, file in ipairs(files) do + + -- convert to the relative path + if path.is_absolute(file) then + file = path.relative(file, xmake._PROJECT_DIR) + end + + -- save it + sourcefiles[i] = file + i = i + 1 + + end + end + + -- remove repeat files + sourcefiles = utils.unique(sourcefiles) + + -- ok? + return sourcefiles +end + +-- get the header files from the given target +function rule.headerfiles(target, headerdir) + + -- check + assert(target) + + -- no headers? + local headers = target.headers + if not headers then return end + + -- get the headerdir + if not headerdir then headerdir = target.headerdir or config.get("buildir") end + assert(headerdir) + + -- get the source pathes and destinate pathes + local srcheaders = {} + local dstheaders = {} + for _, header in ipairs(utils.wrap(headers)) do + + -- get the root directory + local rootdir = header:gsub("%(.*%)", ""):gsub("|.*$", "") + + -- remove '(' and ')' + local srcpathes = header:gsub("[%(%)]", "") + if srcpathes then + + -- get the source pathes + srcpathes = os.match(srcpathes) + if srcpathes then + + -- add the source headers + table.join2(srcheaders, srcpathes) + + -- add the destinate headers + for _, srcpath in ipairs(srcpathes) do + + -- the header + local dstheader = path.absolute(path.relative(srcpath, rootdir), headerdir) + assert(dstheader) + + -- add it + table.insert(dstheaders, dstheader) + end + end + end + end + + -- ok? + return srcheaders, dstheaders +end + +-- return module: rule +return rule diff --git a/xmake/core/base/string.lua b/xmake/core/base/string.lua new file mode 100644 index 000000000..b4be08cfa --- /dev/null +++ b/xmake/core/base/string.lua @@ -0,0 +1,115 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file string.lua +-- + +-- define module: string +local string = string or {} + +-- find the last substring with the given pattern +function string.find_last(self, pattern, plain) + + -- find the last substring + local curr = 0 + repeat + local next = self:find(pattern, curr + 1, plain) + if next then + curr = next + end + until (not next) + + -- found? + if curr > 0 then + return curr + end +end + +-- split string with the given pattern +function string.split(self, pattern) + + -- split it + local list = {} + self:gsub("[^" .. pattern .."]+", function(v) table.insert(list, v) end ) + return list +end + +-- trim the spaces +function string.trim(self) + return (self:gsub("^%s*(.-)%s*$", "%1")) +end + +-- trim the left spaces +function string.ltrim(self) + return (self:gsub("^%s*", "")) +end + +-- trim the right spaces +function string.rtrim(self) + local n = #self + while n > 0 and s:find("^%s", n) do n = n - 1 end + return self:sub(1, n) +end + +-- append a substring with a given separator +function string.append(self, substr, separator) + + -- check + assert(self) + + -- not substr? return self + if not substr then + return self + end + + -- append it + local s = self + if #s == 0 then + s = substr + else + s = string.format("%s%s%s", s, separator or "", substr) + end + + -- ok + return s +end + +-- encode: ' ', '=', '\"', '<' +function string.encode(self) + + -- null? + if self == nil then return end + + -- done + return (self:gsub("[%s=\"<]", function (w) return string.format("%%%x", w:byte()) end)) +end + +-- decode: ' ', '=', '\"' +function string.decode(self) + + -- null? + if self == nil then return end + + -- done + return (self:gsub("%%(%x%x)", function (w) return string.char(tonumber(w, 16)) end)) +end + + +-- return module: string +return string diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua new file mode 100644 index 000000000..52b726412 --- /dev/null +++ b/xmake/core/base/table.lua @@ -0,0 +1,99 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file table.lua +-- + +-- define module: table +local table = table or {} + +-- join all objects and tables +function table.join(...) + + -- done + local args = {...} + local result = {} + for _, t in ipairs(args) do + if type(t) == "table" then + for k, v in pairs(t) do + if type(k) == "number" then table.insert(result, v) + else result[k] = v end + end + else + table.insert(result, t) + end + end + + -- ok? + return result +end + +-- join all objects and tables to self +function table.join2(self, ...) + + -- check + assert(self and type(self) == "table") + + -- done + local args = {...} + for _, t in ipairs(args) do + if type(t) == "table" then + for k, v in pairs(t) do + if type(k) == "number" then table.insert(self, v) + else self[k] = v end + end + else + table.insert(self, t) + end + end + + -- ok? + return self +end + +-- clear the table +function table.clear(self) + + -- check + assert(self and type(self) == "table") + + -- clear it + for k in next, self do + rawset(self, k, nil) + end +end + +-- copy the table to self +function table.copy2(self, copied) + + -- check + assert(self and copied) + + -- clear self first + table.clear(self) + + -- copy it + for k, v in pairs(copied) do + self[k] = v + end + +end + +-- return module: table +return table diff --git a/xmake/core/base/template.lua b/xmake/core/base/template.lua new file mode 100644 index 000000000..c02b135c3 --- /dev/null +++ b/xmake/core/base/template.lua @@ -0,0 +1,77 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file template.lua +-- + +-- define module: template +local template = template or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") + +-- get the language list +function template.languages() + + -- make list + local list = {} + + -- get the language list + local languages = os.match(xmake._TEMPLATES_DIR .. "/*", true) + if languages then + for _, v in ipairs(languages) do + table.insert(list, path.basename(v)) + end + end + + -- ok? + return list +end + +-- load all templates from the given language +function template.loadall(language) + + -- check + assert(language) + + -- load all templates + local modules = {} + local templates = os.match(string.format("%s/%s/**/_template.lua", xmake._TEMPLATES_DIR, language)) + if templates then + for _, t in ipairs(templates) do + local script = assert(loadfile(t)) + if script then + local module = script() + if module then + module._DIRECTORY = path.directory(t) + table.insert(modules, module) + end + end + end + end + + -- ok? + return modules +end + + +-- return module: template +return template diff --git a/xmake/core/base/uninstall.lua b/xmake/core/base/uninstall.lua new file mode 100644 index 000000000..304b73c92 --- /dev/null +++ b/xmake/core/base/uninstall.lua @@ -0,0 +1,104 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file uninstall.lua +-- + +-- define module: uninstall +local uninstall = uninstall or {} + +-- load modules +local os = require("base/os") +local io = require("base/io") +local rule = require("base/rule") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local platform = require("platform/platform") + +-- uninstall target from the platform script +function uninstall._done_from_platform(target) + + -- check + assert(target) + + -- the platform uninstall script file + local uninstallscript = nil + local scriptfile = platform.directory() .. "/uninstall.lua" + if os.isfile(scriptfile) then + + -- load the uninstall script + local script, errors = loadfile(scriptfile) + if script then + uninstallscript = script() + if type(uninstallscript) == "table" and uninstallscript.main then + uninstallscript = uninstallscript.main + end + else + utils.error(errors) + end + end + + -- uninstall it + if type(uninstallscript) == "function" then + return uninstallscript(target) + end + + -- continue + return 0 +end + +-- uninstall target from the given target configure +function uninstall._done(target) + + -- check + assert(target) + + -- uninstall it from the platform script + local ok = uninstall._done_from_platform(target) + if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end + + -- ok + return true +end + +-- done uninstall from the configure +function uninstall.done(configs) + + -- check + assert(configs) + + -- uninstall targets + for _, target in pairs(configs) do + + -- uninstall it + if not uninstall._done(target) then + -- errors + utils.error("uninstall %s failed!", target.name) + return false + end + + end + + -- ok + return true +end + +-- return module: uninstall +return uninstall diff --git a/xmake/core/base/utils.lua b/xmake/core/base/utils.lua new file mode 100644 index 000000000..fd1f053d6 --- /dev/null +++ b/xmake/core/base/utils.lua @@ -0,0 +1,258 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file utils.lua +-- + +-- define module: utils +local utils = utils or {} + +-- the printf function +function utils.printf(msg, ...) + + -- check + assert(msg) + + -- trace + print(string.format(msg, ...)) +end + +-- the verbose function +function utils.verbose(msg, ...) + + if xmake._OPTIONS.verbose then + + -- check + assert(msg) + + -- trace + print(string.format(msg, ...)) + end +end + +-- the error function +function utils.error(msg, ...) + + -- check + assert(msg) + + -- trace + print("error: " .. string.format(msg, ...)) +end + +-- the warning function +function utils.warning(msg, ...) + + -- check + assert(msg) + + -- trace + print("warning: " .. string.format(msg, ...)) +end + +-- ifelse, a? b : c +function utils.ifelse(a, b, c) + if a then return b else return c end +end + +-- dump object with the level +function utils._dump_with_level(object, exclude, level) + + -- dump string + if type(object) == "string" then + io.write(string.format("%q", object)) + -- dump boolean + elseif type(object) == "boolean" then + io.write(tostring(object)) + -- dump number + elseif type(object) == "number" then + io.write(object) + -- dump function + elseif type(object) == "function" then + io.write("") + -- dump table + elseif type(object) == "table" then + + -- dump head + io.write("\n") + for l = 1, level do + io.write(" ") + end + io.write("{\n") + + -- dump body + local i = 0 + for k, v in pairs(object) do + + -- exclude some keys + if not exclude or type(k) ~= "string" or not k:find(exclude) then + + -- dump spaces and separator + for l = 1, level do + io.write(" ") + end + + io.write(utils.ifelse(i == 0, " ", ", ")) + + -- dump key + if type(k) == "string" then + io.write(k, " = ") + end + + -- dump value + if not utils._dump_with_level(v, exclude, level + 1) then + return false + end + + -- dump newline + io.write("\n") + i = i + 1 + end + end + + -- dump tail + for l = 1, level do + io.write(" ") + end + io.write("}\n") + else + -- error + utils.error("invalid object type: %s", type(object)) + return false + end + + -- ok + return true +end + +-- dump object +function utils.dump(object, exclude, prefix) + + -- dump prefix + if prefix then + io.write(prefix) + end + + -- dump it + utils._dump_with_level(object, exclude, 0) + + -- return it + return object +end + +-- unwrap object if be only one +function utils.unwrap(object) + + -- check + assert(object) + + -- unwrap it + if type(object) == "table" and table.getn(object) == 1 then + for _, v in pairs(object) do + return v + end + end + + -- ok + return object +end + +-- wrap object to table +function utils.wrap(object) + + -- no object? + if not object then + return {} + end + + -- wrap it if not table + if type(object) ~= "table" then + return {object} + end + + -- ok + return object +end + +-- remove repeat from the given array +function utils.unique(array) + + -- check + assert(array) + + -- remove repeat + if type(array) == "table" then + + -- not only one? + if table.getn(array) ~= 1 then + + -- done + local exists = {} + local unique = {} + for _, v in ipairs(array) do + if type(v) == "string" then + if not exists[v] then + exists[v] = true + table.insert(unique, v) + end + else + if not exists["\"" .. v .. "\""] then + exists["\"" .. v .. "\""] = true + table.insert(unique, v) + end + end + end + + -- update it + array = unique + end + end + + -- ok + return array +end + +-- call functions +function utils.call(funcs, pred, ...) + + -- check + assert(funcs) + + -- call all + for _, func in ipairs(utils.wrap(funcs)) do + + -- check + assert(type(func) == "function") + + -- call it + local result = func(...) + + -- exists predicate? + if pred and type(pred) == "function" then + if not pred(name, result) then return false end + -- failed? + elseif not result then return false end + end + + -- ok + return true +end + +-- return module: utils +return utils diff --git a/xmake/core/module/os.lua b/xmake/core/module/os.lua new file mode 100644 index 000000000..3689086f2 --- /dev/null +++ b/xmake/core/module/os.lua @@ -0,0 +1,46 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file os.lua +-- + +-- load modules +local io = require("base/io") +local os = require("base/os") + +-- define module: _os +local _os = _os or {} + +-- cat the given file +function _os.cat(filepath, linecount) + + -- cat it + return io.cat(filepath, linecount) +end + +-- only copy the interfaces of os +for k, v in pairs(os) do + if type(v) == "function" then + _os[k] = v + end +end + +-- return module: _os +return _os + diff --git a/xmake/core/module/path.lua b/xmake/core/module/path.lua new file mode 100644 index 000000000..9de905667 --- /dev/null +++ b/xmake/core/module/path.lua @@ -0,0 +1,25 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file path.lua +-- + +-- return module: path +return require("base/path") + diff --git a/xmake/core/module/project.lua b/xmake/core/module/project.lua new file mode 100644 index 000000000..f3f726c6f --- /dev/null +++ b/xmake/core/module/project.lua @@ -0,0 +1,73 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file project.lua +-- + +-- define module: project +local project = project or {} + +-- load modules +local rule = require("base/rule") +local config = require("base/config") + +-- get the build directory +function project.buildir() + + -- get it + return config.get("buildir") +end + +-- get the project directory +function project.projectdir() + + -- get it + return xmake._PROJECT_DIR +end + +-- get the log file +function project.logfile() + + -- get it + return rule.logfile() +end + +-- get the current platform +function project.plat() + + -- get it + return config.get("plat") +end + +-- get the current architecture +function project.arch() + + -- get it + return config.get("arch") +end + +-- get the current mode +function project.mode() + + -- get it + return config.get("mode") +end + +-- return module: project +return project diff --git a/xmake/core/module/string.lua b/xmake/core/module/string.lua new file mode 100644 index 000000000..60d3408cf --- /dev/null +++ b/xmake/core/module/string.lua @@ -0,0 +1,24 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file string.lua +-- + +-- return module: string +return require("base/string") diff --git a/xmake/core/module/utils.lua b/xmake/core/module/utils.lua new file mode 100644 index 000000000..ab4d2c96f --- /dev/null +++ b/xmake/core/module/utils.lua @@ -0,0 +1,24 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file utils.lua +-- + +-- return module: utils +return require("base/utils") diff --git a/xmake/core/platform/android/android.lua b/xmake/core/platform/android/android.lua new file mode 100644 index 000000000..15e3c33a2 --- /dev/null +++ b/xmake/core/platform/android/android.lua @@ -0,0 +1,120 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file android.lua +-- + +-- define module: android +local android = android or {} + +-- load modules +local config = require("base/config") + +-- init host +android._HOST = xmake._HOST + +-- init os +android._OS = "android" + +-- init architectures +android._ARCHS = {"armv5te", "armv6", "armv7-a", "armv8-a", "arm64-v8a"} + +-- make configure +function android.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".so"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.as = config.get("as") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + + -- init flags + local arch = config.get("arch") + if arch:startswith("arm64") then + configs.cxflags = {} + configs.asflags = {} + configs.ldflags = {"-llog"} + configs.shflags = {"-llog"} + else + configs.cxflags = { "-march=" .. arch, "-mthumb"} + configs.asflags = { "-march=" .. arch, "-mthumb"} + configs.ldflags = { "-march=" .. arch, "-llog", "-mthumb"} + configs.shflags = { "-march=" .. arch, "-llog", "-mthumb"} + end + + -- add flags for the sdk directory of ndk + local ndk = config.get("ndk") + local ndk_sdkver = config.get("ndk_sdkver") + if ndk and ndk_sdkver then + local ndk_sdkdir = path.translate(string.format("%s/platforms/android-%d", ndk, ndk_sdkver)) + if arch:startswith("arm64") then + table.insert(configs.cxflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) + table.insert(configs.asflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) + table.insert(configs.ldflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) + table.insert(configs.shflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) + else + table.insert(configs.cxflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) + table.insert(configs.asflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) + table.insert(configs.ldflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) + table.insert(configs.shflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) + end + end + +end + +-- get the option menu for action: xmake config or global +function android.menu(action) + + -- init config option menu + android._MENU_CONFIG = android._MENU_CONFIG or + { {} + , {nil, "ndk", "kv", nil, "The NDK Directory" } + , {nil, "ndk_sdkver", "kv", "auto", "The SDK Version for NDK" } + , } + + -- init global option menu + android._MENU_GLOBAL = android._MENU_GLOBAL or + { {} + , {nil, "ndk", "kv", nil, "The NDK Directory" } + , {nil, "ndk_sdkver", "kv", "auto", "The SDK Version for NDK" } + , } + + -- get the option menu + if action == "config" then + return android._MENU_CONFIG + elseif action == "global" then + return android._MENU_GLOBAL + end +end + +-- return module: android +return android diff --git a/xmake/core/platform/android/prober.lua b/xmake/core/platform/android/prober.lua new file mode 100644 index 000000000..a6446e0e1 --- /dev/null +++ b/xmake/core/platform/android/prober.lua @@ -0,0 +1,269 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", "armv7-a") + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the sdk version for ndk +function prober._probe_ndk_sdkver(configs) + + -- ok? + local ndk_sdkver = configs.get("ndk_sdkver") + if ndk_sdkver then return true end + + -- get the ndk + local ndk = configs.get("ndk") + if ndk then + + -- match all sdk directories + local sdkdirs = os.match(ndk .. "/platforms/android-*", true) + if sdkdirs then + + -- get the max version + local version_maxn = 0 + for _, sdkdir in ipairs(sdkdirs) do + local filename = path.filename(sdkdir) + local version, count = filename:gsub("android%-", "") + if count > 0 then + version = tonumber(version) + if version > version_maxn then version_maxn = version end + end + end + + -- save the version + if version_maxn > 0 then ndk_sdkver = version_maxn end + end + end + + -- probe ok? update it + if type(ndk_sdkver) == "number" and ndk_sdkver > 0 then + + -- save it + configs.set("ndk_sdkver", ndk_sdkver) + + -- trace + utils.printf("checking for the SDK version of NDK ... %s", string.format("android-%d", ndk_sdkver)) + else + + -- trace + utils.printf("checking for the SDK version of NDK ... no") + end + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolpath(configs, kind, cross, name, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- attempt to get it from the given cross toolchains + local toolpath = nil + local toolchains = configs.get("toolchains") + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to get it from the ndk + if not toolpath then + local ndk = configs.get("ndk") + if ndk then + + -- match all toolchains + local arch = configs.get("arch") + if arch and arch:startswith("arm64") then + toolchains = os.match(string.format("%s/toolchains/aarch64-linux-android-**/prebuilt/*/bin/%s%s", ndk, cross, name)) + else + toolchains = os.match(string.format("%s/toolchains/arm-linux-androideabi-**/prebuilt/*/bin/%s%s", ndk, cross, name)) + end + + -- probe the tool path + if toolchains then + for _, filepath in ipairs(toolchains) do + toolpath = tools.probe(cross .. name, path.directory(filepath)) + if toolpath then break end + end + end + end + end + + -- probe ok? update it + if toolpath then configs.set(kind, toolpath) end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- failed? + if not toolpath and not configs.get("ndk") then + utils.error("checking for the NDK directory ... no") + utils.error(" - xmake config --ndk=xxx") + utils.error("or - xmake global --ndk=xxx") + return false + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- init prefix + local prefix = "arm-linux-androideabi-" + local arch = configs.get("arch") + if arch and arch:startswith("arm64") then + prefix = "aarch64-linux-android-" + end + + -- done + if not prober._probe_toolpath(configs, "cc", prefix, "gcc", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", prefix, "g++", "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", prefix, "gcc", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", prefix, "g++", "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", prefix, "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", prefix, "g++", "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", prefix, "swiftc", "the swift compiler") then return false end + + -- ok + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_make + , prober._probe_ccache + , prober._probe_ndk_sdkver + , prober._probe_toolchains} + , nil + , config) + +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_make + , prober._probe_ccache + , prober._probe_ndk_sdkver} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/iphoneos/iphoneos.lua b/xmake/core/platform/iphoneos/iphoneos.lua new file mode 100644 index 000000000..f9147945c --- /dev/null +++ b/xmake/core/platform/iphoneos/iphoneos.lua @@ -0,0 +1,141 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file iphoneos.lua +-- + +-- define module: iphoneos +local iphoneos = iphoneos or {} + +-- load modules +local config = require("base/config") + +-- init host +iphoneos._HOST = "macosx" + +-- init os +iphoneos._OS = "ios" + +-- init architectures +iphoneos._ARCHS = {"armv7", "armv7s", "arm64"} + +-- make configure +function iphoneos.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".dylib"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.mm = config.get("mm") + configs.tools.mxx = config.get("mxx") + configs.tools.as = config.get("as") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + configs.tools.lipo = config.get("lipo") + + -- init target minimal version + local target_minver = config.get("target_minver") + assert(target_minver) + + -- init flags for architecture + local archflags = nil + local arch = config.get("arch") + if arch then archflags = "-arch " .. arch end + configs.cxflags = { archflags, "-miphoneos-version-min=" .. target_minver } + configs.mxflags = { archflags, "-miphoneos-version-min=" .. target_minver } + configs.asflags = { archflags, "-miphoneos-version-min=" .. target_minver } + configs.ldflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-miphoneos-version-min=" .. target_minver } + configs.shflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-miphoneos-version-min=" .. target_minver } + if arch then + configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } + end + + -- init flags for the xcode sdk directory + local xcode_dir = config.get("xcode_dir") + local xcode_sdkver = config.get("xcode_sdkver") + if xcode_dir and xcode_sdkver then + + -- init flags + local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" .. xcode_sdkver .. ".sdk" + table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) + + -- save swift link directory + config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos") + end + +end + +-- get the option menu for action: xmake config or global +function iphoneos.menu(action) + + -- init config option menu + iphoneos._MENU_CONFIG = iphoneos._MENU_CONFIG or + { {} + , {nil, "mm", "kv", nil, "The Objc Compiler" } + , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } + , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } + , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } + , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } + , {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } + , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- init global option menu + iphoneos._MENU_GLOBAL = iphoneos._MENU_GLOBAL or + { {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- get the option menu + if action == "config" then + return iphoneos._MENU_CONFIG + elseif action == "global" then + return iphoneos._MENU_GLOBAL + end +end + + +-- return module: iphoneos +return iphoneos diff --git a/xmake/core/platform/iphoneos/package.lua b/xmake/core/platform/iphoneos/package.lua new file mode 100644 index 000000000..1e46ddadc --- /dev/null +++ b/xmake/core/platform/iphoneos/package.lua @@ -0,0 +1,76 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file package.lua +-- + +-- define module: package +local package = package or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local rule = require("base/rule") +local utils = require("base/utils") +local string = require("base/string") +local platform = require("platform/platform") + +-- package target +function package.main(target) + + -- check + assert(target and target.name) + + -- the count of architectures + local count = 0 + for _, _ in pairs(target.archs) do count = count + 1 end + if count < 2 then return 0 end + + -- get the lipo tool + local lipo = platform.tool("lipo") + if not lipo then return 0 end + + -- make universal info + local universal = {} + universal.targetdir = rule.backupdir(target.name, "universal") + universal.targetfile = rule.targetfile(target.name, target) + if not universal.targetdir or not universal.targetfile then return 0 end + + -- make the universal directory + os.mkdir(path.directory(string.format("%s/%s", universal.targetdir, universal.targetfile))) + + -- make the lipo command + local cmd = lipo .. " -create" + for arch, info in pairs(target.archs) do + cmd = string.format("%s -arch %s %s/%s", cmd, arch, info.targetdir, info.targetfile) + end + cmd = string.format("%s -output %s/%s", cmd, universal.targetdir, universal.targetfile) + + -- make the universal target + if 0 ~= os.execute(cmd) then return 0 end + + -- ok + target.archs.universal = universal + + -- continue + return 0 +end + +-- return module: package +return package diff --git a/xmake/core/platform/iphoneos/prober.lua b/xmake/core/platform/iphoneos/prober.lua new file mode 100644 index 000000000..0de95c783 --- /dev/null +++ b/xmake/core/platform/iphoneos/prober.lua @@ -0,0 +1,310 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", "armv7") + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the xcode application directory +function prober._probe_xcode(configs) + + -- get the xcode directory + local xcode_dir = configs.get("xcode_dir") + + -- ok? + if xcode_dir then return true end + + -- clear it first + xcode_dir = nil + + -- attempt to get the default directory + if not xcode_dir then + if os.isdir("/Applications/Xcode.app") then + xcode_dir = "/Applications/Xcode.app" + end + end + + -- attempt to match the other directories + if not xcode_dir then + local dirs = os.match("/Applications/Xcode*.app", true) + if dirs and table.getn(dirs) ~= 0 then + xcode_dir = dirs[1] + end + end + + -- probe ok? update it + if xcode_dir then + -- save it + configs.set("xcode_dir", xcode_dir) + + -- trace + utils.printf("checking for the Xcode application directory ... %s", xcode_dir) + else + -- failed + utils.error("checking for the Xcode application directory ... no") + utils.error(" - xmake config --xcode_dir=xxx") + utils.error("or - xmake global --xcode_dir=xxx") + return false + end + + -- ok + return true +end + +-- probe the xcode sdk version +function prober._probe_xcode_sdkver(configs) + + -- get the xcode sdk version + local xcode_sdkver = configs.get("xcode_sdkver") + + -- ok? + if xcode_sdkver then return true end + + -- clear it first + xcode_sdkver = nil + + -- attempt to match the directory + if not xcode_sdkver then + local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk", true) + if dirs then + for _, dir in ipairs(dirs) do + xcode_sdkver = string.match(dir, "%d+%.%d+") + if xcode_sdkver then break end + end + end + end + + -- probe ok? update it + if xcode_sdkver then + + -- save it + configs.set("xcode_sdkver", xcode_sdkver) + + -- trace + utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) + else + -- failed + utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) + utils.error(" - xmake config --xcode_sdkver=xxx") + utils.error("or - xmake global --xcode_sdkver=xxx") + return false + end + + -- ok + return true +end + +-- probe the target minimal version +function prober._probe_target_minver(configs) + + -- get the target minimal version + local target_minver = configs.get("target_minver") + + -- ok? + if target_minver then return true end + + -- init the default target minimal version + configs.set("target_minver", "7.0") + + -- trace + utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, cross, names, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- done + local toolpath = nil + local toolchains = configs.get("toolchains") + for _, name in ipairs(utils.wrap(names)) do + + -- attempt to get it from the given cross toolchains + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to run it directly + if not toolpath then + toolpath = tools.probe(cross .. name) + end + + -- probe ok? + if toolpath then + + -- update config + configs.set(kind, toolpath) + + -- end + break + end + + end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- done + if not prober._probe_toolpath(configs, "cc", "xcrun -sdk iphoneos ", "clang", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "mm", "xcrun -sdk iphoneos ", "clang", "the objc compiler") then return false end + if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the objc++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", xmake._CORE_DIR .. "/tools/gas-preprocessor.pl xcrun -sdk iphoneos ", "clang", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", "xcrun -sdk iphoneos ", "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", "xcrun -sdk iphoneos ", "swiftc", "the swift compiler") then return false end + if not prober._probe_toolpath(configs, "lipo", "xcrun -sdk iphoneos ", "lipo", "the universal files creater") then return false end + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_xcode + , prober._probe_xcode_sdkver + , prober._probe_target_minver + , prober._probe_make + , prober._probe_ccache + , prober._probe_toolchains} + , nil + , config) + +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_xcode + , prober._probe_make + , prober._probe_ccache} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/iphonesimulator/iphonesimulator.lua b/xmake/core/platform/iphonesimulator/iphonesimulator.lua new file mode 100644 index 000000000..4ceeb3eca --- /dev/null +++ b/xmake/core/platform/iphonesimulator/iphonesimulator.lua @@ -0,0 +1,138 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file iphonesimulator.lua +-- + +-- define module: iphonesimulator +local iphonesimulator = iphonesimulator or {} + +-- load modules +local config = require("base/config") + +-- init host +iphonesimulator._HOST = "macosx" + +-- init os +iphonesimulator._OS = "ios" + +-- init architectures +iphonesimulator._ARCHS = {"i386", "x86_64"} + +-- make configure +function iphonesimulator.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".dylib"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.mm = config.get("mm") + configs.tools.mxx = config.get("mxx") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + + -- init target minimal version + local target_minver = config.get("target_minver") + assert(target_minver) + + -- init flags for architecture + local archflags = nil + local arch = config.get("arch") + if arch then archflags = "-arch " .. arch end + configs.cxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } + configs.mxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } + configs.asflags = { archflags, "-mios-simulator-version-min=" .. target_minver } + configs.ldflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } + configs.shflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } + if arch then + configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } + end + + -- init flags for the xcode sdk directory + local xcode_dir = config.get("xcode_dir") + local xcode_sdkver = config.get("xcode_sdkver") + if xcode_dir and xcode_sdkver then + + -- init flags + local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" .. xcode_sdkver .. ".sdk" + table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) + + -- save swift link directory + config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator") + end +end + +-- get the option menu for action: xmake config or global +function iphonesimulator.menu(action) + + -- init config option menu + iphonesimulator._MENU_CONFIG = iphonesimulator._MENU_CONFIG or + { {} + , {nil, "mm", "kv", nil, "The Objc Compiler" } + , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } + , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } + , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } + , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } + , {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } + , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- init global option menu + iphonesimulator._MENU_GLOBAL = iphonesimulator._MENU_GLOBAL or + { {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- get the option menu + if action == "config" then + return iphonesimulator._MENU_CONFIG + elseif action == "global" then + return iphonesimulator._MENU_GLOBAL + end +end + + +-- return module: iphonesimulator +return iphonesimulator diff --git a/xmake/core/platform/iphonesimulator/prober.lua b/xmake/core/platform/iphonesimulator/prober.lua new file mode 100644 index 000000000..a4c69c72a --- /dev/null +++ b/xmake/core/platform/iphonesimulator/prober.lua @@ -0,0 +1,308 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", "x86_64") + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the xcode application directory +function prober._probe_xcode(configs) + + -- get the xcode directory + local xcode_dir = configs.get("xcode_dir") + + -- ok? + if xcode_dir then return true end + + -- clear it first + xcode_dir = nil + + -- attempt to get the default directory + if not xcode_dir then + if os.isdir("/Applications/Xcode.app") then + xcode_dir = "/Applications/Xcode.app" + end + end + + -- attempt to match the other directories + if not xcode_dir then + local dirs = os.match("/Applications/Xcode*.app", true) + if dirs and table.getn(dirs) ~= 0 then + xcode_dir = dirs[1] + end + end + + -- probe ok? update it + if xcode_dir then + -- save it + configs.set("xcode_dir", xcode_dir) + + -- trace + utils.printf("checking for the Xcode application directory ... %s", xcode_dir) + else + -- failed + utils.error("checking for the Xcode application directory ... no") + utils.error(" - xmake config --xcode_dir=xxx") + utils.error("or - xmake global --xcode_dir=xxx") + return false + end + + -- ok + return true +end + +-- probe the xcode sdk version +function prober._probe_xcode_sdkver(configs) + + -- get the xcode sdk version + local xcode_sdkver = configs.get("xcode_sdkver") + + -- ok? + if xcode_sdkver then return true end + + -- clear it first + xcode_sdkver = nil + + -- attempt to match the directory + if not xcode_sdkver then + local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator*.sdk", true) + if dirs then + for _, dir in ipairs(dirs) do + xcode_sdkver = string.match(dir, "%d+%.%d+") + if xcode_sdkver then break end + end + end + end + + -- probe ok? update it + if xcode_sdkver then + + -- save it + configs.set("xcode_sdkver", xcode_sdkver) + + -- trace + utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) + else + -- failed + utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) + utils.error(" - xmake config --xcode_sdkver=xxx") + utils.error("or - xmake global --xcode_sdkver=xxx") + return false + end + + -- ok + return true +end + +-- probe the target minimal version +function prober._probe_target_minver(configs) + + -- get the target minimal version + local target_minver = configs.get("target_minver") + + -- ok? + if target_minver then return true end + + -- init the default target minimal version + configs.set("target_minver", "7.0") + + -- trace + utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, cross, names, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- done + local toolpath = nil + local toolchains = configs.get("toolchains") + for _, name in ipairs(utils.wrap(names)) do + + -- attempt to get it from the given cross toolchains + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to run it directly + if not toolpath then + toolpath = tools.probe(cross .. name) + end + + -- probe ok? + if toolpath then + + -- update config + configs.set(kind, toolpath) + + -- end + break + end + + end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- done + if not prober._probe_toolpath(configs, "cc", "xcrun -sdk iphonesimulator ", "clang", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "mm", "xcrun -sdk iphonesimulator ", "clang", "the objc compiler") then return false end + if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the objc++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", "xcrun -sdk iphonesimulator ", "clang", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", "xcrun -sdk iphonesimulator ", "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", "xcrun -sdk iphonesimulator ", "swiftc", "the swift compiler") then return false end + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_xcode + , prober._probe_xcode_sdkver + , prober._probe_target_minver + , prober._probe_make + , prober._probe_ccache + , prober._probe_toolchains} + , nil + , config) +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_xcode + , prober._probe_make + , prober._probe_ccache} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/linux/install.lua b/xmake/core/platform/linux/install.lua new file mode 100644 index 000000000..870cf5040 --- /dev/null +++ b/xmake/core/platform/linux/install.lua @@ -0,0 +1,182 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file install.lua +-- + +-- define module: install +local install = install or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local rule = require("base/rule") +local utils = require("base/utils") +local string = require("base/string") +local platform = require("platform/platform") + +-- install target for the library file +function install._done_library(target) + + -- check + assert(target and target.name and target.archs) + + -- the output directory + local outputdir = target.outputdir or "/usr/local" + assert(outputdir) + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- make the library directory + local librarydir = outputdir .. "/lib" + if not os.isdir(librarydir) then + if not os.mkdir(librarydir) then + utils.error("create directory %s failed", librarydir) + return -1 + end + end + + -- copy the library file to the library directory + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", librarydir, path.filename(info.targetfile))) + if not ok then + utils.error(errors) + return -1 + end + + -- make the include directory + local includedir = outputdir .. "/include" + if not os.isdir(includedir) then + if not os.mkdir(includedir) then + utils.error("create directory %s failed", includedir) + return -1 + end + end + + -- copy the config.h to the output directory + if info.config_h then + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h))) + if not ok then + utils.error(errors) + return -1 + end + + -- update the config.h + info.config_h = string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h)) + end + + -- copy headers + if target.headers then + local srcheaders, dstheaders = rule.headerfiles(target, includedir) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + local ok, errors = os.cp(srcheader, dstheader) + if not ok then + utils.error(errors) + return -1 + end + end + i = i + 1 + end + end + + -- update the headers + target.headers = dstheaders + end + + -- update the target directory and file + info.targetdir = librarydir + info.targetfile = path.filename(info.targetfile) + + -- ok + return 1 +end + +-- install target for the binary file +function install._done_binary(target) + + -- check + assert(target and target.archs) + + -- the output directory + local outputdir = target.outputdir or "/usr/local" + assert(outputdir) + + -- make the binary directory + local binarydir = outputdir .. "/bin" + if not os.isdir(binarydir) then + if not os.mkdir(binarydir) then + utils.error("create directory %s failed", binarydir) + return -1 + end + end + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- copy the binary file to the binary directory + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), binarydir) + if not ok then + utils.error(errors) + return -1 + end + + -- update the target directory and file + info.targetdir = binarydir + info.targetfile = path.filename(info.targetfile) + + -- ok + return 1 +end + +-- install target +function install.main(target) + + -- check + assert(target and target.kind) + + -- the install scripts + local installscripts = + { + static = install._done_library + , shared = install._done_library + , binary = install._done_binary + } + + -- install it + local installscript = installscripts[target.kind] + if installscript then return installscript(target) end + + -- continue + return 0 +end + +-- return module: install +return install diff --git a/xmake/core/platform/linux/linux.lua b/xmake/core/platform/linux/linux.lua new file mode 100644 index 000000000..406dc5c58 --- /dev/null +++ b/xmake/core/platform/linux/linux.lua @@ -0,0 +1,103 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file linux.lua +-- + +-- define module: linux +local linux = linux or {} + +-- load modules +local config = require("base/config") + +-- init host +linux._HOST = "linux" + +-- init os +linux._OS = "linux" + +-- init architectures +linux._ARCHS = {"i386", "x86_64"} + +-- make configure +function linux.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".so"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.mm = config.get("mm") + configs.tools.mxx = config.get("mxx") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + + -- cross toolchains? + if config.get("cross") then return end + + -- init flags for architecture + local archflags = nil + local arch = config.get("arch") + if arch then + if arch == "x86_64" then archflags = "-m64" + elseif arch == "i386" then archflags = "-m32" + else archflags = "-arch " .. arch + end + end + configs.cxflags = { archflags } + configs.mxflags = { archflags } + configs.asflags = { archflags } + configs.ldflags = { archflags } + configs.shflags = { archflags } + + -- init linkdirs and includedirs + configs.linkdirs = {"/usr/lib", "/usr/local/lib"} + configs.includedirs = {"/usr/include", "/usr/local/include"} + +end + +-- get the option menu for action: xmake config or global +function linux.menu(action) + + -- init config option menu + linux._MENU_CONFIG = linux._MENU_CONFIG or {} + + -- init global option menu + linux._MENU_GLOBAL = linux._MENU_GLOBAL or {} + + -- get the option menu + if action == "config" then + return linux._MENU_CONFIG + elseif action == "global" then + return linux._MENU_GLOBAL + end +end + +-- return module: linux +return linux diff --git a/xmake/core/platform/linux/prober.lua b/xmake/core/platform/linux/prober.lua new file mode 100644 index 000000000..4e50b13cf --- /dev/null +++ b/xmake/core/platform/linux/prober.lua @@ -0,0 +1,198 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + if configs.get("cross") then + configs.set("arch", "none") + else + configs.set("arch", xmake._ARCH) + end + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, cross, names, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- done + local toolpath = nil + local toolchains = configs.get("toolchains") + for _, name in ipairs(utils.wrap(names)) do + + -- attempt to get it from the given cross toolchains + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to run it directly + if not toolpath then + toolpath = tools.probe(cross .. name) + end + + -- probe ok? + if toolpath then + + -- update config + configs.set(kind, toolpath) + + -- end + break + end + + end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- done + if not prober._probe_toolpath(configs, "cc", "", "gcc", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", "", {"g++", "gcc"}, "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", "", "gcc", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", "", {"g++", "gcc"}, "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", "", "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", "", {"g++", "gcc"}, "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", "", "swiftc", "the swift compiler") then return false end + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_make + , prober._probe_ccache + , prober._probe_toolchains} + , nil + , config) +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_make + , prober._probe_ccache} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/linux/uninstall.lua b/xmake/core/platform/linux/uninstall.lua new file mode 100644 index 000000000..468692620 --- /dev/null +++ b/xmake/core/platform/linux/uninstall.lua @@ -0,0 +1,134 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file uninstall.lua +-- + +-- define module: uninstall +local uninstall = uninstall or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local rule = require("base/rule") +local utils = require("base/utils") +local string = require("base/string") +local platform = require("platform/platform") + +-- uninstall target for the library file +function uninstall._done_library(target) + + -- check + assert(target and target.name and target.archs) + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- remove the target file + local targetfile = info.targetdir .. "/" .. info.targetfile + if os.isfile(targetfile) then + local ok, errors = os.rm(targetfile) + if not ok then + utils.error(errors) + return -1 + end + end + + -- remove config.h + if info.config_h and os.isfile(info.config_h) then + local ok, errors = os.rm(info.config_h) + if not ok then + utils.error(errors) + return -1 + end + end + + -- remove headers + if target.headers then + for _, header in ipairs(target.headers) do + if os.isfile(header) then + local ok, errors = os.rm(header) + if not ok then + utils.error(errors) + return -1 + end + end + end + end + + -- ok + return 1 +end + +-- uninstall target for the binary file +function uninstall._done_binary(target) + + -- check + assert(target and target.archs) + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- the target file + local targetfile = info.targetdir .. "/" .. info.targetfile + if not os.isfile(targetfile) then return 1 end + + -- remove the target file + local ok, errors = os.rm(targetfile) + if not ok then + utils.error(errors) + return -1 + end + + -- ok + return 1 +end + +-- uninstall target +function uninstall.main(target) + + -- check + assert(target and target.kind) + + -- the uninstall scripts + local uninstallscripts = + { + static = uninstall._done_library + , shared = uninstall._done_library + , binary = uninstall._done_binary + } + + -- uninstall it + local uninstallscript = uninstallscripts[target.kind] + if uninstallscript then return uninstallscript(target) end + + -- continue + return 0 +end + +-- return module: uninstall +return uninstall diff --git a/xmake/core/platform/macosx/install.lua b/xmake/core/platform/macosx/install.lua new file mode 100644 index 000000000..870cf5040 --- /dev/null +++ b/xmake/core/platform/macosx/install.lua @@ -0,0 +1,182 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file install.lua +-- + +-- define module: install +local install = install or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local rule = require("base/rule") +local utils = require("base/utils") +local string = require("base/string") +local platform = require("platform/platform") + +-- install target for the library file +function install._done_library(target) + + -- check + assert(target and target.name and target.archs) + + -- the output directory + local outputdir = target.outputdir or "/usr/local" + assert(outputdir) + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- make the library directory + local librarydir = outputdir .. "/lib" + if not os.isdir(librarydir) then + if not os.mkdir(librarydir) then + utils.error("create directory %s failed", librarydir) + return -1 + end + end + + -- copy the library file to the library directory + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", librarydir, path.filename(info.targetfile))) + if not ok then + utils.error(errors) + return -1 + end + + -- make the include directory + local includedir = outputdir .. "/include" + if not os.isdir(includedir) then + if not os.mkdir(includedir) then + utils.error("create directory %s failed", includedir) + return -1 + end + end + + -- copy the config.h to the output directory + if info.config_h then + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h))) + if not ok then + utils.error(errors) + return -1 + end + + -- update the config.h + info.config_h = string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h)) + end + + -- copy headers + if target.headers then + local srcheaders, dstheaders = rule.headerfiles(target, includedir) + if srcheaders and dstheaders then + local i = 1 + for _, srcheader in ipairs(srcheaders) do + local dstheader = dstheaders[i] + if dstheader then + local ok, errors = os.cp(srcheader, dstheader) + if not ok then + utils.error(errors) + return -1 + end + end + i = i + 1 + end + end + + -- update the headers + target.headers = dstheaders + end + + -- update the target directory and file + info.targetdir = librarydir + info.targetfile = path.filename(info.targetfile) + + -- ok + return 1 +end + +-- install target for the binary file +function install._done_binary(target) + + -- check + assert(target and target.archs) + + -- the output directory + local outputdir = target.outputdir or "/usr/local" + assert(outputdir) + + -- make the binary directory + local binarydir = outputdir .. "/bin" + if not os.isdir(binarydir) then + if not os.mkdir(binarydir) then + utils.error("create directory %s failed", binarydir) + return -1 + end + end + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- copy the binary file to the binary directory + local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), binarydir) + if not ok then + utils.error(errors) + return -1 + end + + -- update the target directory and file + info.targetdir = binarydir + info.targetfile = path.filename(info.targetfile) + + -- ok + return 1 +end + +-- install target +function install.main(target) + + -- check + assert(target and target.kind) + + -- the install scripts + local installscripts = + { + static = install._done_library + , shared = install._done_library + , binary = install._done_binary + } + + -- install it + local installscript = installscripts[target.kind] + if installscript then return installscript(target) end + + -- continue + return 0 +end + +-- return module: install +return install diff --git a/xmake/core/platform/macosx/macosx.lua b/xmake/core/platform/macosx/macosx.lua new file mode 100644 index 000000000..088a01c18 --- /dev/null +++ b/xmake/core/platform/macosx/macosx.lua @@ -0,0 +1,140 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file macosx.lua +-- + +-- define module: macosx +local macosx = macosx or {} + +-- load modules +local config = require("base/config") + +-- init host +macosx._HOST = "macosx" + +-- init os +macosx._OS = "macosx" + +-- init architectures +macosx._ARCHS = {"i386", "x86_64"} + +-- make configure +function macosx.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".dylib"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.mm = config.get("mm") + configs.tools.mxx = config.get("mxx") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + + -- init target minimal version + local target_minver = config.get("target_minver") + assert(target_minver) + + -- init flags for architecture + local archflags = nil + local arch = config.get("arch") + if arch then archflags = "-arch " .. arch end + configs.cxflags = { archflags, "-fpascal-strings", "-fmessage-length=0" } + configs.mxflags = { archflags, "-fpascal-strings", "-fmessage-length=0" } + configs.asflags = { archflags } + configs.ldflags = { archflags, "-mmacosx-version-min=" .. target_minver, "-stdlib=libc++", "-lz" } + configs.shflags = { archflags, "-mmacosx-version-min=" .. target_minver, "-stdlib=libc++", "-lz" } + if arch then + configs.scflags = { string.format("-target %s-apple-macosx%s", arch, target_minver) } + end + + -- init flags for the xcode sdk directory + local xcode_dir = config.get("xcode_dir") + local xcode_sdkver = config.get("xcode_sdkver") + if xcode_dir and xcode_sdkver then + + -- init flags + local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX" .. xcode_sdkver .. ".sdk" + table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) + + -- save swift link directory + config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx") + end + + -- init linkdirs + configs.linkdirs = {"/usr/lib", "/usr/local/lib"} + + -- init includedirs + -- + -- @note + -- cannot use configs.includedirs because the swift/objc compiler will compile code failed + table.insert(configs.cxflags, "-I/usr/include") + table.insert(configs.cxflags, "-I/usr/local/include") + +end + +-- get the option menu for action: xmake config or global +function macosx.menu(action) + + -- init config option menu + macosx._MENU_CONFIG = macosx._MENU_CONFIG or + { {} + , {nil, "mm", "kv", nil, "The Objc Compiler" } + , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } + , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } + , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } + , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } + , {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } + , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } + , } + + -- init global option menu + macosx._MENU_GLOBAL = macosx._MENU_GLOBAL or + { {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , } + + -- get the option menu + if action == "config" then + return macosx._MENU_CONFIG + elseif action == "global" then + return macosx._MENU_GLOBAL + end +end + +-- return module: macosx +return macosx diff --git a/xmake/core/platform/macosx/prober.lua b/xmake/core/platform/macosx/prober.lua new file mode 100644 index 000000000..e2571fdd9 --- /dev/null +++ b/xmake/core/platform/macosx/prober.lua @@ -0,0 +1,307 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", xmake._ARCH) + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the xcode application directory +function prober._probe_xcode(configs) + + -- get the xcode directory + local xcode_dir = configs.get("xcode_dir") + + -- ok? + if xcode_dir then return true end + + -- clear it first + xcode_dir = nil + + -- attempt to get the default directory + if not xcode_dir then + if os.isdir("/Applications/Xcode.app") then + xcode_dir = "/Applications/Xcode.app" + end + end + + -- attempt to match the other directories + if not xcode_dir then + local dirs = os.match("/Applications/Xcode*.app", true) + if dirs and table.getn(dirs) ~= 0 then + xcode_dir = dirs[1] + end + end + + -- probe ok? update it + if xcode_dir then + -- save it + configs.set("xcode_dir", xcode_dir) + + -- trace + utils.printf("checking for the Xcode application directory ... %s", xcode_dir) + else + -- failed + utils.error("checking for the Xcode application directory ... no") + utils.error(" - xmake config --xcode_dir=xxx") + utils.error("or - xmake global --xcode_dir=xxx") + return false + end + + -- ok + return true +end + +-- probe the xcode sdk version +function prober._probe_xcode_sdkver(configs) + + -- get the xcode sdk version + local xcode_sdkver = configs.get("xcode_sdkver") + + -- ok? + if xcode_sdkver then return true end + + -- clear it first + xcode_sdkver = nil + + -- attempt to match the directory + if not xcode_sdkver then + local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX*.sdk", true) + if dirs then + for _, dir in ipairs(dirs) do + xcode_sdkver = string.match(dir, "%d+%.%d+") + if xcode_sdkver then break end + end + end + end + + -- probe ok? update it + if xcode_sdkver then + + -- save it + configs.set("xcode_sdkver", xcode_sdkver) + + -- trace + utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) + else + -- failed + utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) + utils.error(" - xmake config --xcode_sdkver=xxx") + utils.error("or - xmake global --xcode_sdkver=xxx") + return false + end + + -- ok + return true +end + +-- probe the target minimal version +function prober._probe_target_minver(configs) + + -- get the target minimal version + local target_minver = configs.get("target_minver") + + -- ok? + if target_minver then return true end + + -- init the default target minimal version + configs.set("target_minver", "10.9") + + -- trace + utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, cross, names, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- done + local toolpath = nil + local toolchains = configs.get("toolchains") + for _, name in ipairs(utils.wrap(names)) do + + -- attempt to get it from the given cross toolchains + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to run it directly + if not toolpath then + toolpath = tools.probe(cross .. name) + end + + -- probe ok? + if toolpath then + + -- update config + configs.set(kind, toolpath) + + -- end + break + end + + end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- done + if not prober._probe_toolpath(configs, "cc", "xcrun -sdk macosx ", "clang", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk macosx ", {"clang++", "clang"}, "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "mm", "xcrun -sdk macosx ", "clang", "the objc compiler") then return false end + if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk macosx ", {"clang++", "clang"}, "the objc++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", "xcrun -sdk macosx ", "clang", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", "xcrun -sdk macosx ", {"clang++", "clang"}, "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", "xcrun -sdk macosx ", "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", "xcrun -sdk macosx ", {"clang++", "clang"}, "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", "xcrun -sdk macosx ", "swiftc", "the swift compiler") then return false end + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_xcode + , prober._probe_xcode_sdkver + , prober._probe_target_minver + , prober._probe_make + , prober._probe_ccache + , prober._probe_toolchains} + , nil + , config) +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_xcode + , prober._probe_ccache} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/macosx/uninstall.lua b/xmake/core/platform/macosx/uninstall.lua new file mode 100644 index 000000000..468692620 --- /dev/null +++ b/xmake/core/platform/macosx/uninstall.lua @@ -0,0 +1,134 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file uninstall.lua +-- + +-- define module: uninstall +local uninstall = uninstall or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local rule = require("base/rule") +local utils = require("base/utils") +local string = require("base/string") +local platform = require("platform/platform") + +-- uninstall target for the library file +function uninstall._done_library(target) + + -- check + assert(target and target.name and target.archs) + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- remove the target file + local targetfile = info.targetdir .. "/" .. info.targetfile + if os.isfile(targetfile) then + local ok, errors = os.rm(targetfile) + if not ok then + utils.error(errors) + return -1 + end + end + + -- remove config.h + if info.config_h and os.isfile(info.config_h) then + local ok, errors = os.rm(info.config_h) + if not ok then + utils.error(errors) + return -1 + end + end + + -- remove headers + if target.headers then + for _, header in ipairs(target.headers) do + if os.isfile(header) then + local ok, errors = os.rm(header) + if not ok then + utils.error(errors) + return -1 + end + end + end + end + + -- ok + return 1 +end + +-- uninstall target for the binary file +function uninstall._done_binary(target) + + -- check + assert(target and target.archs) + + -- get target info + local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] + if not info then return -1 end + + -- check + assert(info.targetdir and info.targetfile) + + -- the target file + local targetfile = info.targetdir .. "/" .. info.targetfile + if not os.isfile(targetfile) then return 1 end + + -- remove the target file + local ok, errors = os.rm(targetfile) + if not ok then + utils.error(errors) + return -1 + end + + -- ok + return 1 +end + +-- uninstall target +function uninstall.main(target) + + -- check + assert(target and target.kind) + + -- the uninstall scripts + local uninstallscripts = + { + static = uninstall._done_library + , shared = uninstall._done_library + , binary = uninstall._done_binary + } + + -- uninstall it + local uninstallscript = uninstallscripts[target.kind] + if uninstallscript then return uninstallscript(target) end + + -- continue + return 0 +end + +-- return module: uninstall +return uninstall diff --git a/xmake/core/platform/mingw/mingw.lua b/xmake/core/platform/mingw/mingw.lua new file mode 100644 index 000000000..7264489b2 --- /dev/null +++ b/xmake/core/platform/mingw/mingw.lua @@ -0,0 +1,93 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file mingw.lua +-- + +-- define module: mingw +local mingw = mingw or {} + +-- load modules +local config = require("base/config") + +-- init host +mingw._HOST = xmake._HOST + +-- init os +mingw._OS = "windows" + +-- init architectures +mingw._ARCHS = {"i386", "x86_64"} + +-- make configure +function mingw.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".so"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + + -- init flags for architecture + local archflags = nil + local arch = config.get("arch") + if arch then + if arch == "x86_64" then archflags = "-m64" + elseif arch == "i386" then archflags = "-m32" + else archflags = "-arch " .. arch + end + end + configs.cxflags = { archflags } + configs.asflags = { archflags } + configs.ldflags = { archflags } + configs.shflags = { archflags } + +end + +-- get the option menu for action: xmake config or global +function mingw.menu(action) + + -- init config option menu + mingw._MENU_CONFIG = mingw._MENU_CONFIG or {} + + -- init global option menu + mingw._MENU_GLOBAL = mingw._MENU_GLOBAL or {} + + -- get the option menu + if action == "config" then + return mingw._MENU_CONFIG + elseif action == "global" then + return mingw._MENU_GLOBAL + end +end + +-- return module: mingw +return mingw diff --git a/xmake/core/platform/mingw/prober.lua b/xmake/core/platform/mingw/prober.lua new file mode 100644 index 000000000..575e3a7ba --- /dev/null +++ b/xmake/core/platform/mingw/prober.lua @@ -0,0 +1,207 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", "i386") + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, cross, names, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- done + local toolpath = nil + local toolchains = configs.get("toolchains") + for _, name in ipairs(utils.wrap(names)) do + + -- attempt to get it from the given cross toolchains + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to run it directly + if not toolpath then + toolpath = tools.probe(cross .. name) + end + + -- probe ok? + if toolpath then + + -- update config + configs.set(kind, toolpath) + + -- end + break + end + + end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- init the default cross from the current host and architecture + local cross = "" + local arch = configs.get("arch") + if arch then + if xmake._HOST == "macosx" and arch == "i386" then + cross = "i386-mingw32-" + elseif arch == "i386" then + cross = "i686-w64-mingw32-" + elseif arch == "x86_64" then + cross = "x86_64-w64-mingw32-" + end + end + + -- done + if not prober._probe_toolpath(configs, "cc", cross, "gcc", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", cross, {"g++", "gcc"}, "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", cross, "gcc", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", cross, {"g++", "gcc"}, "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", cross, "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", cross, {"g++", "gcc"}, "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", cross, "swiftc", "the swift compiler") then return false end + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_make + , prober._probe_ccache + , prober._probe_toolchains} + , nil + , config) +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_make + , prober._probe_ccache} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/platform.lua b/xmake/core/platform/platform.lua new file mode 100644 index 000000000..2fc411cbf --- /dev/null +++ b/xmake/core/platform/platform.lua @@ -0,0 +1,385 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file platform.lua +-- + +-- define module: platform +local platform = platform or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local config = require("base/config") +local global = require("base/global") + +-- load prober the given platform directory +function platform._load_prober(root) + + -- the platform file path + local filepath = string.format("%s/prober.lua", root) + if os.isfile(filepath) then + + -- load script + local script = loadfile(filepath) + if script then + + -- load prober + local prober = script() + if prober then + + -- ok + return prober + end + end + end +end + +-- load the given platform from the given root directory +function platform._load_from(root, plat) + + -- the platform file path + local filepath = string.format("%s/platform/%s/%s.lua", root, plat, plat) + if os.isfile(filepath) then + + -- load script + local script = loadfile(filepath) + if script then + + -- load module + local module = script() + if module then + + -- save directory + module._DIRECTORY = path.directory(filepath) + assert(module._DIRECTORY) + + -- attempt to load prober + module._PROBER = platform._load_prober(module._DIRECTORY) + + -- ok + return module + end + end + end +end + +-- load the given platform +function platform._load(plat) + + -- the module + platform._MODULES = platform._MODULES or {} + local module = platform._MODULES[plat] + + -- return it directory if ok + if module then return module end + + -- attempt to load it from the project configure directory + if not module then module = platform._load_from(config.directory(), plat) end + + -- attempt to load it from the global configure directory + if not module then module = platform._load_from(global.directory(), plat) end + + -- attempt to load it from the script directory + if not module then module = platform._load_from(xmake._CORE_DIR, plat) end + + -- cache it if ok + if module then + platform._MODULES[plat] = module + end + + -- ok? + return module +end + +-- get the configure of the given platform +function platform._configs(plat) + + -- the configure + platform._CONFIGS = platform._CONFIGS or {} + local configs = platform._CONFIGS[plat] + + -- return it directly if exists + if configs then + return configs + end + + -- load platform + local module = platform._load(plat) + if module then + + -- init configure + platform._CONFIGS[plat]= {} + configs = platform._CONFIGS[plat] + + -- make configure + module.make(configs) + end + + -- ok? + return configs +end + +-- get the current platform module +function platform.module() + + -- load it + return platform._load(config.get("plat")) +end + +-- get the current platform module directory +function platform.directory() + + -- load it + local module = platform.module() + if module then + return module._DIRECTORY + end +end + +-- make the current platform configure +function platform.make() + + -- get the platform + local plat = config.get("plat") + assert(plat) + + -- make and get the current platform configure + return platform._configs(plat) +end + +-- get the platform os +function platform.os() + + -- get module + local module = platform.module() + if not module then return end + + -- ok? + return module._OS +end + +-- get the given configure +function platform.get(name) + + -- check + assert(platform._CONFIGS) + + -- get the current platform configure + local configs = platform._configs(config.get("plat")) + if configs then + -- get it + return configs[name] + end +end + +-- get the given tool +function platform.tool(name) + + -- check + assert(name) + + -- get tools + local tools = platform.get("tools") + if tools then + return tools[name] + end + +end + +-- get the given format +function platform.format(kind) + + -- check + assert(kind) + + -- get formats + local formats = platform.get("formats") + if formats then + return formats[kind] + end + +end + +-- dump the platform configure +function platform.dump() + + -- check + assert(platform._CONFIGS) + + -- dump + if xmake._OPTIONS.verbose then + utils.dump(platform._configs(config.get("plat"))) + end + +end + +-- list all platforms +function platform.plats() + + -- return it directly if exists + if platform._PLATS then + return platform._PLATS + end + + -- make list + local list = {} + + -- get the platform list from the project configure directory + local plats = os.match(config.directory() .. "/platform/*", true) + if plats then + for _, v in ipairs(plats) do + table.insert(list, path.basename(v)) + end + end + + -- get the platform list from the global configure directory + plats = os.match(global.directory() .. "/platform/*", true) + if plats then + for _, v in ipairs(plats) do + table.insert(list, path.basename(v)) + end + end + + -- get the platform list from the script directory + plats = os.match(xmake._CORE_DIR .. "/platform/*", true) + if plats then + for _, v in ipairs(plats) do + table.insert(list, path.basename(v)) + end + end + + -- save it + platform._PLATS = list + + -- ok + return list +end + +-- list all architectures +function platform.archs(plat) + + -- check + assert(plat) + + -- load all platform configs + local archs = {} + local module = platform._load(plat) + if module and module._ARCHS then + for _, arch in ipairs(module._ARCHS) do + table.insert(archs, arch) + end + end + + -- ok + return archs +end + +-- get the option menu for action: xmake config or global +function platform.menu(action) + + -- check + assert(action) + + -- get all platforms + local plats = platform.plats() + assert(plats) + + -- load and merge all platform menus + local menus = {} + local exist = {} + for _, plat in ipairs(plats) do + + -- load platform + local module = platform._load(plat) + if module and module.menu then + + -- get the platform menu + local menu = module.menu(action) + if menu then + + -- exists options? + local exists = false + for _, option in ipairs(menu) do + local name = option[2] + if name and not exist[name] then + exists = true + break + end + end + + -- merge it and remove repeat if exists options + if exists then + -- get the platform menu option + for _, option in ipairs(menu) do + + -- merge it and remove repeat + local name = option[2] + if name then + if not exist[name] then + table.insert(menus, option) + exist[name] = true + end + else + table.insert(menus, option) + end + end + end + end + end + end + + -- get all platform menus + return menus +end + +-- probe the platform configure +function platform.probe(is_global) + + -- probe global + if is_global then + + -- get all platforms + local plats = platform.plats() + assert(plats) + + -- probe all platforms with the current host + for _, plat in ipairs(plats) do + local module = platform._load(plat) + if module and module._PROBER and module._PROBER.global and module._HOST and module._HOST == xmake._HOST then + if not module._PROBER.global() then return false end + end + end + + -- probe config + else + -- probe it + local module = platform.module() + if module and module._PROBER and module._PROBER.config then + if not module._PROBER.config() then return false end + end + end + + -- ok + return true +end + +-- return module: platform +return platform diff --git a/xmake/core/platform/watchos/package.lua b/xmake/core/platform/watchos/package.lua new file mode 100644 index 000000000..1e46ddadc --- /dev/null +++ b/xmake/core/platform/watchos/package.lua @@ -0,0 +1,76 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file package.lua +-- + +-- define module: package +local package = package or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local rule = require("base/rule") +local utils = require("base/utils") +local string = require("base/string") +local platform = require("platform/platform") + +-- package target +function package.main(target) + + -- check + assert(target and target.name) + + -- the count of architectures + local count = 0 + for _, _ in pairs(target.archs) do count = count + 1 end + if count < 2 then return 0 end + + -- get the lipo tool + local lipo = platform.tool("lipo") + if not lipo then return 0 end + + -- make universal info + local universal = {} + universal.targetdir = rule.backupdir(target.name, "universal") + universal.targetfile = rule.targetfile(target.name, target) + if not universal.targetdir or not universal.targetfile then return 0 end + + -- make the universal directory + os.mkdir(path.directory(string.format("%s/%s", universal.targetdir, universal.targetfile))) + + -- make the lipo command + local cmd = lipo .. " -create" + for arch, info in pairs(target.archs) do + cmd = string.format("%s -arch %s %s/%s", cmd, arch, info.targetdir, info.targetfile) + end + cmd = string.format("%s -output %s/%s", cmd, universal.targetdir, universal.targetfile) + + -- make the universal target + if 0 ~= os.execute(cmd) then return 0 end + + -- ok + target.archs.universal = universal + + -- continue + return 0 +end + +-- return module: package +return package diff --git a/xmake/core/platform/watchos/prober.lua b/xmake/core/platform/watchos/prober.lua new file mode 100644 index 000000000..1a818dfdf --- /dev/null +++ b/xmake/core/platform/watchos/prober.lua @@ -0,0 +1,310 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", "armv7") + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the xcode application directory +function prober._probe_xcode(configs) + + -- get the xcode directory + local xcode_dir = configs.get("xcode_dir") + + -- ok? + if xcode_dir then return true end + + -- clear it first + xcode_dir = nil + + -- attempt to get the default directory + if not xcode_dir then + if os.isdir("/Applications/Xcode.app") then + xcode_dir = "/Applications/Xcode.app" + end + end + + -- attempt to match the other directories + if not xcode_dir then + local dirs = os.match("/Applications/Xcode*.app", true) + if dirs and table.getn(dirs) ~= 0 then + xcode_dir = dirs[1] + end + end + + -- probe ok? update it + if xcode_dir then + -- save it + configs.set("xcode_dir", xcode_dir) + + -- trace + utils.printf("checking for the Xcode application directory ... %s", xcode_dir) + else + -- failed + utils.error("checking for the Xcode application directory ... no") + utils.error(" - xmake config --xcode_dir=xxx") + utils.error("or - xmake global --xcode_dir=xxx") + return false + end + + -- ok + return true +end + +-- probe the xcode sdk version +function prober._probe_xcode_sdkver(configs) + + -- get the xcode sdk version + local xcode_sdkver = configs.get("xcode_sdkver") + + -- ok? + if xcode_sdkver then return true end + + -- clear it first + xcode_sdkver = nil + + -- attempt to match the directory + if not xcode_sdkver then + local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS*.sdk", true) + if dirs then + for _, dir in ipairs(dirs) do + xcode_sdkver = string.match(dir, "%d+%.%d+") + if xcode_sdkver then break end + end + end + end + + -- probe ok? update it + if xcode_sdkver then + + -- save it + configs.set("xcode_sdkver", xcode_sdkver) + + -- trace + utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) + else + -- failed + utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) + utils.error(" - xmake config --xcode_sdkver=xxx") + utils.error("or - xmake global --xcode_sdkver=xxx") + return false + end + + -- ok + return true +end + +-- probe the target minimal version +function prober._probe_target_minver(configs) + + -- get the target minimal version + local target_minver = configs.get("target_minver") + + -- ok? + if target_minver then return true end + + -- init the default target minimal version + configs.set("target_minver", "7.0") + + -- trace + utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, cross, names, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- done + local toolpath = nil + local toolchains = configs.get("toolchains") + for _, name in ipairs(utils.wrap(names)) do + + -- attempt to get it from the given cross toolchains + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to run it directly + if not toolpath then + toolpath = tools.probe(cross .. name) + end + + -- probe ok? + if toolpath then + + -- update config + configs.set(kind, toolpath) + + -- end + break + end + + end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- done + if not prober._probe_toolpath(configs, "cc", "xcrun -sdk watchos ", "clang", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk watchos ", {"clang++", "clang"}, "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "mm", "xcrun -sdk watchos ", "clang", "the objc compiler") then return false end + if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk watchos ", {"clang++", "clang"}, "the objc++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", xmake._CORE_DIR .. "/tools/gas-preprocessor.pl xcrun -sdk watchos ", "clang", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", "xcrun -sdk watchos ", {"clang++", "clang"}, "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", "xcrun -sdk watchos ", "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", "xcrun -sdk watchos ", {"clang++", "clang"}, "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", "xcrun -sdk watchos ", "swiftc", "the swift compiler") then return false end + if not prober._probe_toolpath(configs, "lipo", "xcrun -sdk watchos ", "lipo", "the universal files creater") then return false end + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_xcode + , prober._probe_xcode_sdkver + , prober._probe_target_minver + , prober._probe_make + , prober._probe_ccache + , prober._probe_toolchains} + , nil + , config) + +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_xcode + , prober._probe_make + , prober._probe_ccache} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/watchos/watchos.lua b/xmake/core/platform/watchos/watchos.lua new file mode 100644 index 000000000..9551084f8 --- /dev/null +++ b/xmake/core/platform/watchos/watchos.lua @@ -0,0 +1,141 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file watchos.lua +-- + +-- define module: watchos +local watchos = watchos or {} + +-- load modules +local config = require("base/config") + +-- init host +watchos._HOST = "macosx" + +-- init os +watchos._OS = "ios" + +-- init architectures +watchos._ARCHS = {"armv7", "armv7s", "arm64"} + +-- make configure +function watchos.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".dylib"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.mm = config.get("mm") + configs.tools.mxx = config.get("mxx") + configs.tools.as = config.get("as") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + configs.tools.lipo = config.get("lipo") + + -- init target minimal version + local target_minver = config.get("target_minver") + assert(target_minver) + + -- init flags for architecture + local archflags = nil + local arch = config.get("arch") + if arch then archflags = "-arch " .. arch end + configs.cxflags = { archflags, "-mwatchos-version-min=" .. target_minver } + configs.mxflags = { archflags, "-mwatchos-version-min=" .. target_minver } + configs.asflags = { archflags, "-mwatchos-version-min=" .. target_minver } + configs.ldflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-mwatchos-version-min=" .. target_minver } + configs.shflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-mwatchos-version-min=" .. target_minver } + if arch then + configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } + end + + -- init flags for the xcode sdk directory + local xcode_dir = config.get("xcode_dir") + local xcode_sdkver = config.get("xcode_sdkver") + if xcode_dir and xcode_sdkver then + + -- init flags + local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS" .. xcode_sdkver .. ".sdk" + table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) + + -- save swift link directory + config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/watchos") + end + +end + +-- get the option menu for action: xmake config or global +function watchos.menu(action) + + -- init config option menu + watchos._MENU_CONFIG = watchos._MENU_CONFIG or + { {} + , {nil, "mm", "kv", nil, "The Objc Compiler" } + , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } + , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } + , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } + , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } + , {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } + , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- init global option menu + watchos._MENU_GLOBAL = watchos._MENU_GLOBAL or + { {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- get the option menu + if action == "config" then + return watchos._MENU_CONFIG + elseif action == "global" then + return watchos._MENU_GLOBAL + end +end + + +-- return module: watchos +return watchos diff --git a/xmake/core/platform/watchsimulator/prober.lua b/xmake/core/platform/watchsimulator/prober.lua new file mode 100644 index 000000000..d33059c36 --- /dev/null +++ b/xmake/core/platform/watchsimulator/prober.lua @@ -0,0 +1,308 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") +local config = require("base/config") +local global = require("base/global") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", "x86_64") + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the xcode application directory +function prober._probe_xcode(configs) + + -- get the xcode directory + local xcode_dir = configs.get("xcode_dir") + + -- ok? + if xcode_dir then return true end + + -- clear it first + xcode_dir = nil + + -- attempt to get the default directory + if not xcode_dir then + if os.isdir("/Applications/Xcode.app") then + xcode_dir = "/Applications/Xcode.app" + end + end + + -- attempt to match the other directories + if not xcode_dir then + local dirs = os.match("/Applications/Xcode*.app", true) + if dirs and table.getn(dirs) ~= 0 then + xcode_dir = dirs[1] + end + end + + -- probe ok? update it + if xcode_dir then + -- save it + configs.set("xcode_dir", xcode_dir) + + -- trace + utils.printf("checking for the Xcode application directory ... %s", xcode_dir) + else + -- failed + utils.error("checking for the Xcode application directory ... no") + utils.error(" - xmake config --xcode_dir=xxx") + utils.error("or - xmake global --xcode_dir=xxx") + return false + end + + -- ok + return true +end + +-- probe the xcode sdk version +function prober._probe_xcode_sdkver(configs) + + -- get the xcode sdk version + local xcode_sdkver = configs.get("xcode_sdkver") + + -- ok? + if xcode_sdkver then return true end + + -- clear it first + xcode_sdkver = nil + + -- attempt to match the directory + if not xcode_sdkver then + local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator*.sdk", true) + if dirs then + for _, dir in ipairs(dirs) do + xcode_sdkver = string.match(dir, "%d+%.%d+") + if xcode_sdkver then break end + end + end + end + + -- probe ok? update it + if xcode_sdkver then + + -- save it + configs.set("xcode_sdkver", xcode_sdkver) + + -- trace + utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) + else + -- failed + utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) + utils.error(" - xmake config --xcode_sdkver=xxx") + utils.error("or - xmake global --xcode_sdkver=xxx") + return false + end + + -- ok + return true +end + +-- probe the target minimal version +function prober._probe_target_minver(configs) + + -- get the target minimal version + local target_minver = configs.get("target_minver") + + -- ok? + if target_minver then return true end + + -- init the default target minimal version + configs.set("target_minver", "7.0") + + -- trace + utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) + + -- ok + return true +end + +-- probe the make +function prober._probe_make(configs) + + -- ok? + local make = configs.get("make") + if make then return true end + + -- probe the make path + make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if make then configs.set("make", make) end + + -- trace + utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) + + -- ok + return true +end + +-- probe the ccache +function prober._probe_ccache(configs) + + -- ok? + local ccache_enable = configs.get("ccache") + if ccache_enable and configs.get("__ccache") then return true end + + -- disable? + if type(ccache_enable) == "boolean" and not ccache_enable then + configs.set("__ccache", nil) + return true + end + + -- probe the ccache path + local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) + + -- probe ok? update it + if ccache_path then + configs.set("ccache", true) + configs.set("__ccache", ccache_path) + else + configs.set("ccache", false) + end + + -- trace + utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, cross, names, description) + + -- check + assert(kind) + + -- get the cross + cross = configs.get("cross") or cross + + -- done + local toolpath = nil + local toolchains = configs.get("toolchains") + for _, name in ipairs(utils.wrap(names)) do + + -- attempt to get it from the given cross toolchains + if toolchains then + toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) + end + + -- attempt to get it directly from the configure + if not toolpath then + toolpath = configs.get(kind) + end + + -- attempt to run it directly + if not toolpath then + toolpath = tools.probe(cross .. name) + end + + -- probe ok? + if toolpath then + + -- update config + configs.set(kind, toolpath) + + -- end + break + end + + end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- done + if not prober._probe_toolpath(configs, "cc", "xcrun -sdk watchsimulator ", "clang", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "mm", "xcrun -sdk watchsimulator ", "clang", "the objc compiler") then return false end + if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the objc++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", "xcrun -sdk watchsimulator ", "clang", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", "xcrun -sdk watchsimulator ", "ar", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "sc", "xcrun -sdk watchsimulator ", "swiftc", "the swift compiler") then return false end + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_xcode + , prober._probe_xcode_sdkver + , prober._probe_target_minver + , prober._probe_make + , prober._probe_ccache + , prober._probe_toolchains} + , nil + , config) +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_xcode + , prober._probe_make + , prober._probe_ccache} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/watchsimulator/watchsimulator.lua b/xmake/core/platform/watchsimulator/watchsimulator.lua new file mode 100644 index 000000000..a13bfde1e --- /dev/null +++ b/xmake/core/platform/watchsimulator/watchsimulator.lua @@ -0,0 +1,138 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file watchsimulator.lua +-- + +-- define module: watchsimulator +local watchsimulator = watchsimulator or {} + +-- load modules +local config = require("base/config") + +-- init host +watchsimulator._HOST = "macosx" + +-- init os +watchsimulator._OS = "ios" + +-- init architectures +watchsimulator._ARCHS = {"i386", "x86_64"} + +-- make configure +function watchsimulator.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"lib", ".a"} + configs.formats.object = {"", ".o"} + configs.formats.shared = {"lib", ".dylib"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.ccache = config.get("__ccache") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.mm = config.get("mm") + configs.tools.mxx = config.get("mxx") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.ex = config.get("ar") + configs.tools.sc = config.get("sc") + + -- init target minimal version + local target_minver = config.get("target_minver") + assert(target_minver) + + -- init flags for architecture + local archflags = nil + local arch = config.get("arch") + if arch then archflags = "-arch " .. arch end + configs.cxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } + configs.mxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } + configs.asflags = { archflags, "-mios-simulator-version-min=" .. target_minver } + configs.ldflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } + configs.shflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } + if arch then + configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } + end + + -- init flags for the xcode sdk directory + local xcode_dir = config.get("xcode_dir") + local xcode_sdkver = config.get("xcode_sdkver") + if xcode_dir and xcode_sdkver then + + -- init flags + local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator" .. xcode_sdkver .. ".sdk" + table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) + table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) + + -- save swift link directory + config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/watchsimulator") + end +end + +-- get the option menu for action: xmake config or global +function watchsimulator.menu(action) + + -- init config option menu + watchsimulator._MENU_CONFIG = watchsimulator._MENU_CONFIG or + { {} + , {nil, "mm", "kv", nil, "The Objc Compiler" } + , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } + , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } + , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } + , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } + , {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } + , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- init global option menu + watchsimulator._MENU_GLOBAL = watchsimulator._MENU_GLOBAL or + { {} + , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } + , {} + , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } + , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } + , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } + , } + + -- get the option menu + if action == "config" then + return watchsimulator._MENU_CONFIG + elseif action == "global" then + return watchsimulator._MENU_GLOBAL + end +end + + +-- return module: watchsimulator +return watchsimulator diff --git a/xmake/core/platform/windows/prober.lua b/xmake/core/platform/windows/prober.lua new file mode 100644 index 000000000..40d214efd --- /dev/null +++ b/xmake/core/platform/windows/prober.lua @@ -0,0 +1,300 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local io = require("base/io") +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") +local global = require("base/global") +local tools = require("tools/tools") +local platform = require("platform/platform") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.get("arch") + + -- ok? + if arch then return true end + + -- init the default architecture + configs.set("arch", "x86") + + -- trace + utils.printf("checking for the architecture ... %s", configs.get("arch")) + + -- ok + return true +end + +-- probe the vs version +function prober._probe_vs_version(configs) + + -- get the vs version + local vs = configs.get("vs") + + -- ok? + if vs then return true end + + -- clear it first + vs = nil + + -- make the map table + local map = + { + VS140COMNTOOLS = "2015" + , VS120COMNTOOLS = "2013" + , VS110COMNTOOLS = "2012" + , VS100COMNTOOLS = "2010" + , VS90COMNTOOLS = "2008" + , VS80COMNTOOLS = "2005" + , VS71COMNTOOLS = "2003" + , VS70COMNTOOLS = "7.0" + , VS60COMNTOOLS = "6.0" + , VS50COMNTOOLS = "5.0" + , VS42COMNTOOLS = "4.2" + } + + -- attempt to get it from the envirnoment variable + if not vs then + for k, v in pairs(map) do + if os.getenv(k) then + vs = v + break + end + end + end + + -- probe ok? update it + if vs then + -- save it + configs.set("vs", vs) + + -- trace + utils.printf("checking for the Microsoft Visual Studio version ... %s", vs) + else + -- failed + utils.error("checking for the Microsoft Visual Studio version ... no") + utils.error(" - xmake config --vs=xxx") + utils.error("or - xmake global --vs=xxx") + return false + end + + -- ok + return true +end + +-- probe the vs path +function prober._probe_vs_path(configs) + + -- ok? + if configs.get("__vsenv_path") then return true end + + -- get the vs version + local vs = configs.get("vs") + assert(vs) + + -- make the map table + local map = + { + ["2015"] = "VS140COMNTOOLS" + , ["2013"] = "VS120COMNTOOLS" + , ["2012"] = "VS110COMNTOOLS" + , ["2010"] = "VS100COMNTOOLS" + , ["2008"] = "VS90COMNTOOLS" + , ["2005"] = "VS80COMNTOOLS" + , ["2003"] = "VS71COMNTOOLS" + , ["7.0"] = "VS70COMNTOOLS" + , ["6.0"] = "VS60COMNTOOLS" + , ["5.0"] = "VS50COMNTOOLS" + , ["4.2"] = "VS42COMNTOOLS" + } + + -- attempt to get the vs directory from the envirnoment variable + local vsdir = map[vs] + if vsdir then + vsdir = os.getenv(vsdir) + end + if vsdir then + vsdir = vsdir .. "\\..\\.." + end + if not os.isdir(vsdir) then + -- error + utils.error("not found %s", vsdir) + return false + end + + -- the vcvarsall.bat path + local vcvarsall = vsdir .. "\\VC\\vcvarsall.bat" + if not os.isfile(vcvarsall) then + -- error + utils.error("not found %s", vcvarsall) + return false + end + + -- get the temporary directory + local tmpdir = os.tmpdir() + assert(tmpdir) + + -- make the call(vcvarsall.bat) file + local callpath = tmpdir .. "\\call_vcvarsall.bat" + local callfile = io.openmk(callpath) + assert(callfile) + + -- make call scripts + callfile:write("@echo off\n") + callfile:write(string.format("call \"%s\" %s > nul\n", vcvarsall, configs.get("arch"))) + callfile:write("echo return \n") + callfile:write("echo { \n") + callfile:write("echo path = \"%path%\"\n") + callfile:write("echo , lib = \"%lib%\"\n") + callfile:write("echo , libpath = \"%libpath%\"\n") + callfile:write("echo , include = \"%include%\"\n") + callfile:write("echo , devenvdir = \"%devenvdir%\"\n") + callfile:write("echo , vsinstalldir = \"%vsinstalldir%\"\n") + callfile:write("echo , vcinstalldir = \"%vcinstalldir%\"\n") + callfile:write("echo } \n") + + -- close the file + callfile:close() + + -- execute the call(vsvars32.bat) file and get all envirnoment variables + local cmd = io.popen(callpath) + local results = cmd:read("*all") + cmd:close() + + -- translate '\' => '\\' + results = results:gsub("\\", "\\\\") + + -- get all envirnoment variables + local variables = assert(loadstring(results))() + if not variables or not variables.path then + return false + end + + -- save the variables + for k, v in pairs(variables) do + configs.set("__vsenv_" .. k, v) + end + + -- ok + return true +end + +-- probe the tool path +function prober._probe_toolpath(configs, kind, name, description) + + -- check + assert(kind) + + -- attempt to get it directly from the configure + local toolpath = configs.get(kind) + if toolpath then return true end + + -- make cmd + local cmd = string.format("%s > %s 2>&1", name, xmake._NULDEV) + if kind == "ld" then + cmd = string.format("%s nul > %s 2>&1", name, xmake._NULDEV) + end + + -- attempt to run it directly first + if not toolpath and os.execute(cmd) ~= 1 then + toolpath = name + end + + -- probe ok? update it + if toolpath then configs.set(kind, toolpath) end + + -- trace + if toolpath then + utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) + else + utils.printf("checking for %s (%s) ... no", description, kind) + end + + -- failed? + if not toolpath and (kind == "cc" or kind == "ld" or kind == "make") then + return false + end + + -- ok + return true +end + +-- probe the toolchains +function prober._probe_toolchains(configs) + + -- the windows module + local windows = platform.module() + assert(windows) + + -- enter envirnoment + windows.enter() + + -- done + if not prober._probe_toolpath(configs, "cc", "cl.exe", "the c compiler") then return false end + if not prober._probe_toolpath(configs, "cxx", "cl.exe", "the c++ compiler") then return false end + if not prober._probe_toolpath(configs, "as", "ml.exe", "the assember") then return false end + if not prober._probe_toolpath(configs, "ld", "link.exe", "the linker") then return false end + if not prober._probe_toolpath(configs, "ar", "link.exe -lib", "the static library linker") then return false end + if not prober._probe_toolpath(configs, "sh", "link.exe -dll", "the shared library linker") then return false end + if not prober._probe_toolpath(configs, "ex", "lib.exe", "the library extractor") then return false end + if not prober._probe_toolpath(configs, "make", "nmake.exe", "the make") then return false end + + -- leave envirnoment + windows.leave() + + -- ok + return true +end + +-- probe the project configure +function prober.config() + + -- call all probe functions + return utils.call( { prober._probe_arch + , prober._probe_vs_version + , prober._probe_vs_path + , prober._probe_toolchains} + , nil + , config) +end + +-- probe the global configure +function prober.global() + + -- call all probe functions + return utils.call( { prober._probe_vs_version + , prober._probe_vs_path} + , nil + , global) +end + +-- return module: prober +return prober diff --git a/xmake/core/platform/windows/tools/cl.lua b/xmake/core/platform/windows/tools/cl.lua new file mode 100644 index 000000000..299960bb8 --- /dev/null +++ b/xmake/core/platform/windows/tools/cl.lua @@ -0,0 +1,139 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file cl.lua +-- + +-- define module: cl +local cl = cl or {} + +-- load modules +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") +local platform = require("platform/platform") + +-- init the compiler +function cl.init(self, name) + + -- save name + self.name = name or "cl.exe" + + -- init cxflags + self.cxflags = { "-nologo", "-Gd", "-MP4", "-D_MBCS", "-D_CRT_SECURE_NO_WARNINGS"} + + -- init flags map + self.mapflags = + { + -- optimize + ["-O0"] = "-Od" + , ["-O3"] = "-Ot" + , ["-Ofast"] = "-Ox" + , ["-fomit-frame-pointer"] = "-Oy" + + -- symbols + , ["-g"] = "-Z7" + , ["-fvisibility=.*"] = "" + + -- warnings + , ["-Wall"] = "-W3" -- = "-Wall" will enable too more warnings + , ["-W1"] = "-W1" + , ["-W2"] = "-W2" + , ["-W3"] = "-W3" + , ["-Werror"] = "-WX" + , ["%-Wno%-error=.*"] = "" + , ["%-fno%-.*"] = "" + + -- vectorexts + , ["-mmmx"] = "-arch:MMX" + , ["-msse"] = "-arch:SSE" + , ["-msse2"] = "-arch:SSE2" + , ["-msse3"] = "-arch:SSE3" + , ["-mssse3"] = "-arch:SSSE3" + , ["-mavx"] = "-arch:AVX" + , ["-mavx2"] = "-arch:AVX2" + , ["-mfpu=.*"] = "" + + -- language + , ["-ansi"] = "" + , ["-std=c99"] = "-TP" -- compile as c++ files because msvc only support c89 + , ["-std=gnu99"] = "-TP" -- compile as c++ files because msvc only support c89 + , ["-std=.*"] = "" + + -- others + , ["-ftrapv"] = "" + , ["-fsanitize=address"] = "" + } + +end + +-- make the compiler command +function cl.command_compile(self, srcfile, objfile, flags, logfile) + + -- redirect + local redirect = "" + if logfile then redirect = string.format(" > %s 2>&1", logfile) end + + -- make it + return string.format("%s -c %s -Fo%s %s%s", self.name, flags, objfile, srcfile, redirect) +end + +-- make the define flag +function cl.flag_define(self, define) + + -- make it + return "-D" .. define:gsub("\"", "\\\"") +end + +-- make the undefine flag +function cl.flag_undefine(self, undefine) + + -- make it + return "-U" .. undefine +end + +-- make the includedir flag +function cl.flag_includedir(self, includedir) + + -- make it + return "-I" .. includedir +end + +-- the main function +function cl.main(self, cmd) + + -- the windows module + local windows = platform.module() + assert(windows) + + -- enter envirnoment + windows.enter() + + -- execute it + local ok = os.execute(cmd) + + -- leave envirnoment + windows.leave() + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: cl +return cl diff --git a/xmake/core/platform/windows/tools/lib.lua b/xmake/core/platform/windows/tools/lib.lua new file mode 100644 index 000000000..1d94152cc --- /dev/null +++ b/xmake/core/platform/windows/tools/lib.lua @@ -0,0 +1,138 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file lib.lua +-- + +-- define module: lib +local lib = lib or {} + +-- load modules +local io = require("base/io") +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") +local platform = require("platform/platform") + +-- init the compiler +function lib.init(self, name) + + -- save name + self.name = name or "lib.exe" + +end + +-- extract the static library to object files +function lib.extract(self, ...) + + -- check + local args = ... + assert(#args == 2 and self.name) + + -- get library and object file path + local libfile = args[1] + local objfile = args[2] + assert(libfile and objfile) + + -- get object directory + local objdir = path.directory(objfile) + if not os.isdir(objdir) then os.mkdir(objdir) end + if not os.isdir(objdir) then + utils.error("%s not found!", objdir) + return false + end + + -- the windows module + local windows = platform.module() + assert(windows) + + -- enter envirnoment + windows.enter() + + -- list object files + local file = io.popen(string.format("%s -nologo -list %s", self.name, libfile)) + if not file then + utils.error("extract %s to %s failed!", libfile, objdir) + windows.leave() + return false + end + + -- extrace all object files + for line in file:lines() do + + -- is object file? + if line:find("%.obj") then + + -- init command + local out = path.translate(string.format("%s\\%s", objdir, path.filename(line))) + + -- repeat? rename it + if os.isfile(out) then + for i = 0, 10 do + out = path.translate(string.format("%s\\%d_%s", objdir, i, path.filename(line))) + if not os.isfile(out) then break end + end + end + + -- init command + local cmd = string.format("%s -nologo -extract:%s -out:%s %s", self.name, line, out, libfile) + + -- extract it + if 0 ~= os.execute(cmd) then + utils.error("extract %s to %s failed!", libfile, objdir) + windows.leave() + return false + end + end + end + + -- exit file + file:close() + + -- leave envirnoment + windows.leave() + + -- ok + return true +end + +-- the main function +function lib.main(self, cmd) + + -- the windows module + local windows = platform.module() + assert(windows) + + -- enter envirnoment + windows.enter() + + -- execute it + local ok = os.execute(cmd) + + -- leave envirnoment + windows.leave() + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: lib +return lib diff --git a/xmake/core/platform/windows/tools/link.lua b/xmake/core/platform/windows/tools/link.lua new file mode 100644 index 000000000..66476fa41 --- /dev/null +++ b/xmake/core/platform/windows/tools/link.lua @@ -0,0 +1,128 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file link.lua +-- + +-- define module: link +local link = link or {} + +-- load modules +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") +local platform = require("platform/platform") + +-- init the compiler +function link.init(self, name) + + -- save name + self.name = name or "link.exe" + + -- the architecture + local arch = config.get("arch") + assert(arch) + + -- init flags for architecture + local flags_arch = "" + if arch == "x86" then flags_arch = "-machine:x86" + elseif arch == "x64" or arch == "amd64" or arch == "x86_amd64" then flags_arch = "-machine:x64" + end + + -- init ldflags + self.ldflags = { "-nologo" + , "-dynamicbase" + , "-nxcompat" + , flags_arch} + + -- init arflags + self.arflags = {"-nologo", flags_arch} + + -- init shflags + self.shflags = {"-nologo", flags_arch} + + -- init flags map + self.mapflags = + { + -- strip + ["-s"] = "" + , ["-S"] = "" + + -- others + , ["-ftrapv"] = "" + , ["-fsanitize=address"] = "" + } + +end + +-- make the linker command +function link.command_link(self, objfiles, targetfile, flags, logfile) + + -- redirect + local redirect = "" + if logfile then redirect = string.format(" > %s 2>&1", logfile) end + + -- make it + local cmd = string.format("%s %s -out:%s %s%s", self.name, flags, targetfile, objfiles, redirect) + + -- too long? + if #cmd > 256 then + cmd = string.format("%s%s @<<\n%s -out:%s %s\n<<", self.name, redirect, flags, targetfile, objfiles) + end + + -- ok? + return cmd +end + +-- make the link flag +function link.flag_link(self, link) + + -- make it + return link .. ".lib" +end + +-- make the linkdir flag +function link.flag_linkdir(self, linkdir) + + -- make it + return "-libpath:" .. linkdir +end + +-- the main function +function link.main(self, cmd) + + -- the windows module + local windows = platform.module() + assert(windows) + + -- enter envirnoment + windows.enter() + + -- execute it + local ok = os.execute(cmd) + + -- leave envirnoment + windows.leave() + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: link +return link diff --git a/xmake/core/platform/windows/tools/ml.lua b/xmake/core/platform/windows/tools/ml.lua new file mode 100644 index 000000000..5a6034320 --- /dev/null +++ b/xmake/core/platform/windows/tools/ml.lua @@ -0,0 +1,132 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file ml.lua +-- + +-- define module: ml +local ml = ml or {} + +-- load modules +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") +local platform = require("platform/platform") + +-- init the compiler +function ml.init(self, name) + + -- save name + self.name = name or "ml.exe" + + -- init asflags + self.asflags = { "-nologo", "-Gd", "-MP4", "-D_MBCS", "-D_CRT_SECURE_NO_WARNINGS"} + + -- init flags map + self.mapflags = + { + -- optimize + ["-O0"] = "-Od" + , ["-O3"] = "-Ot" + , ["-Ofast"] = "-Ox" + , ["-fomit-frame-pointer"] = "-Oy" + + -- symbols + , ["-g"] = "-Z7" + , ["-fvisibility=.*"] = "" + + -- warnings + , ["-Wall"] = "-W3" -- = "-Wall" will enable too more warnings + , ["-W1"] = "-W1" + , ["-W2"] = "-W2" + , ["-W3"] = "-W3" + , ["-Werror"] = "-WX" + , ["%-Wno%-error=.*"] = "" + + -- vectorexts + , ["-mmmx"] = "-arch:MMX" + , ["-msse"] = "-arch:SSE" + , ["-msse2"] = "-arch:SSE2" + , ["-msse3"] = "-arch:SSE3" + , ["-mssse3"] = "-arch:SSSE3" + , ["-mavx"] = "-arch:AVX" + , ["-mavx2"] = "-arch:AVX2" + , ["-mfpu=.*"] = "" + + -- others + , ["-ftrapv"] = "" + , ["-fsanitize=address"] = "" + } + +end + +-- make the compiler command +function ml.command_compile(self, srcfile, objfile, flags, logfile) + + -- redirect + local redirect = "" + if logfile then redirect = string.format(" > %s 2>&1", logfile) end + + -- make it + return string.format("%s -c %s -Fo%s %s%s", self.name, flags, objfile, srcfile, redirect) +end + +-- make the define flag +function ml.flag_define(self, define) + + -- make it + return "-D" .. define:gsub("\"", "\\\"") +end + +-- make the undefine flag +function ml.flag_undefine(self, undefine) + + -- make it + return "-U" .. undefine +end + +-- make the includedir flag +function ml.flag_includedir(self, includedir) + + -- make it + return "-I" .. includedir +end + +-- the main function +function ml.main(self, cmd) + + -- the windows module + local windows = platform.module() + assert(windows) + + -- enter envirnoment + windows.enter() + + -- execute it + local ok = os.execute(cmd) + + -- leave envirnoment + windows.leave() + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: ml +return ml diff --git a/xmake/core/platform/windows/tools/nmake.lua b/xmake/core/platform/windows/tools/nmake.lua new file mode 100644 index 000000000..3dddc7cf2 --- /dev/null +++ b/xmake/core/platform/windows/tools/nmake.lua @@ -0,0 +1,74 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file nmake.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") +local platform = require("platform/platform") + +-- define module: nmake +local nmake = nmake or {} + +-- the init function +function nmake.init(self, name) + + -- save name + self.name = name or "nmake.exe" + + -- is verbose? + self._VERBOSE = utils.ifelse(xmake._OPTIONS.verbose, "-v", "") + +end + +-- the main function +function nmake.main(self, mkfile, target) + + -- the windows module + local windows = platform.module() + assert(windows) + + -- enter envirnoment + windows.enter() + + -- make command + local cmd = nil + if mkfile and os.isfile(mkfile) then + cmd = string.format("%s /nologo /f %s %s VERBOSE=%s", self.name, mkfile, target or "", self._VERBOSE) + else + cmd = string.format("%s /nologo %s VERBOSE=%s", self.name, target or "", self._VERBOSE) + end + + -- done + local ok = os.execute(cmd) + + -- leave envirnoment + windows.leave() + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: nmake +return nmake diff --git a/xmake/core/platform/windows/windows.lua b/xmake/core/platform/windows/windows.lua new file mode 100644 index 000000000..794358dc1 --- /dev/null +++ b/xmake/core/platform/windows/windows.lua @@ -0,0 +1,144 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file windows.lua +-- + +-- define module: windows +local windows = windows or {} + +-- load modules +local os = require("base/os") +local config = require("base/config") + +-- init host +windows._HOST = "windows" + +-- init os +windows._OS = "windows" + +-- init architectures +windows._ARCHS = {"x86", "x64", "amd64", "x86_amd64"} + +-- enter the given environment +function windows._enter(name) + + -- check + assert(name) + + -- get the pathes for the vs environment + local old = nil + local new = config.get("__vsenv_" .. name) + if new then + + -- get the current pathes + old = os.getenv(name) or "" + + -- append the current pathes + new = new .. ";" .. old + + -- update the pathes for the environment + os.setenv(name, new) + end + + -- return the previous environment + return old; +end + +-- leave the given environment +function windows._leave(name, old) + + -- check + assert(name) + + -- restore the previous environment + if old then + os.setenv(name, old) + end +end + +-- enter environment +function windows.enter() + + -- enter the vs environment + windows._pathes = windows._enter("path") + windows._libs = windows._enter("lib") + windows._includes = windows._enter("include") + windows._libpathes = windows._enter("libpath") + +end + +-- leave environment +function windows.leave() + + -- leave the vs environment + windows._leave("path", windows._pathes) + windows._leave("lib", windows._libs) + windows._leave("include", windows._includes) + windows._leave("libpath", windows._libpathes) + +end +-- make configure +function windows.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"", ".lib"} + configs.formats.object = {"", ".obj"} + configs.formats.shared = {"", ".dll"} + configs.formats.binary = {"", ".exe"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = config.get("make") + configs.tools.cc = config.get("cc") + configs.tools.cxx = config.get("cxx") + configs.tools.ld = config.get("ld") + configs.tools.ar = config.get("ar") + configs.tools.sh = config.get("sh") + configs.tools.as = config.get("as") + configs.tools.ex = config.get("ex") +end + +-- get the option menu for action: xmake config or global +function windows.menu(action) + + -- init config option menu + windows._MENU_CONFIG = windows._MENU_CONFIG or + { {} + , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } + , } + + -- init global option menu + windows._MENU_GLOBAL = windows._MENU_GLOBAL or + { {} + , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } + , } + + -- get the option menu + if action == "config" then + return windows._MENU_CONFIG + elseif action == "global" then + return windows._MENU_GLOBAL + end +end + + +-- return module: windows +return windows diff --git a/xmake/core/tools/ar.lua b/xmake/core/tools/ar.lua new file mode 100644 index 000000000..75e63f83d --- /dev/null +++ b/xmake/core/tools/ar.lua @@ -0,0 +1,114 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file ar.lua +-- + +-- define module: ar +local ar = ar or {} + +-- load modules +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") + +-- init the linker +function ar.init(self, name) + + -- save name + self.name = name or "ar" + + -- init arflags + self.arflags = { "-crs" } + +end + +-- make the link command +function ar.command_link(self, objfiles, targetfile, flags, logfile) + + -- redirect + local redirect = "" + if logfile then redirect = string.format(" > %s 2>&1", logfile) end + + -- make it + return string.format("%s %s %s %s%s", self.name, flags, targetfile, objfiles, redirect) +end + +-- extract the static library to object files +function ar.extract(self, ...) + + -- check + local args = ... + assert(#args == 2 and self.name) + + -- get library and object file path + local libfile = args[1] + local objfile = args[2] + assert(libfile and objfile) + + -- get object directory + local objdir = path.directory(objfile) + if not os.isdir(objdir) then os.mkdir(objdir) end + if not os.isdir(objdir) then + utils.error("%s not found!", objdir) + return false + end + + -- absolute the library path + libfile = path.absolute(libfile) + assert(libfile) + + -- enter the object directory + ok, errors = os.cd(objdir) + if not ok then + utils.error(errors) + return false + end + + -- extract it + local ok = self:main(string.format("%s -x %s", self.name, libfile)) + if not ok then + utils.error("extract %s to %s failed!", libfile, objdir) + return false + end + + -- leave the object directory + ok, errors = os.cd("-") + if not ok then + utils.error(errors) + return false + end + + -- ok + return true +end + + +-- the main function +function ar.main(self, cmd) + + -- execute it + local ok = os.execute(cmd) + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: ar +return ar diff --git a/xmake/core/tools/cat.lua b/xmake/core/tools/cat.lua new file mode 100644 index 000000000..32fea4e24 --- /dev/null +++ b/xmake/core/tools/cat.lua @@ -0,0 +1,43 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file cat.lua +-- + +-- define module: cat +local cat = cat or {} + +-- load modules +local io = require("base/io") +local os = require("base/os") + +-- the main function +function cat.main(self, ...) + + -- cat all + for _, v in ipairs(...) do + if os.isfile(v) then io.cat(v) end + end + + -- ok + return true +end + +-- return module: cat +return cat diff --git a/xmake/core/tools/clang++.lua b/xmake/core/tools/clang++.lua new file mode 100644 index 000000000..37352dec4 --- /dev/null +++ b/xmake/core/tools/clang++.lua @@ -0,0 +1,38 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file clang.lua +-- + +-- load modules +local gcc = require("tools/gcc") + +-- define module: clang++ +local clangxx = clangxx or {} + +-- only copy the interfaces of gcc to clang++ +for k, v in pairs(gcc) do + if type(v) == "function" then + clangxx[k] = v + end +end + +-- return module: clang++ +return clangxx + diff --git a/xmake/core/tools/clang.lua b/xmake/core/tools/clang.lua new file mode 100644 index 000000000..280ae73a6 --- /dev/null +++ b/xmake/core/tools/clang.lua @@ -0,0 +1,38 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file clang.lua +-- + +-- load modules +local gcc = require("tools/gcc") + +-- define module: clang +local clang = clang or {} + +-- only copy the interfaces of gcc to clang +for k, v in pairs(gcc) do + if type(v) == "function" then + clang[k] = v + end +end + +-- return module: clang +return clang + diff --git a/xmake/core/tools/cp.lua b/xmake/core/tools/cp.lua new file mode 100644 index 000000000..1b3ba9843 --- /dev/null +++ b/xmake/core/tools/cp.lua @@ -0,0 +1,44 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file cp.lua +-- + +-- define module: cp +local cp = cp or {} + +-- load modules +local os = require("base/os") + +-- the main function +function cp.main(self, ...) + + -- cp it + local pathes = ... + if pathes and table.getn(pathes) == 2 then + return os.cp(pathes[1], pathes[2]) + end + + -- failed + return false + +end + +-- return module: cp +return cp diff --git a/xmake/core/tools/dispatcher.lua b/xmake/core/tools/dispatcher.lua new file mode 100644 index 000000000..d019937ec --- /dev/null +++ b/xmake/core/tools/dispatcher.lua @@ -0,0 +1,80 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file dispatcher.lua +-- + +-- define module: dispatcher +local dispatcher = dispatcher or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local tools = require("tools/tools") + +-- the main function +-- +-- dispatcher toolname toolpath action arguments ... +function dispatcher.main(self, ...) + + -- check + local args = ... + assert(#args >= 2) + + -- get tool kind and action name + local tool_kind = args[1] + local action_name = args[2] + assert(tool_kind and action_name) + + -- get the tool + local tool = tools.get(tool_kind) + if tool then + + -- load action + local action = tool[action_name] + if action then + + -- init arguments for action + local action_args = {} + for i = 3, #args do + table.insert(action_args, args[i]:decode()) + end + + -- done action + if not action(tool, action_args) then + utils.error("run action %s failed!", action_name) + assert(false) + end + else + utils.error("load action %s failed!", action_name) + assert(false) + end + + else + assert(false) + end + + -- ok + return true +end + +-- return module: dispatcher +return dispatcher diff --git a/xmake/core/tools/echo.lua b/xmake/core/tools/echo.lua new file mode 100644 index 000000000..dbfa67426 --- /dev/null +++ b/xmake/core/tools/echo.lua @@ -0,0 +1,44 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file echo.lua +-- + +-- define module: echo +local echo = echo or {} + +-- load modules +local io = require("base/io") +local string = require("base/string") + +-- the main function +function echo.main(self, ...) + + -- echo all + for _, v in ipairs(...) do + io.write(string.format("%s ", v:decode())) + end + io.write("\n") + + -- ok + return true +end + +-- return module: echo +return echo diff --git a/xmake/core/tools/g++.lua b/xmake/core/tools/g++.lua new file mode 100644 index 000000000..64970b039 --- /dev/null +++ b/xmake/core/tools/g++.lua @@ -0,0 +1,38 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file g++.lua +-- + +-- load modules +local gcc = require("tools/gcc") + +-- define module: gxx +local gxx = gxx or {} + +-- only copy the interfaces of gcc to g++ +for k, v in pairs(gcc) do + if type(v) == "function" then + gxx[k] = v + end +end + +-- return module: g++ +return gxx + diff --git a/xmake/core/tools/gas-preprocessor.pl b/xmake/core/tools/gas-preprocessor.pl new file mode 100755 index 000000000..98dfe4ad9 --- /dev/null +++ b/xmake/core/tools/gas-preprocessor.pl @@ -0,0 +1,1025 @@ +#!/usr/bin/env perl +# by David Conrad +# This code is licensed under GPLv2 or later; go to gnu.org to read it +# (not that it much matters for an asm preprocessor) +# usage: set your assembler to be something like "perl gas-preprocessor.pl gcc" +use strict; + +# Apple's gas is ancient and doesn't support modern preprocessing features like +# .rept and has ugly macro syntax, among other things. Thus, this script +# implements the subset of the gas preprocessor used by x264 and ffmpeg +# that isn't supported by Apple's gas. + +my %canonical_arch = ("aarch64" => "aarch64", "arm64" => "aarch64", + "arm" => "arm", + "powerpc" => "powerpc", "ppc" => "powerpc"); + +my %comments = ("aarch64" => '//', + "arm" => '@', + "powerpc" => '#'); + +my @gcc_cmd; +my @preprocess_c_cmd; + +my $comm; +my $arch; +my $as_type = "apple-gas"; + +my $fix_unreq = $^O eq "darwin"; +my $force_thumb = 0; + +my $arm_cond_codes = "eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo"; + +my $usage_str = " +$0\n +Gas-preprocessor.pl converts assembler files using modern GNU as syntax for +Apple's ancient gas version or clang's incompatible integrated assembler. The +conversion is regularly tested for Libav, x264 and vlc. Other projects might +use different features which are not correctly handled. + +Options for this program needs to be separated with ' -- ' from the assembler +command. Following options are currently supported: + + -help - this usage text + -arch - target architecture + -as-type - one value out of {{,apple-}{gas,clang},armasm} + -fix-unreq + -no-fix-unreq + -force-thumb - assemble as thumb regardless of the input source + (note, this is incomplete and only works for sources + it explicitly was tested with) +"; + +sub usage() { + print $usage_str; +} + +while (@ARGV) { + my $opt = shift; + + if ($opt =~ /^-(no-)?fix-unreq$/) { + $fix_unreq = $1 ne "no-"; + } elsif ($opt eq "-force-thumb") { + $force_thumb = 1; + } elsif ($opt eq "-arch") { + $arch = shift; + die "unknown arch: '$arch'\n" if not exists $comments{$arch}; + } elsif ($opt eq "-as-type") { + $as_type = shift; + die "unknown as type: '$as_type'\n" if $as_type !~ /^((apple-)?(gas|clang)|armasm)$/; + } elsif ($opt eq "-help") { + usage(); + exit 0; + } elsif ($opt eq "--" ) { + @gcc_cmd = @ARGV; + } elsif ($opt =~ /^-/) { + die "option '$opt' is not known. See '$0 -help' for usage information\n"; + } else { + push @gcc_cmd, $opt, @ARGV; + } + last if (@gcc_cmd); +} + +if (grep /\.c$/, @gcc_cmd) { + # C file (inline asm?) - compile + @preprocess_c_cmd = (@gcc_cmd, "-S"); +} elsif (grep /\.[sS]$/, @gcc_cmd) { + # asm file, just do C preprocessor + @preprocess_c_cmd = (@gcc_cmd, "-E"); +} elsif (grep /-(v|-version|dumpversion)/, @gcc_cmd) { + # pass -v/--version along, used during probing. Matching '-v' might have + # uninteded results but it doesn't matter much if gas-preprocessor or + # the compiler fails. + exec(@gcc_cmd); +} else { + die "Unrecognized input filetype"; +} +if ($as_type eq "armasm") { + + $preprocess_c_cmd[0] = "cpp"; + + @preprocess_c_cmd = grep ! /^-nologo$/, @preprocess_c_cmd; + # Remove -ignore XX parameter pairs from preprocess_c_cmd + my $index = 1; + while ($index < $#preprocess_c_cmd) { + if ($preprocess_c_cmd[$index] eq "-ignore" and $index + 1 < $#preprocess_c_cmd) { + splice(@preprocess_c_cmd, $index, 2); + next; + } + $index++; + } + if (grep /^-MM$/, @preprocess_c_cmd) { + system(@preprocess_c_cmd) == 0 or die "Error running preprocessor"; + exit 0; + } +} + +# if compiling, avoid creating an output file named '-.o' +if ((grep /^-c$/, @gcc_cmd) && !(grep /^-o/, @gcc_cmd)) { + foreach my $i (@gcc_cmd) { + if ($i =~ /\.[csS]$/) { + my $outputfile = $i; + $outputfile =~ s/\.[csS]$/.o/; + push(@gcc_cmd, "-o"); + push(@gcc_cmd, $outputfile); + last; + } + } +} +# replace only the '-o' argument with '-', avoids rewriting the make dependency +# target specified with -MT to '-' +my $index = 1; +while ($index < $#preprocess_c_cmd) { + if ($preprocess_c_cmd[$index] eq "-o") { + $index++; + $preprocess_c_cmd[$index] = "-"; + } + $index++; +} + +my $tempfile; +if ($as_type ne "armasm") { + @gcc_cmd = map { /\.[csS]$/ ? qw(-x assembler -) : $_ } @gcc_cmd; +} else { + @preprocess_c_cmd = grep ! /^-c$/, @preprocess_c_cmd; + @preprocess_c_cmd = grep ! /^-m/, @preprocess_c_cmd; + + @preprocess_c_cmd = grep ! /^-G/, @preprocess_c_cmd; + @preprocess_c_cmd = grep ! /^-W/, @preprocess_c_cmd; + @preprocess_c_cmd = grep ! /^-Z/, @preprocess_c_cmd; + @preprocess_c_cmd = grep ! /^-fp/, @preprocess_c_cmd; + @preprocess_c_cmd = grep ! /^-EHsc$/, @preprocess_c_cmd; + @preprocess_c_cmd = grep ! /^-O/, @preprocess_c_cmd; + + @gcc_cmd = grep ! /^-G/, @gcc_cmd; + @gcc_cmd = grep ! /^-W/, @gcc_cmd; + @gcc_cmd = grep ! /^-Z/, @gcc_cmd; + @gcc_cmd = grep ! /^-fp/, @gcc_cmd; + @gcc_cmd = grep ! /^-EHsc$/, @gcc_cmd; + @gcc_cmd = grep ! /^-O/, @gcc_cmd; + + my @outfiles = grep /\.(o|obj)$/, @gcc_cmd; + $tempfile = $outfiles[0].".asm"; + + # Remove most parameters from gcc_cmd, which actually is the armasm command, + # which doesn't support any of the common compiler/preprocessor options. + @gcc_cmd = grep ! /^-D/, @gcc_cmd; + @gcc_cmd = grep ! /^-U/, @gcc_cmd; + @gcc_cmd = grep ! /^-m/, @gcc_cmd; + @gcc_cmd = grep ! /^-M/, @gcc_cmd; + @gcc_cmd = grep ! /^-c$/, @gcc_cmd; + @gcc_cmd = grep ! /^-I/, @gcc_cmd; + @gcc_cmd = map { /\.S$/ ? $tempfile : $_ } @gcc_cmd; +} + +# detect architecture from gcc binary name +if (!$arch) { + if ($gcc_cmd[0] =~ /(arm64|aarch64|arm|powerpc|ppc)/) { + $arch = $1; + } else { + # look for -arch flag + foreach my $i (1 .. $#gcc_cmd-1) { + if ($gcc_cmd[$i] eq "-arch" and + $gcc_cmd[$i+1] =~ /(arm64|aarch64|arm|powerpc|ppc)/) { + $arch = $1; + } + } + } +} + +# assume we're not cross-compiling if no -arch or the binary doesn't have the arch name +$arch = qx/arch/ if (!$arch); + +die "Unknown target architecture '$arch'" if not exists $canonical_arch{$arch}; + +$arch = $canonical_arch{$arch}; +$comm = $comments{$arch}; +my $inputcomm = $comm; +$comm = ";" if $as_type =~ /armasm/; + +my %ppc_spr = (ctr => 9, + vrsave => 256); + +open(INPUT, "-|", @preprocess_c_cmd) || die "Error running preprocessor"; + +if ($ENV{GASPP_DEBUG}) { + open(ASMFILE, ">&STDOUT"); +} else { + if ($as_type ne "armasm") { + open(ASMFILE, "|-", @gcc_cmd) or die "Error running assembler"; + } else { + open(ASMFILE, ">", $tempfile); + } +} + +my $current_macro = ''; +my $macro_level = 0; +my $rept_level = 0; +my %macro_lines; +my %macro_args; +my %macro_args_default; +my $macro_count = 0; +my $altmacro = 0; +my $in_irp = 0; + +my $num_repts; +my @rept_lines; + +my @irp_args; +my $irp_param; + +my @ifstack; + +my %symbols; + +my @sections; + +my %literal_labels; # for ldr , = +my $literal_num = 0; +my $literal_expr = ".word"; +$literal_expr = ".quad" if $arch eq "aarch64"; + +my $thumb = 0; + +my %thumb_labels; +my %call_targets; +my %mov32_targets; + +my %neon_alias_reg; +my %neon_alias_type; + +my $temp_label_next = 0; +my %last_temp_labels; +my %next_temp_labels; + +my %labels_seen; + +my %aarch64_req_alias; + +if ($force_thumb) { + parse_line(".thumb\n"); +} + +# pass 1: parse .macro +# note that the handling of arguments is probably overly permissive vs. gas +# but it should be the same for valid cases +while () { + # remove all comments (to avoid interfering with evaluating directives) + s/(? 0) { + $ifstack[-1] = -$ifstack[-1]; + } + return 1; + } elsif ($line =~ /\.else/) { + $ifstack[-1] = !$ifstack[-1]; + return 1; + } elsif (handle_if($line)) { + return 1; + } + } + + # discard lines in false .if blocks + foreach my $i (0 .. $#ifstack) { + if ($ifstack[$i] <= 0) { + return 1; + } + } + } + return 0; +} + +sub parse_line { + my $line = $_[0]; + + return if (parse_if_line($line)); + + if (scalar(@rept_lines) == 0) { + if (/\.macro/) { + $macro_level++; + if ($macro_level > 1 && !$current_macro) { + die "nested macros but we don't have master macro"; + } + } elsif (/\.endm/) { + $macro_level--; + if ($macro_level < 0) { + die "unmatched .endm"; + } elsif ($macro_level == 0) { + $current_macro = ''; + return; + } + } + } + + if ($macro_level == 0) { + if ($line =~ /\.(rept|irp)/) { + $rept_level++; + } elsif ($line =~ /.endr/) { + $rept_level--; + } + } + + if ($macro_level > 1) { + push(@{$macro_lines{$current_macro}}, $line); + } elsif (scalar(@rept_lines) and $rept_level >= 1) { + push(@rept_lines, $line); + } elsif ($macro_level == 0) { + expand_macros($line); + } else { + if ($line =~ /\.macro\s+([\d\w\.]+)\s*(.*)/) { + $current_macro = $1; + + # commas in the argument list are optional, so only use whitespace as the separator + my $arglist = $2; + $arglist =~ s/,/ /g; + + my @args = split(/\s+/, $arglist); + foreach my $i (0 .. $#args) { + my @argpair = split(/=/, $args[$i]); + $macro_args{$current_macro}[$i] = $argpair[0]; + $argpair[0] =~ s/:vararg$//; + $macro_args_default{$current_macro}{$argpair[0]} = $argpair[1]; + } + # ensure %macro_lines has the macro name added as a key + $macro_lines{$current_macro} = []; + + } elsif ($current_macro) { + push(@{$macro_lines{$current_macro}}, $line); + } else { + die "macro level without a macro name"; + } + } +} + +sub handle_set { + my $line = $_[0]; + if ($line =~ /\.set\s+(.*),\s*(.*)/) { + $symbols{$1} = eval_expr($2); + return 1; + } + return 0; +} + +sub expand_macros { + my $line = $_[0]; + + # handle .if directives; apple's assembler doesn't support important non-basic ones + # evaluating them is also needed to handle recursive macros + if (handle_if($line)) { + return; + } + + if (/\.purgem\s+([\d\w\.]+)/) { + delete $macro_lines{$1}; + delete $macro_args{$1}; + delete $macro_args_default{$1}; + return; + } + + if ($line =~ /\.altmacro/) { + $altmacro = 1; + return; + } + + if ($line =~ /\.noaltmacro/) { + $altmacro = 0; + return; + } + + $line =~ s/\%([^,]*)/eval_expr($1)/eg if $altmacro; + + # Strip out the .set lines from the armasm output + return if (handle_set($line) and $as_type eq "armasm"); + + if ($line =~ /\.rept\s+(.*)/) { + $num_repts = $1; + @rept_lines = ("\n"); + + # handle the possibility of repeating another directive on the same line + # .endr on the same line is not valid, I don't know if a non-directive is + if ($num_repts =~ s/(\.\w+.*)//) { + push(@rept_lines, "$1\n"); + } + $num_repts = eval_expr($num_repts); + } elsif ($line =~ /\.irp\s+([\d\w\.]+)\s*(.*)/) { + $in_irp = 1; + $num_repts = 1; + @rept_lines = ("\n"); + $irp_param = $1; + + # only use whitespace as the separator + my $irp_arglist = $2; + $irp_arglist =~ s/,/ /g; + $irp_arglist =~ s/^\s+//; + @irp_args = split(/\s+/, $irp_arglist); + } elsif ($line =~ /\.irpc\s+([\d\w\.]+)\s*(.*)/) { + $in_irp = 1; + $num_repts = 1; + @rept_lines = ("\n"); + $irp_param = $1; + + my $irp_arglist = $2; + $irp_arglist =~ s/,/ /g; + $irp_arglist =~ s/^\s+//; + @irp_args = split(//, $irp_arglist); + } elsif ($line =~ /\.endr/) { + my @prev_rept_lines = @rept_lines; + my $prev_in_irp = $in_irp; + my @prev_irp_args = @irp_args; + my $prev_irp_param = $irp_param; + my $prev_num_repts = $num_repts; + @rept_lines = (); + $in_irp = 0; + @irp_args = ''; + + if ($prev_in_irp != 0) { + foreach my $i (@prev_irp_args) { + foreach my $origline (@prev_rept_lines) { + my $line = $origline; + $line =~ s/\\$prev_irp_param/$i/g; + $line =~ s/\\\(\)//g; # remove \() + parse_line($line); + } + } + } else { + for (1 .. $prev_num_repts) { + foreach my $origline (@prev_rept_lines) { + my $line = $origline; + parse_line($line); + } + } + } + } elsif ($line =~ /(\S+:|)\s*([\w\d\.]+)\s*(.*)/ && exists $macro_lines{$2}) { + handle_serialized_line($1); + my $macro = $2; + + # commas are optional here too, but are syntactically important because + # parameters can be blank + my @arglist = split(/,/, $3); + my @args; + my @args_seperator; + + my $comma_sep_required = 0; + foreach (@arglist) { + # allow arithmetic/shift operators in macro arguments + $_ =~ s/\s*(\+|-|\*|\/|<<|>>|<|>)\s*/$1/g; + + my @whitespace_split = split(/\s+/, $_); + if (!@whitespace_split) { + push(@args, ''); + push(@args_seperator, ''); + } else { + foreach (@whitespace_split) { + #print ("arglist = \"$_\"\n"); + if (length($_)) { + push(@args, $_); + my $sep = $comma_sep_required ? "," : " "; + push(@args_seperator, $sep); + #print ("sep = \"$sep\", arg = \"$_\"\n"); + $comma_sep_required = 0; + } + } + } + + $comma_sep_required = 1; + } + + my %replacements; + if ($macro_args_default{$macro}){ + %replacements = %{$macro_args_default{$macro}}; + } + + # construct hashtable of text to replace + foreach my $i (0 .. $#args) { + my $argname = $macro_args{$macro}[$i]; + my @macro_args = @{ $macro_args{$macro} }; + if ($args[$i] =~ m/=/) { + # arg=val references the argument name + # XXX: I'm not sure what the expected behaviour if a lot of + # these are mixed with unnamed args + my @named_arg = split(/=/, $args[$i]); + $replacements{$named_arg[0]} = $named_arg[1]; + } elsif ($i > $#{$macro_args{$macro}}) { + # more args given than the macro has named args + # XXX: is vararg allowed on arguments before the last? + $argname = $macro_args{$macro}[-1]; + if ($argname =~ s/:vararg$//) { + #print "macro = $macro, args[$i] = $args[$i], args_seperator=@args_seperator, argname = $argname, arglist[$i] = $arglist[$i], arglist = @arglist, args=@args, macro_args=@macro_args\n"; + #$replacements{$argname} .= ", $args[$i]"; + $replacements{$argname} .= "$args_seperator[$i] $args[$i]"; + } else { + die "Too many arguments to macro $macro"; + } + } else { + $argname =~ s/:vararg$//; + $replacements{$argname} = $args[$i]; + } + } + + my $count = $macro_count++; + + # apply replacements as regex + foreach (@{$macro_lines{$macro}}) { + my $macro_line = $_; + # do replacements by longest first, this avoids wrong replacement + # when argument names are subsets of each other + foreach (reverse sort {length $a <=> length $b} keys %replacements) { + $macro_line =~ s/\\$_/$replacements{$_}/g; + } + if ($altmacro) { + foreach (reverse sort {length $a <=> length $b} keys %replacements) { + $macro_line =~ s/\b$_\b/$replacements{$_}/g; + } + } + $macro_line =~ s/\\\@/$count/g; + $macro_line =~ s/\\\(\)//g; # remove \() + parse_line($macro_line); + } + } else { + handle_serialized_line($line); + } +} + +sub is_arm_register { + my $name = $_[0]; + if ($name eq "lr" or + $name eq "ip" or + $name =~ /^[rav]\d+$/) { + return 1; + } + return 0; +} + +sub handle_local_label { + my $line = $_[0]; + my $num = $_[1]; + my $dir = $_[2]; + my $target = "$num$dir"; + if ($dir eq "b") { + $line =~ s/$target/$last_temp_labels{$num}/g; + } else { + my $name = "temp_label_$temp_label_next"; + $temp_label_next++; + push(@{$next_temp_labels{$num}}, $name); + $line =~ s/$target/$name/g; + } + return $line; +} + +sub handle_serialized_line { + my $line = $_[0]; + + # handle .previous (only with regard to .section not .subsection) + if ($line =~ /\.(section|text|const_data)/) { + push(@sections, $line); + } elsif ($line =~ /\.previous/) { + if (!$sections[-2]) { + die ".previous without a previous section"; + } + $line = $sections[-2]; + push(@sections, $line); + } + + $thumb = 1 if $line =~ /\.code\s+16|\.thumb/; + $thumb = 0 if $line =~ /\.code\s+32|\.arm/; + + # handle ldr , = + if ($line =~ /(.*)\s*ldr([\w\s\d]+)\s*,\s*=(.*)/ and $as_type ne "armasm") { + my $label = $literal_labels{$3}; + if (!$label) { + $label = "Literal_$literal_num"; + $literal_num++; + $literal_labels{$3} = $label; + } + $line = "$1 ldr$2, $label\n"; + } elsif ($line =~ /\.ltorg/ and $as_type ne "armasm") { + $line .= ".align 2\n"; + foreach my $literal (keys %literal_labels) { + $line .= "$literal_labels{$literal}:\n $literal_expr $literal\n"; + } + %literal_labels = (); + } + + # handle GNU as pc-relative relocations for adrp/add + if ($line =~ /(.*)\s*adrp([\w\s\d]+)\s*,\s*#?:pg_hi21:([^\s]+)/) { + $line = "$1 adrp$2, ${3}\@PAGE\n"; + } elsif ($line =~ /(.*)\s*add([\w\s\d]+)\s*,([\w\s\d]+)\s*,\s*#?:lo12:([^\s]+)/) { + $line = "$1 add$2, $3, ${4}\@PAGEOFF\n"; + } + + # thumb add with large immediate needs explicit add.w + if ($thumb and $line =~ /add\s+.*#([^@]+)/) { + $line =~ s/add/add.w/ if eval_expr($1) > 255; + } + + # mach-o local symbol names start with L (no dot) + $line =~ s/(? with ic as conditional code + if ($cond =~ /|$arm_cond_codes/) { + if (exists $thumb_labels{$label}) { + print ASMFILE ".thumb_func $label\n"; + } else { + $call_targets{$label}++; + } + } + } + + # @l -> lo16() @ha -> ha16() + $line =~ s/,\s+([^,]+)\@l\b/, lo16($1)/g; + $line =~ s/,\s+([^,]+)\@ha\b/, ha16($1)/g; + + # move to/from SPR + if ($line =~ /(\s+)(m[ft])([a-z]+)\s+(\w+)/ and exists $ppc_spr{$3}) { + if ($2 eq 'mt') { + $line = "$1${2}spr $ppc_spr{$3}, $4\n"; + } else { + $line = "$1${2}spr $4, $ppc_spr{$3}\n"; + } + } + + if ($line =~ /\.unreq\s+(.*)/) { + if (defined $neon_alias_reg{$1}) { + delete $neon_alias_reg{$1}; + delete $neon_alias_type{$1}; + return; + } elsif (defined $aarch64_req_alias{$1}) { + delete $aarch64_req_alias{$1}; + return; + } + } + # old gas versions store upper and lower case names on .req, + # but they remove only one on .unreq + if ($fix_unreq) { + if ($line =~ /\.unreq\s+(.*)/) { + $line = ".unreq " . lc($1) . "\n"; + $line .= ".unreq " . uc($1) . "\n"; + } + } + + if ($line =~ /(\w+)\s+\.(dn|qn)\s+(\w+)(?:\.(\w+))?(\[\d+\])?/) { + $neon_alias_reg{$1} = "$3$5"; + $neon_alias_type{$1} = $4; + return; + } + if (scalar keys %neon_alias_reg > 0 && $line =~ /^\s+v\w+/) { + # This line seems to possibly have a neon instruction + foreach (keys %neon_alias_reg) { + my $alias = $_; + # Require the register alias to match as an invididual word, not as a substring + # of a larger word-token. + if ($line =~ /\b$alias\b/) { + $line =~ s/\b$alias\b/$neon_alias_reg{$alias}/g; + # Add the type suffix. If multiple aliases match on the same line, + # only do this replacement the first time (a vfoo.bar string won't match v\w+). + $line =~ s/^(\s+)(v\w+)(\s+)/$1$2.$neon_alias_type{$alias}$3/; + } + } + } + + if ($arch eq "aarch64" or $as_type eq "armasm") { + # clang's integrated aarch64 assembler in Xcode 5 does not support .req/.unreq + if ($line =~ /\b(\w+)\s+\.req\s+(\w+)\b/) { + $aarch64_req_alias{$1} = $2; + return; + } + foreach (keys %aarch64_req_alias) { + my $alias = $_; + # recursively resolve aliases + my $resolved = $aarch64_req_alias{$alias}; + while (defined $aarch64_req_alias{$resolved}) { + $resolved = $aarch64_req_alias{$resolved}; + } + $line =~ s/\b$alias\b/$resolved/g; + } + } + if ($arch eq "aarch64") { + # fix missing aarch64 instructions in Xcode 5.1 (beta3) + # mov with vector arguments is not supported, use alias orr instead + if ($line =~ /^\s*mov\s+(v\d[\.{}\[\]\w]+),\s*(v\d[\.{}\[\]\w]+)\b\s*$/) { + $line = " orr $1, $2, $2\n"; + } + # movi 16, 32 bit shifted variant, shift is optional + if ($line =~ /^\s*movi\s+(v[0-3]?\d\.(?:2|4|8)[hsHS])\s*,\s*(#\w+)\b\s*$/) { + $line = " movi $1, $2, lsl #0\n"; + } + # Xcode 5 misses the alias uxtl. Replace it with the more general ushll. + # Clang 3.4 misses the alias sxtl too. Replace it with the more general sshll. + if ($line =~ /^\s*(s|u)xtl(2)?\s+(v[0-3]?\d\.[248][hsdHSD])\s*,\s*(v[0-3]?\d\.(?:2|4|8|16)[bhsBHS])\b\s*$/) { + $line = " $1shll$2 $3, $4, #0\n"; + } + # clang 3.4 does not automatically use shifted immediates in add/sub + if ($as_type eq "clang" and + $line =~ /^(\s*(?:add|sub)s?) ([^#l]+)#([\d\+\-\*\/ <>]+)\s*$/) { + my $imm = eval $3; + if ($imm > 4095 and not ($imm & 4095)) { + $line = "$1 $2#" . ($imm >> 12) . ", lsl #12\n"; + } + } + if ($ENV{GASPP_FIX_XCODE5}) { + if ($line =~ /^\s*bsl\b/) { + $line =~ s/\b(bsl)(\s+v[0-3]?\d\.(\w+))\b/$1.$3$2/; + $line =~ s/\b(v[0-3]?\d)\.$3\b/$1/g; + } + if ($line =~ /^\s*saddl2?\b/) { + $line =~ s/\b(saddl2?)(\s+v[0-3]?\d\.(\w+))\b/$1.$3$2/; + $line =~ s/\b(v[0-3]?\d)\.\w+\b/$1/g; + } + if ($line =~ /^\s*dup\b.*\]$/) { + $line =~ s/\bdup(\s+v[0-3]?\d)\.(\w+)\b/dup.$2$1/g; + $line =~ s/\b(v[0-3]?\d)\.[bhsdBHSD](\[\d\])$/$1$2/g; + } + } + } + + if ($as_type eq "armasm") { + # Also replace variables set by .set + foreach (keys %symbols) { + my $sym = $_; + $line =~ s/\b$sym\b/$symbols{$sym}/g; + } + + # Handle function declarations and keep track of the declared labels + if ($line =~ s/^\s*\.func\s+(\w+)/$1 PROC/) { + $labels_seen{$1} = 1; + } + + if ($line =~ s/^(\d+)://) { + # Convert local labels into unique labels. armasm (at least in + # RVCT) has something similar, but still different enough. + # By converting to unique labels we avoid any possible + # incompatibilities. + + my $num = $1; + foreach (@{$next_temp_labels{$num}}) { + $line = "$_\n" . $line; + } + @next_temp_labels{$num} = (); + my $name = "temp_label_$temp_label_next"; + $temp_label_next++; + # The matching regexp above removes the label from the start of + # the line (which might contain an instruction as well), readd + # it on a separate line above it. + $line = "$name:\n" . $line; + $last_temp_labels{$num} = $name; + } + + if ($line =~ s/^(\w+):/$1/) { + # Skip labels that have already been declared with a PROC, + # labels must not be declared multiple times. + return if (defined $labels_seen{$1}); + $labels_seen{$1} = 1; + } elsif ($line !~ /(\w+) PROC/) { + # If not a label, make sure the line starts with whitespace, + # otherwise ms armasm interprets it incorrectly. + $line =~ s/^[\.\w]/\t$&/; + } + + + # Check branch instructions + if ($line =~ /(?:^|\n)\s*(\w+\s*:\s*)?(bl?x?(..)?(\.w)?)\s+(\w+)/) { + my $instr = $2; + my $cond = $3; + my $width = $4; + my $target = $5; + # Don't interpret e.g. bic as b with ic as conditional code + if ($cond !~ /|$arm_cond_codes/) { + # Not actually a branch + } elsif ($target =~ /(\d+)([bf])/) { + # The target is a local label + $line = handle_local_label($line, $1, $2); + $line =~ s/\b$instr\b/$&.w/ if $width eq ""; + } elsif (!is_arm_register($target)) { + $call_targets{$target}++; + } + } elsif ($line =~ /^\s*.h?word.*\b\d+[bf]\b/) { + while ($line =~ /\b(\d+)([bf])\b/g) { + $line = handle_local_label($line, $1, $2); + } + } + + # ALIGN in armasm syntax is the actual number of bytes + if ($line =~ /\.align\s+(\d+)/) { + my $align = 1 << $1; + $line =~ s/\.align\s(\d+)/ALIGN $align/; + } + # Convert gas style [r0, :128] into armasm [r0@128] alignment specification + $line =~ s/\[([^\[]+),\s*:(\d+)\]/[$1\@$2]/g; + + # armasm treats logical values {TRUE} and {FALSE} separately from + # numeric values - logical operators and values can't be intermixed + # with numerical values. Evaluate ! and (a <> b) into numbers, + # let the assembler evaluate the rest of the expressions. This current + # only works for cases when ! and <> are used with actual constant numbers, + # we don't evaluate subexpressions here. + + # Evaluate ! + while ($line =~ /!\s*(\d+)/g) { + my $val = ($1 != 0) ? 0 : 1; + $line =~ s/!(\d+)/$val/; + } + # Evaluate (a > b) + while ($line =~ /\(\s*(\d+)\s*([<>])\s*(\d+)\s*\)/) { + my $val; + if ($2 eq "<") { + $val = ($1 < $3) ? 1 : 0; + } else { + $val = ($1 > $3) ? 1 : 0; + } + $line =~ s/\(\s*(\d+)\s*([<>])\s*(\d+)\s*\)/$val/; + } + + # Change a movw... #:lower16: into a mov32 pseudoinstruction + $line =~ s/^(\s*)movw(\s+\w+\s*,\s*)\#:lower16:(.*)$/$1mov32$2$3/; + # and remove the following, matching movt completely + $line =~ s/^\s*movt\s+\w+\s*,\s*\#:upper16:.*$//; + + if ($line =~ /^\s*mov32\s+\w+,\s*([a-zA-Z]\w*)/) { + $mov32_targets{$1}++; + } + + # Misc bugs/deficiencies: + # armasm seems unable to parse e.g. "vmov s0, s1" without a type + # qualifier, thus add .f32. + $line =~ s/^(\s+(?:vmov|vadd))(\s+s)/$1.f32$2/; + # armasm is unable to parse &0x - add spacing + $line =~ s/&0x/& 0x/g; + } + + if ($force_thumb) { + # Convert register post indexing to a separate add instruction. + # This converts e.g. "ldr r0, [r1], r2" into "ldr r0, [r1]", + # "add r1, r1, r2". + $line =~ s/(ldr|str)\s+(\w+),\s*\[(\w+)\],\s*(\w+)/$1 $2, [$3]\n\tadd $3, $3, $4/g; + + # Convert "mov pc, lr" into "bx lr", since the former only works + # for switching from arm to thumb (and only in armv7), but not + # from thumb to arm. + s/mov\s*pc\s*,\s*lr/bx lr/g; + + # Convert stmdb/ldmia with only one register into a plain str/ldr with post-increment/decrement + $line =~ s/stmdb\s+sp!\s*,\s*\{([^,-]+)\}/str $1, [sp, #-4]!/g; + $line =~ s/ldmia\s+sp!\s*,\s*\{([^,-]+)\}/ldr $1, [sp], #4/g; + + $line =~ s/\.arm/.thumb/x; + } + + # comment out unsupported directives + $line =~ s/\.type/$comm$&/x if $as_type =~ /^(apple-|armasm)/; + $line =~ s/\.func/$comm$&/x if $as_type =~ /^(apple-|clang)/; + $line =~ s/\.endfunc/$comm$&/x if $as_type =~ /^(apple-|clang)/; + $line =~ s/\.endfunc/ENDP/x if $as_type =~ /armasm/; + $line =~ s/\.ltorg/$comm$&/x if $as_type =~ /^(apple-|clang)/; + $line =~ s/\.ltorg/LTORG/x if $as_type eq "armasm"; + $line =~ s/\.size/$comm$&/x if $as_type =~ /^(apple-|armasm)/; + $line =~ s/\.fpu/$comm$&/x if $as_type =~ /^(apple-|armasm)/; + $line =~ s/\.arch/$comm$&/x if $as_type =~ /^(apple-|clang|armasm)/; + $line =~ s/\.object_arch/$comm$&/x if $as_type =~ /^(apple-|armasm)/; + $line =~ s/.section\s+.note.GNU-stack.*/$comm$&/x if $as_type =~ /^(apple-|armasm)/; + $line =~ s/\.hidden/$comm$&/x if $as_type =~ /^(apple-|clang|armasm)/; + + $line =~ s/\.syntax/$comm$&/x if $as_type =~ /armasm/; + + $line =~ s/\.hword/.short/x; + + if ($as_type =~ /^apple-/) { + # the syntax for these is a little different + $line =~ s/\.global/.globl/x; + # also catch .section .rodata since the equivalent to .const_data is .section __DATA,__const + $line =~ s/(.*)\.rodata/.const_data/x; + $line =~ s/\.int/.long/x; + $line =~ s/\.float/.single/x; + } + if ($as_type eq "armasm") { + $line =~ s/\.global/EXPORT/x; + $line =~ s/\.int/dcd/x; + $line =~ s/\.long/dcd/x; + $line =~ s/\.float/dcfs/x; + $line =~ s/\.word/dcd/x; + $line =~ s/\.short/dcw/x; + $line =~ s/\.byte/dcb/x; + $line =~ s/\.thumb/THUMB/x; + $line =~ s/\.arm/ARM/x; + # The alignment in AREA is the power of two, just as .align in gas + $line =~ s/\.text/AREA |.text|, CODE, READONLY, ALIGN=2, CODEALIGN/; + $line =~ s/(\s*)(.*)\.rodata/$1AREA |.rodata|, DATA, READONLY, ALIGN=5/; + + $line =~ s/fmxr/vmsr/; + $line =~ s/fmrx/vmrs/; + $line =~ s/fadds/vadd/; + } + + # catch unknown section names that aren't mach-o style (with a comma) + if ($as_type =~ /apple-/ and $line =~ /.section ([^,]*)$/) { + die ".section $1 unsupported; figure out the mach-o section name and add it"; + } + + print ASMFILE $line; +} + +if ($as_type ne "armasm") { + print ASMFILE ".text\n"; + print ASMFILE ".align 2\n"; + foreach my $literal (keys %literal_labels) { + print ASMFILE "$literal_labels{$literal}:\n $literal_expr $literal\n"; + } + + map print(ASMFILE ".thumb_func $_\n"), + grep exists $thumb_labels{$_}, keys %call_targets; +} else { + map print(ASMFILE "\tIMPORT $_\n"), + grep ! exists $labels_seen{$_}, (keys %call_targets, keys %mov32_targets); + + print ASMFILE "\tEND\n"; +} + +close(INPUT) or exit 1; +close(ASMFILE) or exit 1; +if ($as_type eq "armasm" and ! defined $ENV{GASPP_DEBUG}) { + system(@gcc_cmd) == 0 or die "Error running assembler"; +} + +END { + unlink($tempfile) if defined $tempfile; +} +#exit 1 diff --git a/xmake/core/tools/gcc.lua b/xmake/core/tools/gcc.lua new file mode 100644 index 000000000..ab5e94ccb --- /dev/null +++ b/xmake/core/tools/gcc.lua @@ -0,0 +1,192 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file gcc.lua +-- + +-- load modules +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local config = require("base/config") +local platform = require("platform/platform") + +-- define module: gcc +local gcc = gcc or {} + +-- check the given flag +function gcc._check(self, flag) + + -- this flag has been checked? + self._CHECK = self._CHECK or {} + if self._CHECK[flag] then + return self._CHECK[flag] + end + + -- check it + local result = flag + if 0 ~= os.execute(string.format("%s %s -S -o %s -xc %s > %s 2>&1", self.name, flag, xmake._NULDEV, xmake._NULDEV, xmake._NULDEV)) then + result = "" + end + + -- trace + utils.verbose("checking for the compiler flags %s ... %s", flag, utils.ifelse(#result ~= 0, "ok", "no")) + + -- save it + self._CHECK[flag] = result + + -- ok? + return result +end + +-- the init function +function gcc.init(self, name) + + -- save name + self.name = name or "gcc" + + -- init mxflags + self.mxflags = { "-fmessage-length=0" + , "-pipe" + , "-fpascal-strings" + , "\"-DIBOutlet=__attribute__((iboutlet))\"" + , "\"-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))\"" + , "\"-DIBAction=void)__attribute__((ibaction)\""} + + -- init shflags + if name:find("clang") then + self.shflags = { "-dynamiclib", "-fPIC" } + else + self.shflags = { "-shared", "-fPIC" } + end + + -- init cxflags for the kind: shared + self.shared = {} + self.shared.cxflags = {"-fPIC"} + + -- suppress warning for the clang + local isclang = false + if name:find("clang") then + isclang = true + self.cxflags = self.cxflags or {} + self.mxflags = self.mxflags or {} + self.asflags = self.asflags or {} + table.join2(self.cxflags, "-Qunused-arguments") + table.join2(self.mxflags, "-Qunused-arguments") + table.join2(self.asflags, "-Qunused-arguments") + end + + -- init flags map + self.mapflags = + { + -- vectorexts + ["-mmmx"] = self._check + , ["-msse$"] = self._check + , ["-msse2"] = self._check + , ["-msse3"] = self._check + , ["-mssse3"] = self._check + , ["-mavx$"] = self._check + , ["-mavx2"] = self._check + , ["-mfpu=.*"] = self._check + + -- warnings + , ["-W1"] = "-Wall" + , ["-W2"] = "-Wall" + , ["-W3"] = "-Wall" + + -- strip + , ["-s"] = utils.ifelse(isclang, "-Wl,-S", "-s") + , ["-S"] = utils.ifelse(isclang, "-Wl,-S", "-S") + + -- others + , ["-ftrapv"] = self._check + , ["-fsanitize=address"] = self._check + } + +end + +-- make the compile command +function gcc.command_compile(self, srcfile, objfile, flags, logfile) + + -- redirect + local redirect = "" + if logfile then redirect = string.format(" > %s 2>&1", logfile) end + + -- make it + return string.format("%s -c %s -o %s %s%s", self.name, flags, objfile, srcfile, redirect) +end + +-- make the link command +function gcc.command_link(self, objfiles, targetfile, flags, logfile) + + -- redirect + local redirect = "" + if logfile then redirect = string.format(" > %s 2>&1", logfile) end + + -- make it + return string.format("%s -o %s %s %s%s", self.name, targetfile, objfiles, flags, redirect) +end + +-- make the define flag +function gcc.flag_define(self, define) + + -- make it + return "-D" .. define:gsub("\"", "\\\"") +end + +-- make the undefine flag +function gcc.flag_undefine(self, undefine) + + -- make it + return "-U" .. undefine +end + +-- make the includedir flag +function gcc.flag_includedir(self, includedir) + + -- make it + return "-I" .. includedir +end + +-- make the link flag +function gcc.flag_link(self, link) + + -- make it + return "-l" .. link +end + +-- make the linkdir flag +function gcc.flag_linkdir(self, linkdir) + + -- make it + return "-L" .. linkdir +end + +-- the main function +function gcc.main(self, cmd) + + -- execute it + local ok = os.execute(cmd) + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: gcc +return gcc diff --git a/xmake/core/tools/make.lua b/xmake/core/tools/make.lua new file mode 100644 index 000000000..5d2d1f42b --- /dev/null +++ b/xmake/core/tools/make.lua @@ -0,0 +1,82 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file make.lua +-- + +-- load modules +local os = require("base/os") +local utils = require("base/utils") + +-- define module: make +local make = make or {} + +-- the init function +function make.init(self, name) + + -- save name + self.name = name or "make" + + -- is verbose? + self._VERBOSE = utils.ifelse(xmake._OPTIONS.verbose, "-v", "") + +end + +-- the main function +function make.main(self, mkfile, target) + + -- enable jobs? + local jobs = "" + if xmake._OPTIONS.jobs ~= nil then + if tonumber(xmake._OPTIONS.jobs) ~= 0 then + jobs = "-j" .. xmake._OPTIONS.jobs + else + jobs = "-j" + end + end + + -- make command + local cmd = nil + if mkfile and os.isfile(mkfile) then + cmd = string.format("%s -r %s -f %s %s VERBOSE=%s", self.name, jobs, mkfile, target or "", self._VERBOSE) + else + cmd = string.format("%s -r %s %s VERBOSE=%s", self.name, jobs, target or "", self._VERBOSE) + end + + -- done + local ok = os.execute(cmd) + if ok ~= 0 then + + -- attempt to execute it again for getting the error logs without jobs + if mkfile and os.isfile(mkfile) then + cmd = string.format("%s -r -f %s %s VERBOSE=%s", self.name, mkfile, target or "", self._VERBOSE) + else + cmd = string.format("%s -r %s VERBOSE=%s", self.name, target or "", self._VERBOSE) + end + + -- done + return os.execute(cmd) == 0 + end + + -- ok + return true +end + +-- return module: make +return make diff --git a/xmake/core/tools/mkdir.lua b/xmake/core/tools/mkdir.lua new file mode 100644 index 000000000..9fadb875d --- /dev/null +++ b/xmake/core/tools/mkdir.lua @@ -0,0 +1,46 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file mkdir.lua +-- + +-- define module: mkdir +local mkdir = mkdir or {} + +-- load modules +local os = require("base/os") + +-- the main function +function mkdir.main(self, ...) + + -- mkdir all + for _, dir in ipairs(...) do + if not os.exists(dir) then + if not os.mkdir(dir) then + return false + end + end + end + + -- ok + return true +end + +-- return module: mkdir +return mkdir diff --git a/xmake/core/tools/mv.lua b/xmake/core/tools/mv.lua new file mode 100644 index 000000000..7af2db9ed --- /dev/null +++ b/xmake/core/tools/mv.lua @@ -0,0 +1,43 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file mv.lua +-- + +-- define module: mv +local mv = mv or {} + +-- load modules +local os = require("base/os") + +-- the main function +function mv.main(self, ...) + + -- mv it + local pathes = ... + if pathes and table.getn(pathes) == 2 then + return os.mv(pathes[1], pathes[2]) + end + + -- failed + return false +end + +-- return module: mv +return mv diff --git a/xmake/core/tools/rm.lua b/xmake/core/tools/rm.lua new file mode 100644 index 000000000..47f57e68b --- /dev/null +++ b/xmake/core/tools/rm.lua @@ -0,0 +1,46 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file rm.lua +-- + +-- define module: rm +local rm = rm or {} + +-- load modules +local os = require("base/os") + +-- the main function +function rm.main(self, ...) + + -- rm all + for _, file_or_dir in ipairs(...) do + if os.exists(file_or_dir) then + if not os.rm(file_or_dir) then + return false + end + end + end + + -- ok + return true +end + +-- return module: rm +return rm diff --git a/xmake/core/tools/rmdir.lua b/xmake/core/tools/rmdir.lua new file mode 100644 index 000000000..cea1e28fa --- /dev/null +++ b/xmake/core/tools/rmdir.lua @@ -0,0 +1,46 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file rmdir.lua +-- + +-- define module: rmdir +local rmdir = rmdir or {} + +-- load modules +local os = require("base/os") + +-- the main function +function rmdir.main(self, ...) + + -- rmdir all + for _, dir in ipairs(...) do + if os.isdir(dir) then + if not os.rmdir(dir) then + return false + end + end + end + + -- ok + return true +end + +-- return module: rmdir +return rmdir diff --git a/xmake/core/tools/swiftc.lua b/xmake/core/tools/swiftc.lua new file mode 100644 index 000000000..39142705f --- /dev/null +++ b/xmake/core/tools/swiftc.lua @@ -0,0 +1,117 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file swiftc.lua +-- + +-- load modules +local utils = require("base/utils") +local table = require("base/table") +local string = require("base/string") +local config = require("base/config") +local platform = require("platform/platform") + +-- define module: swiftc +local swiftc = swiftc or {} + +-- the init function +function swiftc.init(self, name) + + -- save name + self.name = name or "swiftc" + + -- init flags map + self.mapflags = + { + -- symbols + ["-fvisibility=hidden"] = "" + + -- warnings + , ["-w"] = "" + , ["-W.*"] = "" + + -- optimize + , ["-O0"] = "-Onone" + , ["-Ofast"] = "-Ounchecked" + , ["-O.*"] = "-O" + + -- vectorexts + , ["-m.*"] = "" + + -- strip + , ["-s"] = "" + , ["-S"] = "" + + -- others + , ["-ftrapv"] = "" + , ["-fsanitize=address"] = "" + } + + -- init ldflags + local swift_linkdirs = config.get("__swift_linkdirs") + if swift_linkdirs then + self.ldflags = { "-L" .. swift_linkdirs } + end + +end + +-- make the compile command +function swiftc.command_compile(self, srcfile, objfile, flags, logfile) + + -- redirect + local redirect = "" + if logfile then redirect = string.format(" > %s 2>&1", logfile) end + + -- make it + return string.format("%s -c %s -o %s %s%s", self.name, flags, objfile, srcfile, redirect) +end + +-- make the includedir flag +function swiftc.flag_includedir(self, includedir) + + -- make it + return "-Xcc -I" .. includedir +end + +-- make the define flag +function swiftc.flag_define(self, define) + + -- make it + return "-Xcc -D" .. define:gsub("\"", "\\\"") +end + +-- make the undefine flag +function swiftc.flag_undefine(self, undefine) + + -- make it + return "-Xcc -U" .. undefine +end + +-- the main function +function swiftc.main(self, cmd) + + -- execute it + local ok = os.execute(cmd) + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: swiftc +return swiftc diff --git a/xmake/core/tools/tools.lua b/xmake/core/tools/tools.lua new file mode 100644 index 000000000..a61322d3c --- /dev/null +++ b/xmake/core/tools/tools.lua @@ -0,0 +1,222 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file tools.lua +-- + +-- define module: tools +local tools = tools or {} + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local platform = require("platform/platform") + +-- match the tool name +function tools._match(name, toolname) + + -- match full? ok + if name == toolname then return 100 end + + -- match the name for windows? ok + if name:find("^" .. toolname .. "%.exe") then return 90 end + if name:find(toolname .. "%.exe") then return 85 end + + -- match the last word? ok + if name:find(toolname .. "$") then return 80 end + + -- match the partial word? ok + if name:find("%-" .. toolname) then return 60 end + + -- contains it? ok + if name:find(toolname, 1, true) then return 30 end + + -- not matched + return 0 +end + +-- find tool from the given root directory and name +function tools._find_from(root, name) + + -- attempt to get it directly first + local filepath = string.format("%s/%s.lua", root, name) + if os.isfile(filepath) then + return filepath + end + + -- make the lower name + name = name:lower() + + -- get all tool files + local file_ok = nil + local score_maxn = 0 + local files = os.match(string.format("%s/*.lua", root)) + for _, file in ipairs(files) do + + -- the tool name + local toolname = path.basename(file) + + -- found it? + if toolname and toolname ~= "tools" then + + -- match score + local score = tools._match(name, toolname:lower()) + + -- ok? + if score >= 100 then return file end + + -- select the file with the max score + if score > score_maxn then + file_ok = file + score_maxn = score + end + end + end + + -- ok? + return file_ok +end + +-- probe it's absolute path if exists from the given tool name and root directory +function tools._probe(root, name) + + -- check + assert(root and name) + + -- make the tool path + local toolpath = string.format("%s/%s", root, name) + toolpath = path.translate(toolpath) + + -- the tool exists? ok + if toolpath and os.isfile(toolpath) then + return toolpath + end +end + +-- find tool from the given name and directory (optional) +function tools.find(name, root) + + -- check + assert(name) + + -- init filename + local filepath = nil + + -- only find it from this directory if the given directory exists + if root then return tools._find_from(root, name) end + + -- attempt to find it from the current platform directory first + if not filepath then filepath = tools._find_from(platform.directory() .. "/tools", name) end + + -- attempt to find it from the script directory + if not filepath then filepath = tools._find_from(xmake._CORE_DIR .. "/tools", name) end + + -- ok? + return filepath +end + +-- load tool from the given name and directory (optional) +function tools.load(name, root) + + -- check + assert(name) + + -- get it directly from cache dirst + tools._TOOLS = tools._TOOLS or {} + if tools._TOOLS[name] then + return tools._TOOLS[name] + end + + -- find the tool file path + local toolpath = tools.find(name, root) + + -- not exists? + if not toolpath or not os.isfile(toolpath) then + return + end + + -- load script + local script, errors = loadfile(toolpath) + if script then + + -- load tool + local tool = script() + + -- init tool + if tool and tool.init then + tool:init(name) + end + + -- save tool to the cache + tools._TOOLS[name] = tool + + -- ok? + return tool + else + utils.error(errors) + utils.error("load %s failed!", toolpath) + assert(false) + end +end + +-- get the given tool script from the given kind +function tools.get(kind) + + -- get the tool name + local toolname = platform.tool(kind) + if not toolname then + utils.error("cannot get tool name for %s", kind) + return + end + + -- load it + return tools.load(toolname) +end + +-- probe it's absolute path if exists from the given tool name +function tools.probe(name, dirs) + + -- check + assert(name) + + -- attempt to run it directly first + if os.execute(string.format("%s > %s 2>&1", name, xmake._NULDEV)) ~= 0x7f00 then + return name + end + + -- attempt to get it from the given directories + if dirs then + for _, dir in ipairs(utils.wrap(dirs)) do + + -- probe it + local toolpath = tools._probe(dir, name) + + -- ok? + if toolpath and os.execute(string.format("%s > %s 2>&1", toolpath, xmake._NULDEV)) ~= 0x7f00 then + return toolpath + end + end + end +end + + +-- return module: tools +return tools diff --git a/xmake/core/tools/verbose.lua b/xmake/core/tools/verbose.lua new file mode 100644 index 000000000..b1168f29d --- /dev/null +++ b/xmake/core/tools/verbose.lua @@ -0,0 +1,47 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file verbose.lua +-- + + +-- define module: verbose +local verbose = verbose or {} + +-- load modules +local io = require("base/io") +local string = require("base/string") + +-- the main function +function verbose.main(self, ...) + + -- verbose all + if xmake._OPTIONS.verbose then + for _, v in ipairs(...) do + io.write(string.format("%s ", v:decode())) + end + io.write("\n") + end + + -- ok + return true +end + +-- return module: verbose +return verbose diff --git a/xmake/scripts/_xmake_main.lua b/xmake/scripts/_xmake_main.lua deleted file mode 100644 index 50f0d313c..000000000 --- a/xmake/scripts/_xmake_main.lua +++ /dev/null @@ -1,48 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _xmake_main.lua --- - --- init namespace: xmake -xmake = xmake or {} -xmake._ARGV = _ARGV -xmake._HOST = _HOST -xmake._ARCH = _ARCH -xmake._NULDEV = _NULDEV -xmake._VERSION = _VERSION -xmake._PROGRAM_DIR = _PROGRAM_DIR -xmake._PROJECT_DIR = _PROJECT_DIR -xmake._SCRIPTS_DIR = _PROGRAM_DIR .. "/scripts" -xmake._PACKAGES_DIR = _PROGRAM_DIR .. "/packages" -xmake._TEMPLATES_DIR = _PROGRAM_DIR .. "/templates" -xmake._PROJECT_FILE = "xmake.lua" -xmake._OPTIONS = {} -xmake._CONFIGS = {} - --- init package path -package.path = xmake._SCRIPTS_DIR .. "/?.lua;" .. package.path - --- load modules -local main = require("base/main") - --- the main function -function _xmake_main() - return main.done() -end diff --git a/xmake/scripts/action/_build.lua b/xmake/scripts/action/_build.lua deleted file mode 100644 index bf660eab5..000000000 --- a/xmake/scripts/action/_build.lua +++ /dev/null @@ -1,120 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _build.lua --- - --- define module: _build -local _build = _build or {} - --- load modules -local rule = require("base/rule") -local utils = require("base/utils") -local clean = require("base/clean") -local config = require("base/config") -local project = require("base/project") -local makefile = require("base/makefile") - --- need access to the given file? -function _build.need(name) - - -- check - assert(name) - - -- the accessors - local accessors = { config = true, global = true, project = true, platform = true } - - -- need it? - return accessors[name] -end - --- done -function _build.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- the target name - local target_name = options.target - - -- check target - if not project.checktarget(target_name) then - return false - end - - -- rebuild it? - if options.rebuild or config.get("__rebuild") then - clean.remove(target_name, "build") - -- update it? - elseif options.update then - clean.remove(target_name, "targets") - end - - -- clear rebuild mark and save configure to file - if config.get("__rebuild") then - - -- clear it - config.set("__rebuild", nil) - - -- save the configure - if not config.save() then - -- error - utils.error("update configure failed!") - end - end - - -- check makefile - if not os.isfile(rule.makefile()) then - - -- make the configure file for the given target - if not project.makeconf(options.target) then - -- error - utils.error("make configure failed!") - return false - end - - -- make makefile - if not makefile.make() then - -- error - utils.error("make makefile failed!") - return false - end - end - - -- build target for makefile - if not makefile.build(target_name) then - -- error - print("") - if options.verbose then - io.cat(rule.logfile()) - else - io.tail(rule.logfile(), 32) - end - utils.error("build target: %s failed!\n", target_name) - return false - end - - -- ok - print("build ok!") - return true -end - --- return module: _build -return _build diff --git a/xmake/scripts/action/_clean.lua b/xmake/scripts/action/_clean.lua deleted file mode 100644 index 677ff2470..000000000 --- a/xmake/scripts/action/_clean.lua +++ /dev/null @@ -1,106 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _clean.lua --- - --- define module: _clean -local _clean = _clean or {} - --- load modules -local clean = require("base/clean") -local config = require("base/config") -local project = require("base/project") -local utils = require("base/utils") -local platform = require("platform/platform") - --- need access to the given file? -function _clean.need(name) - - -- check - assert(name) - - -- the accessors - local accessors = { global = true, config = true, project = true, platform = true } - - -- need it? - return accessors[name] -end - --- done -function _clean.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check target - if not project.checktarget(options.target) then - return false - end - - -- clean the current target - if not clean.remove(options.target, utils.ifelse(options.all, "all", "build")) then - return false - end - - -- trace - print("clean ok!") - - -- ok - return true -end - --- the menu -function _clean.menu() - - return { - -- xmake c - shortname = 'c' - - -- usage - , usage = "xmake clean|c [options] [target]" - - -- description - , description = "Remove all binary and temporary files." - - -- options - , options = - { - {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - , {} - , {'a', "all", "k", nil, "Clean all auto-generated files by xmake." } - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Clean for the given target." } - } - } -end - --- return module: _clean -return _clean diff --git a/xmake/scripts/action/_config.lua b/xmake/scripts/action/_config.lua deleted file mode 100644 index a883b0499..000000000 --- a/xmake/scripts/action/_config.lua +++ /dev/null @@ -1,215 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _config.lua --- - --- define module: _config -local _config = _config or {} - --- load modules -local utils = require("base/utils") -local config = require("base/config") -local project = require("base/project") -local makefile = require("base/makefile") -local platform = require("platform/platform") - --- need access to the given file? -function _config.need(name) - - -- check - assert(name) - - -- the accessors - local accessors = { config = true, global = true, project = true, platform = true } - - -- need it? - return accessors[name] -end - --- done -function _config.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check target - if not project.checktarget(options.target) then - return false - end - - -- trace - print("configure ...") - - -- save the configure - if not config.save() then - -- error - utils.error("save configure failed!") - return false - end - - -- make the configure file for the given target - if not project.makeconf(options.target) then - -- error - utils.error("make configure failed!") - return false - end - - -- make makefile - if not makefile.make() then - -- error - utils.error("make makefile failed!") - return false - end - - -- dump configure - config.dump() - - -- trace - print("configure ok!") - - -- ok - return true -end - --- the menu -function _config.menu() - - return { - -- xmake f - shortname = 'f' - - -- usage - , usage = "xmake config|f [options] [target]" - - -- description - , description = "Configure the project." - - -- options - , options = - { - {'c', "clean", "k", nil, "Clean the cached configure and configure all again." } - - , {} - , {'p', "plat", "kv", xmake._HOST, "Compile for the given platform." - , function () - local descriptions = {} - local plats = platform.plats() - if plats then - for i, plat in ipairs(plats) do - descriptions[i] = " - " .. plat - end - end - return descriptions - end } - , {'a', "arch", "kv", "auto", "Compile for the given architecture." - , function () - local descriptions = {} - local plats = platform.plats() - if plats then - for i, plat in ipairs(plats) do - descriptions[i] = " - " .. plat .. ":" - local archs = platform.archs(plat) - if archs then - for _, arch in ipairs(archs) do - descriptions[i] = descriptions[i] .. " " .. arch - end - end - end - end - return descriptions - end } - , {'m', "mode", "kv", "release", "Compile for the given mode." - , " - debug" - , " - release" - , " - profile" } - , {'k', "kind", "kv", "static", "Compile for the given target kind." - , " - static" - , " - shared" - , " - binary" } - , {nil, "host", "kv", xmake._HOST, "The current host environment." } - - -- the options for project - , function () return project.menu() end - - , {} - , {nil, "make", "kv", "auto", "Set the make path." } - , {nil, "ccache", "kv", "auto", "Enable or disable the c/c++ compiler cache." } - - , {} - , {nil, "cross", "kv", nil, "The cross toolchains prefix" - , ".e.g" - , " - i386-mingw32-" - , " - arm-linux-androideabi-" } - , {nil, "toolchains", "kv", nil, "The cross toolchains directory" } - - , {} - , {nil, "cc", "kv", nil, "The C Compiler" } - , {nil, "cxx", "kv", nil, "The C++ Compiler" } - , {nil, "cflags", "kv", nil, "The C Compiler Flags" } - , {nil, "cxflags", "kv", nil, "The C/C++ compiler Flags" } - , {nil, "cxxflags", "kv", nil, "The C++ Compiler Flags" } - - , {} - , {nil, "as", "kv", nil, "The Assembler" } - , {nil, "asflags", "kv", nil, "The Assembler Flags" } - - , {} - , {nil, "sc", "kv", nil, "The Swift Compiler" } - , {nil, "scflags", "kv", nil, "The Swift Compiler Flags" } - - , {} - , {nil, "ld", "kv", nil, "The Linker" } - , {nil, "ldflags", "kv", nil, "The Binary Linker Flags" } - - , {} - , {nil, "ar", "kv", nil, "The Static Library Linker" } - , {nil, "arflags", "kv", nil, "The Static Library Linker Flags" } - - , {} - , {nil, "sh", "kv", nil, "The Shared Library Linker" } - , {nil, "shflags", "kv", nil, "The Shared Library Linker Flags" } - - -- the options for all platforms - , function () return platform.menu("config") end - - , {} - , {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - , {'o', "buildir", "kv", "build", "Set the build directory." } - - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Configure for the given target." } - } - } -end - --- return module: _config -return _config diff --git a/xmake/scripts/action/_create.lua b/xmake/scripts/action/_create.lua deleted file mode 100644 index 840631f65..000000000 --- a/xmake/scripts/action/_create.lua +++ /dev/null @@ -1,173 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _create.lua --- - --- define module: _create -local _create = _create or {} - --- load modules -local utils = require("base/utils") -local template = require("base/template") - --- need access to the given file? -function _create.need(name) - - -- no accessors - return false -end - --- done -function _create.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- the target name - local targetname = options.target or options.name or path.basename(xmake._PROJECT_DIR) or "demo" - - -- trace - utils.printf("create %s ...", targetname) - - -- the language - local language = options.language - if not language then - utils.error("no language!") - return false - end - - -- the template id - local templateid = tonumber(options.template) - if type(templateid) ~= "number" then - utils.error("invalid template id: %s!", options.template) - return false - end - - -- load all templates for the given language - local templates = template.loadall(language) - - -- load the template module - local module = nil - if templates then module = templates[templateid] end - if not module then - utils.error("invalid template id: %s!", options.template) - return false - end - - -- enter the template directory - if not module._DIRECTORY or not os.cd(module._DIRECTORY) then - -- error - utils.error("not found template id: %s!", options.template) - return false - end - - -- check the template project - if not os.isdir("project") then - -- errors - utils.error("the template project not exists!") - return false - end - - -- ensure the project directory - if not os.isdir(xmake._PROJECT_DIR) then - os.mkdir(xmake._PROJECT_DIR) - end - - -- copy the project files - local ok, errors = os.cp("project/*", xmake._PROJECT_DIR) - if not ok then - -- errors - utils.error(errors) - return false - end - - -- done the template files - if not module.done(targetname, xmake._PROJECT_DIR, xmake._PACKAGES_DIR) then - utils.error("update the template failed!") - return false - end - - -- trace - utils.printf("create %s ok!", targetname) - - -- ok - return true -end - --- the menu -function _create.menu() - - return { - -- usage - usage = "xmake create [options] [target]" - - -- description - , description = "Create a new project." - - -- options - , options = - { - {'n', "name", "kv", nil, "The project name." } - , {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } - , {'P', "project", "kv", nil, "Create from the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - , {'l', "language", "kv", "c", "The project language" - , function () - local descriptions = {} - local languages = template.languages() - for _, language in ipairs(languages) do - table.insert(descriptions, " - " .. language) - end - return descriptions - end } - , {'t', "template", "kv", "1", "Select the project template id of the given language." - , function () - local descriptions = {} - local languages = template.languages() - for _, language in ipairs(languages) do - table.insert(descriptions, string.format(" - language: %s", language)) - local templates = template.loadall(language) - if templates then - for i, template in ipairs(templates) do - table.insert(descriptions, string.format(" %d. %s", i, utils.ifelse(template.description, template.description, "The Unknown Project"))) - end - end - end - return descriptions - end } - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", nil, "Create the given target." - , "Uses the project name as target if not exists." } - } - } -end - --- return module: _create -return _create diff --git a/xmake/scripts/action/_debug.lua b/xmake/scripts/action/_debug.lua deleted file mode 100644 index c84d78073..000000000 --- a/xmake/scripts/action/_debug.lua +++ /dev/null @@ -1,89 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _debug.lua --- - --- define module: _debug -local _debug = _debug or {} - --- load modules -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- need access to the given file? -function _debug.need(name) - - -- check - assert(name) - - -- the accessors - local accessors = { config = true, global = true, project = true, platform = true } - - -- need it? - return accessors[name] -end - --- done -function _debug.done() - - -- TODO - print("not implement!") - - -- ok - return true -end - --- the menu -function _debug.menu() - - return { - -- xmake d - shortname = 'd' - - -- usage - , usage = "xmake debug|d [options] [target]" - - -- description - , description = "Debug target." - - -- options - , options = - { - {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } - , {'P', "project", "kv", nil, "Create from the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", nil, "Debug a given target" } - } - } -end - --- return module: _debug -return _debug diff --git a/xmake/scripts/action/_global.lua b/xmake/scripts/action/_global.lua deleted file mode 100644 index a8fffa0bc..000000000 --- a/xmake/scripts/action/_global.lua +++ /dev/null @@ -1,104 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _global.lua --- - --- define module: _global -local _global = _global or {} - --- load modules -local utils = require("base/utils") -local global = require("base/global") -local platform = require("platform/platform") - --- need access to the given file? -function _global.need(name) - - -- check - assert(name) - - -- the accessors - local accessors = { global = true } - - -- need it? - return accessors[name] -end - --- done -function _global.done() - - -- probe the global platform configure - if not platform.probe(true) then - return false - end - - -- clear up the global configure - global.clearup() - - -- save the global configure - if not global.save() then - -- error - utils.error("save configure failed!") - return false - end - - -- dump global - global.dump() - - -- ok - print("configure ok!") - return true -end - --- the menu -function _global.menu() - - return { - -- xmake g - shortname = 'g' - - -- usage - , usage = "xmake global|g [options] [target]" - - -- description - , description = "Configure the global options for xmake." - - -- options - , options = - { - {'c', "clean", "k", nil, "Clean the cached configure and configure all again." } - , {nil, "make", "kv", "auto", "Set the make path." } - , {nil, "ccache", "kv", "auto", "Enable or disable the c/c++ compiler cache." - , " --ccache=[y|n]" } - - , {} - -- the options for all platforms - , function () return platform.menu("global") end - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - } - } -end - --- return module: _global -return _global diff --git a/xmake/scripts/action/_install.lua b/xmake/scripts/action/_install.lua deleted file mode 100644 index 28ef3650d..000000000 --- a/xmake/scripts/action/_install.lua +++ /dev/null @@ -1,224 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _install.lua --- - --- define module: _install -local _install = _install or {} - --- load modules -local utils = require("base/utils") -local config = require("base/config") -local global = require("base/global") -local install = require("base/install") -local package = require("base/package") -local project = require("base/project") -local platform = require("platform/platform") - --- need access to the given file? -function _install.need(name) - - -- no accessors - return false -end - --- make configure for the given target -function _install._makeconf(configs, target_name, target) - - -- check - assert(configs and target_name and target) - - -- init configs for targets - configs[target_name] = configs[target_name] or {} - local configs_target = configs[target_name] - - -- save the install script - local installscript = target.installscript - if type(installscript) == "string" and os.isfile(installscript) then - local script, errors = loadfile(installscript) - if script then - installscript = script() - if type(installscript) == "table" and installscript.main then - installscript = installscript.main - end - else - utils.error(errors) - return false - end - end - if target.installscript and type(installscript) ~= "function" then - utils.error("invalid install script!") - return false - end - configs_target.installscript = installscript - - -- ok - return true -end - --- package target -function _install._package(target_name) - - -- get the target name - if not target_name or target_name == "all" then - target_name = "" - end - - -- package it - if os.execute(string.format("xmake p -P %s -f %s %s", xmake._PROJECT_DIR, xmake._PROJECT_FILE, target_name)) ~= 0 then - return false - end - - -- ok - return true -end - --- done -function _install.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- trace - print("install: ...") - - -- load the global configure first - global.load() - - -- enter the project directory - if not os.cd(xmake._PROJECT_DIR) then - -- errors - utils.error("not found project: %s!", xmake._PROJECT_DIR) - return false - end - - -- package the given target first - if not _install._package(options.target) then - -- errors - utils.error("package: failed!") - return false - end - - -- load the package configure - local configs, errors = package.load() - if not configs then - -- errors - utils.error(errors) - return false - end - - -- reload configure - local errors = config.reload() - if errors then - -- error - utils.error(errors) - return false - end - - -- make the platform configure - if not platform.make() then - utils.error("make platform configure: %s failed!", config.get("plat")) - return false - end - - -- reload project - local errors = project.reload() - if errors then - -- error - utils.error(errors) - return false - end - - -- update the outputdir - for _, target in pairs(configs) do - target.outputdir = options.installdir - end - - -- the targets - local targets = project.targets() - assert(targets) - - -- make configure for the given target - if target_name and target_name ~= "all" then - if not _install._makeconf(configs, target_name, targets[target_name]) then - utils.error("make target configure: %s failed!", target_name) - return false - end - else - for target_name, target in pairs(targets) do - if not _install._makeconf(configs, target_name, target) then - utils.error("make target configure: %s failed!", target_name) - return false - end - end - end - - -- done install - if not install.done(configs) then - -- errors - utils.error("install: failed!") - return false - end - - -- trace - print("install: ok!") - - -- ok - return true -end - --- the menu -function _install.menu() - - return { - -- xmake i - shortname = 'i' - - -- usage - , usage = "xmake install|i [options] [target]" - - -- description - , description = "Package and install the project binary files." - - -- options - , options = - { - {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - , {'o', "installdir", "kv", nil, "Set the install directory." } - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Install the given target." } - } - } -end - --- return module: _install -return _install diff --git a/xmake/scripts/action/_lua.lua b/xmake/scripts/action/_lua.lua deleted file mode 100644 index c1a89dc39..000000000 --- a/xmake/scripts/action/_lua.lua +++ /dev/null @@ -1,168 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _lua.lua --- - --- define module: _lua -local _lua = _lua or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local string = require("base/string") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- need access to the given file? -function _lua.need(name) - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- do not load config if be not given -f or -P options - if options.file == nil and options.project == nil then - return false - end - - -- patch target for loading config ok - options.target = "all" - - -- the accessors - local accessors = { config = true, global = true, platform = true } - - -- need it? - return accessors[name] -end - --- done -function _lua.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- no script? - if not options.script then - return false - end - - -- the arguments - local arguments = options.arguments or {} - if type(arguments) ~= "table" then - arguments = {} - end - - -- is string script? - if options.string then - - -- trace - utils.verbose("script: %s", options.script) - - -- load and run string - local script = loadstring(options.script) - if script then - return script(arguments) - end - else - -- attempt to load script from the given file if exists - local file = options.script - if not path.is_absolute(file) then - file = path.absolute(file) - end - - -- attempt to load script from the tools directory - if not os.isfile(file) then - file = tools.find(options.script, xmake._SCRIPTS_DIR .. "/tools") - end - - -- load and run the script file - if os.isfile(file) then - - -- load script - local script = loadfile(file) - if script then - - -- load module - local module = script() - if module then - - -- init module - if module.init then - module:init(options.script) - end - - -- done module - return module:main(arguments) - end - end - end - end - - -- failed - utils.error("cannot run this script: %s", options.script) - return false -end - --- the menu -function _lua.menu() - - return { - -- xmake l - shortname = 'l' - - -- usage - , usage = "xmake lua|l [options] [script] [arguments]" - - -- description - , description = "Run the lua script." - - -- options - , options = - { - {'f', "file", "kv", nil, "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - - , {} - , {'s', "string", "k", nil, "Run the lua string script." } - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "script", "v", nil, "Run the given lua script." - , " - The script name from the xmake tool directory" - , " - The script file" - , " - The script string" } - , {nil, "arguments", "vs", nil, "The script arguments" } - } - } -end - --- return module: _lua -return _lua diff --git a/xmake/scripts/action/_man.lua b/xmake/scripts/action/_man.lua deleted file mode 100644 index feb70dd92..000000000 --- a/xmake/scripts/action/_man.lua +++ /dev/null @@ -1,89 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _man.lua --- - --- define module: _man -local _man = _man or {} - --- load modules -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- need access to the given file? -function _man.need(name) - - -- check - assert(name) - - -- the accessors - local accessors = { config = true, global = true, project = true } - - -- need it? - return accessors[name] -end - --- done -function _man.done() - - -- TODO - print("not implement!") - - -- ok - return true -end - --- the menu -function _man.menu() - - return { - -- xmake m - shortname = 'm' - - -- usage - , usage = "xmake man|m [options] [target]" - - -- description - , description = "Create a project man." - - -- options - , options = - { - {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } - , {'P', "project", "kv", nil, "Create from the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Create man for the given target" } - } - } -end - --- return module: _man -return _man diff --git a/xmake/scripts/action/_package.lua b/xmake/scripts/action/_package.lua deleted file mode 100644 index e39604a33..000000000 --- a/xmake/scripts/action/_package.lua +++ /dev/null @@ -1,365 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _package.lua --- - --- define module: _package -local _package = _package or {} - --- load modules -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local global = require("base/global") -local string = require("base/string") -local project = require("base/project") -local package = require("base/package") -local platform = require("platform/platform") - --- need access to the given file? -function _package.need(name) - - -- no accessors - return false -end - --- configure target for the given architecture -function _package._config(arch, target_name) - - -- need not configure it - if not arch then return true end - - -- done the command - return os.execute(string.format("xmake f -P %s -f %s -a %s %s", xmake._PROJECT_DIR, xmake._PROJECT_FILE, arch, target_name)) == 0; -end - --- build target for the given architecture -function _package._build(arch, target_name) - - -- get the target name - if not target_name or target_name == "all" then - target_name = "" - end - - -- configure it first - if not _package._config(arch, target_name) then return false end - - -- build it - if os.execute(string.format("xmake -P %s %s", xmake._PROJECT_DIR, target_name)) ~= 0 then - -- errors - utils.error("build failed!") - return false - end - - -- ok - return true -end - --- backup the target files -function _package._backup(rootdir, filepath) - - -- the relative file path - if filepath and path.is_absolute(filepath) then - filepath = path.relative(filepath, xmake._PROJECT_DIR) - end - - -- not exists? return it directly - if not filepath or not os.isfile(filepath) then return end - - -- the backup file - local backupfile = string.format("%s/%s", rootdir, filepath) - - -- backup it - local ok, errors = os.cp(filepath, backupfile) - if not ok then - -- errors - utils.error(errors) - return - end - - -- ok - return filepath -end - --- make configure for the given target -function _package._makeconf(target_name, target) - - -- check - assert(target_name and target) - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- the configs - local configs = _package._CONFIGS - assert(configs) - - -- the architecture - local arch = config.get("arch") - if not arch then return false end - - -- init configs for targets - configs[target_name] = configs[target_name] or {} - local configs_target = configs[target_name] - - -- init configs for architectures - configs_target.archs = configs_target.archs or {} - - -- init configs for architecture - configs_target.archs[arch] = configs_target.archs[arch] or {} - local configs_arch = configs_target.archs[arch] - - -- save name - configs_target.name = target_name - - -- save kind - configs_target.kind = target.kind - - -- save the output directory - configs_target.outputdir = options.outputdir or config.get("buildir") - - -- save the header files - configs_target.headers = target.headers - - -- save the target directory - configs_arch.targetdir = rule.backupdir(target_name, arch) - - -- save the config file - configs_arch.config_h = _package._backup(configs_arch.targetdir, rule.config_h(target)) - - -- save the target file - configs_arch.targetfile = _package._backup(configs_arch.targetdir, rule.targetfile(target_name, target)) - - -- save the package script - local packagescript = target.packagescript - if type(packagescript) == "string" and os.isfile(packagescript) then - local script, errors = loadfile(packagescript) - if script then - packagescript = script() - if type(packagescript) == "table" and packagescript.main then - packagescript = packagescript.main - end - else - utils.error(errors) - return false - end - end - if target.packagescript and type(packagescript) ~= "function" then - utils.error("invalid package script!") - return false - end - configs_target.packagescript = packagescript - - -- ok - return true -end - --- load configure for the given target -function _package._loadconf(target_name) - - -- reload configure - local errors = config.reload() - if errors then - -- error - utils.error(errors) - return false - end - - -- make the platform configure - if not platform.make() then - utils.error("make platform configure: %s failed!", config.get("plat")) - return false - end - - -- reload project - local errors = project.reload() - if errors then - -- error - utils.error(errors) - return false - end - - -- the targets - local targets = project.targets() - assert(targets) - - -- make configure for the given target - if target_name and target_name ~= "all" then - if not _package._makeconf(target_name, targets[target_name]) then - utils.error("make target configure: %s failed!", target_name) - return false - end - else - for target_name, target in pairs(targets) do - if not _package._makeconf(target_name, target) then - utils.error("make target configure: %s failed!", target_name) - return false - end - end - end - - -- ok - return true -end - --- build target for all architectures -function _package._build_all(archs, target_name) - - -- exists the given architectures? - if archs then - - -- split all architectures - archs = archs:split(",") - if not archs then return false end - - -- build for all architectures - for _, arch in ipairs(archs) do - - -- trim it - arch = arch:trim() - - -- build it - if not _package._build(arch, target_name) then return false end - - -- load configure - if not _package._loadconf(target_name) then return false end - - end - - -- build for single architecture - else - - -- build it - if not _package._build(nil, target_name) then return false end - - -- load configure - if not _package._loadconf(target_name) then return false end - - end - - -- ok - return true -end - --- done -function _package.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- trace - print("package: ...") - - -- init configs - _package._CONFIGS = _package._CONFIGS or {} - local configs = _package._CONFIGS - - -- load the global configure first - global.load() - - -- enter the project directory - if not os.cd(xmake._PROJECT_DIR) then - -- errors - utils.error("not found project: %s!", xmake._PROJECT_DIR) - return false - end - - -- build the given target first for all architectures - if not _package._build_all(options.archs, options.target) then - -- errors - utils.error("build package failed!") - return false - end - - -- done package - if not package.done(configs) then - -- errors - utils.error("package: failed!") - return false - end - - -- trace - print("package: ok!") - - -- ok - return true -end - --- the menu -function _package.menu() - - return { - -- xmake p - shortname = 'p' - - -- usage - , usage = "xmake package|p [options] [target]" - - -- description - , description = "Package target." - - -- options - , options = - { - {'a', "archs", "kv", nil, "Package multiple given architectures." - , " .e.g --archs=\"armv7, arm64\" or -a i386" - , "" - , function () - local descriptions = {} - local plats = platform.plats() - if plats then - for i, plat in ipairs(plats) do - descriptions[i] = " - " .. plat .. ":" - local archs = platform.archs(plat) - if archs then - for _, arch in ipairs(archs) do - descriptions[i] = descriptions[i] .. " " .. arch - end - end - end - end - return descriptions - end } - - , {} - , {'f', "file", "kv", "xmake.lua", "Create a given xmake.lua file." } - , {'P', "project", "kv", nil, "Create from the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - , {'o', "outputdir", "kv", nil, "Set the output directory." } - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Package a given target" } - } - } -end - --- return module: _package -return _package diff --git a/xmake/scripts/action/_run.lua b/xmake/scripts/action/_run.lua deleted file mode 100644 index 64649fcb8..000000000 --- a/xmake/scripts/action/_run.lua +++ /dev/null @@ -1,179 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _run.lua --- - --- define module: _run -local _run = _run or {} - --- load modules -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local project = require("base/project") -local platform = require("platform/platform") - --- need access to the given file? -function _run.need(name) - - -- check - assert(name) - - -- the accessors - local accessors = { config = true, global = true, project = true, platform = true } - - -- need it? - return accessors[name] -end - --- done -function _run.done() - - -- the options - local options = xmake._OPTIONS - assert(options and xmake._PROJECT_DIR) - - -- the target name - local name = options.target - if not name then - -- error - utils.error("no runable target!") - return false - end - - -- the arguments - local arguments = options.arguments or {} - if type(arguments) ~= "table" then - arguments = {} - end - - -- the targets - local targets = project.targets() - if not targets or not targets[name] then - -- error - utils.error("not found target: %s!", name) - return false - end - - -- the target - local target = targets[name] - - -- the target file - local targetfile = rule.targetfile(name, target) - if targetfile and not path.is_absolute(targetfile) then - targetfile = path.absolute(targetfile, xmake._PROJECT_DIR) - end - - -- load the run script - local runscript = target.runscript - if type(runscript) == "string" and os.isfile(runscript) then - local script, errors = loadfile(runscript) - if script then - runscript = script() - if type(runscript) == "table" and runscript.main then - runscript = runscript.main - end - else - utils.error(errors) - return false - end - end - - -- run script - if runscript ~= nil then - if type(runscript) == "function" then - - -- make passed target - local target_passed = {} - target_passed.name = name - target_passed.arguments = arguments - target_passed.targetfile = targetfile - - -- run it - local ok = runscript(target_passed) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - else - utils.error("invalid run script!") - return false - end - end - - -- not executale? - if not target.kind or type(target.kind) ~= "string" or target.kind ~= "binary" then - -- error - utils.error("the target %s is not executale!", name) - return false - end - - -- check the target file - if not targetfile and not os.isfile(targetfile) then - -- error - utils.error("not found target file: %s!", targetfile) - return false - end - - -- done - local ok = os.execute(string.format("%s %s", targetfile, table.concat(arguments, " "))) - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- the menu -function _run.menu() - - return { - -- xmake r - shortname = 'r' - - -- usage - , usage = "xmake run|r [options] [target] [arguments]" - - -- description - , description = "Run the project target." - - -- options - , options = - { - {'d', "debug", "k", nil, "Run and debug the given target." } - , {nil, "debugger", "kv", "auto", "Set the debugger path." } - - , {} - , {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", nil, "Run the given target." } - , {nil, "arguments", "vs", nil, "The target arguments" } - } - } -end - --- return module: _run -return _run diff --git a/xmake/scripts/action/_uninstall.lua b/xmake/scripts/action/_uninstall.lua deleted file mode 100644 index 8f82907d6..000000000 --- a/xmake/scripts/action/_uninstall.lua +++ /dev/null @@ -1,160 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file _uninstall.lua --- - --- define module: _uninstall -local _uninstall = _uninstall or {} - --- load modules -local utils = require("base/utils") -local config = require("base/config") -local global = require("base/global") -local install = require("base/install") -local uninstall = require("base/uninstall") -local package = require("base/package") -local project = require("base/project") -local platform = require("platform/platform") - --- need access to the given file? -function _uninstall.need(name) - - -- no accessors - return false -end - --- package target -function _uninstall._package(target_name) - - -- get the target name - if not target_name or target_name == "all" then - target_name = "" - end - - -- package it - if os.execute(string.format("xmake p -P %s -f %s %s", xmake._PROJECT_DIR, xmake._PROJECT_FILE, target_name)) ~= 0 then - return false - end - - -- ok - return true -end - - --- done -function _uninstall.done() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- trace - print("uninstall: ...") - - -- load the global configure first - global.load() - - -- enter the project directory - if not os.cd(xmake._PROJECT_DIR) then - -- errors - utils.error("not found project: %s!", xmake._PROJECT_DIR) - return false - end - - -- load the install configure - local configs, errors = install.load() - if not configs then - -- errors - utils.error(errors) - return false - end - - -- reload configure - local errors = config.reload() - if errors then - -- error - utils.error(errors) - return false - end - - -- make the platform configure - if not platform.make() then - utils.error("make platform configure: %s failed!", config.get("plat")) - return false - end - - -- reload project - local errors = project.reload() - if errors then - -- error - utils.error(errors) - return false - end - - -- done uninstall - if not uninstall.done(configs) then - -- errors - utils.error("uninstall: failed!") - return false - end - - -- trace - print("uninstall: ok!") - - -- ok - return true -end - --- the menu -function _uninstall.menu() - - return { - -- xmake u - shortname = 'u' - - -- usage - , usage = "xmake uninstall|u [options] [target]" - - -- description - , description = "Uninstall the project binary files." - - -- options - , options = - { - {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - - , {} - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Install the given target." } - } - } -end - --- return module: _uninstall -return _uninstall diff --git a/xmake/scripts/action/action.lua b/xmake/scripts/action/action.lua deleted file mode 100644 index 1174b140a..000000000 --- a/xmake/scripts/action/action.lua +++ /dev/null @@ -1,190 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file action.lua --- - --- define module: action -local action = action or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local global = require("base/global") -local config = require("base/config") -local project = require("base/project") -local platform = require("platform/platform") - --- load the given action -function action._load(name) - - -- load the given action - return require("action/_" .. name) -end - --- load the project file -function action._load_project() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- enter the project directory - if not os.cd(xmake._PROJECT_DIR) then - -- error - return string.format("not found project: %s!", xmake._PROJECT_DIR) - end - - -- check the project file - if not os.isfile(xmake._PROJECT_FILE) then - return string.format("not found the project file: %s", xmake._PROJECT_FILE) - end - - -- init the build directory - if options.buildir and path.is_absolute(options.buildir) then - options.buildir = path.relative(options.buildir, xmake._PROJECT_DIR) - end - - -- xmake config or marked as "reconfig"? - if options._ACTION == "config" or config._RECONFIG then - - -- probe the current project - project.probe() - - -- clear up the configure - config.clearup() - - end - - -- load the project - return project.load() -end - --- done the given action -function action.done(name) - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- load the given action - local _action = action._load(name) - if not _action then return false end - - -- load the global configure first - if _action.need("global") then global.load() end - - -- load the project configure - if _action.need("config") then - local errors = config.load() - if errors then - -- error - utils.error(errors) - return false - end - end - - -- probe the platform - if _action.need("platform") and (options._ACTION == "config" or config._RECONFIG) then - if not platform.probe(false) then - return false - end - end - - -- merge the default options - for k, v in pairs(options._DEFAULTS) do - if nil == options[k] then options[k] = v end - end - - -- make the platform configure - if _action.need("platform") and not platform.make() then - utils.error("make platform configure: %s failed!", config.get("plat")) - return false - end - - -- load the project file - if _action.need("project") then - local errors = action._load_project() - if errors then - -- error - utils.error(errors) - return false - end - end - - -- reconfig it first if marked as "reconfig" - if _action.need("config") and config._RECONFIG then - - -- config it - local _action_config = action._load("config") - if not _action_config or not _action_config.done() then - -- error - utils.error("reconfig failed for the changed host!") - return false - end - end - - -- done the given action - return _action.done() -end - --- list the all actions -function action.list() - - -- find all action scripts - local list = {} - local files = os.match(xmake._SCRIPTS_DIR .. "/action/_*.lua") - if files then - for _, file in ipairs(files) do - local name = path.basename(file) - if name and name ~= "_build" then - table.insert(list, name:sub(2)) - end - end - end - - -- ok? - return list -end - --- get the all action menus -function action.menu() - - -- get all actions - local menus = {} - local actions = action.list() - for _, name in ipairs(actions) do - - -- load action - local a = action._load(name) - if a and a.menu then - local m = a.menu() - if m then - menus[name] = m - end - end - end - - -- ok? - return menus -end - --- return module: action -return action diff --git a/xmake/scripts/base/clean.lua b/xmake/scripts/base/clean.lua deleted file mode 100644 index 9fbb3258a..000000000 --- a/xmake/scripts/base/clean.lua +++ /dev/null @@ -1,192 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file clean.lua --- - --- define module: clean -local clean = clean or {} - --- load modules -local os = require("base/os") -local rule = require("base/rule") -local utils = require("base/utils") -local config = require("base/config") -local project = require("base/project") - --- remove the given files or directories -function clean._remove(filedirs) - - -- empty? - if not filedirs then return true end - - -- wrap it first - filedirs = utils.wrap(filedirs) - for _, filedir in ipairs(filedirs) do - - -- exists? remove it - if os.exists(filedir) then - -- remove it - local ok, errors = os.rm(filedir) - if not ok then - -- error - utils.error(errors) - return false - end - end - end - - -- ok - return true -end - --- remove the given target name -function clean._remove_target(target_name, target, mode, buildir) - - -- check - assert(target_name and target) - - -- remove the target file - if not clean._remove(rule.targetfile(target_name, target, buildir)) then - return false - end - - -- not only remove target file? - if mode ~= "targets" then - - -- remove the object files - if not clean._remove(rule.objectfiles(target_name, target, rule.sourcefiles(target), buildir)) then - return false - end - - -- remove the header files - local _, dstheaders = rule.headerfiles(target) - if not clean._remove(dstheaders) then - return false - end - - -- remove the config.h file - if mode == "all" and target.config_h then - - -- translate file path - local config_h = nil - if not path.is_absolute(target.config_h) then - config_h = path.absolute(target.config_h, xmake._PROJECT_DIR) - else - config_h = path.translate(target.config_h) - end - if not clean._remove(config_h) then - return false - end - end - end - - -- ok - return true -end - --- remove the given target and all dependent targets -function clean._remove_target_and_deps(target_name, mode, buildir) - - -- the targets - local targets = project.targets() - assert(targets) - - -- the target - local target = targets[target_name] - assert(target) - - -- remove the target - if not clean._remove_target(target_name, target, mode, buildir) then - return false - end - - -- exists the dependent targets? - if target.deps then - local deps = utils.wrap(target.deps) - for _, dep in ipairs(deps) do - if not clean._remove_target_and_deps(dep, mode, buildir) then return false end - end - end - - -- ok - return true -end - --- remove the target and object files for the given target --- --- mode: --- all --- build --- targets --- -function clean.remove(target_name, mode) - - -- the build directory - local buildir = config.get("buildir") - assert(buildir and mode) - - -- the target name - if target_name and target_name ~= "all" then - -- remove target - if not clean._remove_target_and_deps(target_name, mode, buildir) then return false end - else - - -- the targets - local targets = project.targets() - assert(targets) - - -- remove targets - for target_name, target in pairs(targets) do - if not clean._remove_target(target_name, target, mode, buildir) then return false end - end - end - - -- remove all - if mode == "all" then - - -- remove makefile - if not clean._remove(rule.makefile()) then - return false - end - - -- remove the configure directory - if not clean._remove(config.directory()) then - return false - end - - -- remove the log file - if not clean._remove(rule.logfile()) then - return false - end - - -- remove build directory if be empty - local buildir = config.get("buildir") - if os.isdir(buildir) then - os.rm(buildir, true) - end - - end - - -- ok - return true -end - --- return module: clean -return clean diff --git a/xmake/scripts/base/compiler.lua b/xmake/scripts/base/compiler.lua deleted file mode 100644 index a64f8bae0..000000000 --- a/xmake/scripts/base/compiler.lua +++ /dev/null @@ -1,574 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file compiler.lua --- - --- define module: compiler -local compiler = compiler or {} - --- load modules -local io = require("base/io") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local config = require("base/config") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- map gcc flag to the given compiler flag -function compiler._mapflag(module, flag) - - -- check - assert(module.mapflags and flag) - - -- attempt to map it directly - local flag_mapped = module.mapflags[flag] - if flag_mapped and type(flag_mapped) == "string" then - return flag_mapped - end - - -- find and replace it using pattern - for k, v in pairs(module.mapflags) do - local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) - if type(v) == "function" then - return v(module, w) - else - return v - end - end) - if flag_mapped and count ~= 0 then - return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil) - end - end - - -- return it directly - return flag -end - --- map gcc flags to the given compiler flags -function compiler._mapflags(module, flags) - - -- check - assert(module) - - -- wrap flags first - flags = utils.wrap(flags) - - -- need not map flags? return it directly - if not module.mapflags then - return flags - end - - -- map flags - local flags_mapped = {} - for _, flag in pairs(flags) do - -- map it - local flag_mapped = compiler._mapflag(module, flag) - if flag_mapped then - table.insert(flags_mapped, flag_mapped) - end - end - - -- ok? - return flags_mapped -end - --- get the compiler flags from names -function compiler._getflags(module, names, flags) - - -- check - assert(flags) - - -- the mapped flags - local flags_mapped = {} - - -- wrap it first - names = utils.wrap(names) - for _, name in ipairs(names) do - table.join2(flags_mapped, compiler._mapflags(module, flags[name])) - end - - -- get it - return flags_mapped -end - --- add flags from the compiler -function compiler._addflags_from_compiler(module, flags, flagnames, kind) - - -- check - assert(module and flags and flagnames) - - -- done - for _, flagname in ipairs(flagnames) do - - -- add compiler.xxflags - table.join2(flags, module, module[flagname]) - - -- add compiler.kind.xxflags - if kind ~= nil and module[kind] ~= nil then - table.join2(flags, module, module[kind][flagname]) - end - end -end - --- add flags from the configure -function compiler._addflags_from_config(module, flags, flagnames) - - -- check - assert(module and flags and flagnames) - - -- done - for _, flagname in ipairs(flagnames) do - table.join2(flags, config.get(flagname)) - end -end - --- add flags from the platform -function compiler._addflags_from_platform(module, flags, flagnames) - - -- check - assert(module and flags and flagnames) - - -- add flags - for _, flagname in ipairs(flagnames) do - table.join2(flags, compiler._mapflags(module, platform.get(flagname))) - end - - -- add the includedirs flags - if module.flag_includedir then - for _, includedir in ipairs(utils.wrap(platform.get("includedirs"))) do - table.join2(flags, module:flag_includedir(includedir)) - end - end - - -- add the defines flags - if module.flag_define then - for _, define in ipairs(utils.wrap(platform.get("defines"))) do - table.join2(flags, module:flag_define(define)) - end - end - - -- append the undefines flags - if module.flag_undefine then - for _, undefine in ipairs(utils.wrap(platform.get("undefines"))) do - table.join2(flags, module:flag_undefine(undefine)) - end - end -end - - --- add flags from the target -function compiler._addflags_from_target(module, flags, flagnames, target) - - -- check - assert(module and flags and flagnames and target) - - -- add the target flags from the current project - for _, flagname in ipairs(flagnames) do - table.join2(flags, compiler._mapflags(module, target[flagname])) - end - - -- add the symbols flags from the current project - table.join2(flags, compiler._getflags(module, target.symbols, { debug = "-g" - , hidden = "-fvisibility=hidden" - })) - - -- add the warning flags from the current project - table.join2(flags, compiler._getflags(module, target.warnings, { none = "-w" - , less = "-W1" - , more = "-W3" - , all = "-Wall" - , error = "-Werror" - })) - - -- add the optimize flags from the current project - table.join2(flags, compiler._getflags(module, target.optimize, { none = "-O0" - , fast = "-O1" - , faster = "-O2" - , fastest = "-O3" - , smallest = "-Os" - , aggressive = "-Ofast" - })) - - -- add the vector extensions flags from the current project - table.join2(flags, compiler._getflags(module, target.vectorexts, { mmx = "-mmmx" - , sse = "-msse" - , sse2 = "-msse2" - , sse3 = "-msse3" - , ssse3 = "-mssse3" - , avx = "-mavx" - , avx2 = "-mavx2" - , neon = "-mfpu=neon" - })) - - -- add the language flags from the current project - local languages = {} - for _, flagname in ipairs(flagnames) do - if flagname == "cflags" or flagname == "mflags" then - table.join2(languages, { ansi = "-ansi" - , c89 = "-std=c89" - , gnu89 = "-std=gnu89" - , c99 = "-std=c99" - , gnu99 = "-std=gnu99" - , c11 = "-std=c11" - , gnu11 = "-std=gnu11" - }) - elseif flagname == "cxxflags" or flagname == "mxxflags" then - table.join2(languages, { cxx98 = "-std=c++98" - , gnuxx98 = "-std=gnu++98" - , cxx11 = "-std=c++11" - , gnuxx11 = "-std=gnu++11" - , cxx14 = "-std=c++14" - , gnuxx14 = "-std=gnu++14" - }) - end - end - table.join2(flags, compiler._getflags(module, target.languages, languages)) - - -- add the includedirs flags from the current project - if module.flag_includedir then - for _, includedir in ipairs(utils.wrap(target.includedirs)) do - table.join2(flags, module:flag_includedir(includedir)) - end - end - - -- add the defines flags from the current project - if module.flag_define then - for _, define in ipairs(utils.wrap(target.defines)) do - table.join2(flags, module:flag_define(define)) - end - end - - -- append the undefines flags from the current project - if module.flag_undefine then - for _, undefine in ipairs(utils.wrap(target.undefines)) do - table.join2(flags, module:flag_undefine(undefine)) - end - end - - -- the options - if target.options then - for _, name in ipairs(utils.wrap(target.options)) do - - -- get option if be enabled - local opt = nil - if config.get(name) then opt = config.get("__" .. name) end - if nil ~= opt then - - -- add the flags from the option - compiler._addflags_from_target(module, flags, flagnames, opt) - - -- append the defines flags - if opt.defines_if_ok and module.flag_define then - local defines = utils.wrap(opt.defines_if_ok) - for _, define in ipairs(defines) do - table.join2(flags, module:flag_define(define)) - end - end - - -- append the undefines flags - if opt.undefines_if_ok and module.flag_undefine then - local undefines = utils.wrap(opt.undefines_if_ok) - for _, undefine in ipairs(undefines) do - table.join2(flags, module:flag_undefine(undefine)) - end - end - end - end - end -end - --- add flags from the option -function compiler._addflags_from_option(module, flags, flagnames, opt) - - -- check - assert(module and flags and flagnames and opt) - - -- add the flags from the option - compiler._addflags_from_target(module, flags, flagnames, opt) - -end - --- get the flag names from the given compiler name -function compiler._flagnames(name) - - -- check - assert(name) - - -- the flag names - local flagnames = nil - if name == "cc" then flagnames = { "cxflags", "cflags" } - elseif name == "cxx" then flagnames = { "cxflags", "cxxflags" } - elseif name == "mm" then flagnames = { "mxflags", "mflags" } - elseif name == "mxx" then flagnames = { "mxflags", "mxxflags" } - elseif name == "as" then flagnames = { "asflags" } - elseif name == "sc" then flagnames = { "scflags" } - else - -- error - utils.error("unknown compiler: %s", name) - return - end - - -- ok - return flagnames -end - --- get the compiler kind from the source file type -function compiler._kind(srcfile) - - -- get the source file type - local filetype = path.extension(srcfile) - if not filetype then - return nil - end - - -- get the lower file type - filetype = filetype:lower() - - -- get the compiler kind - local kind = nil - if filetype == ".c" then kind = "cc" - elseif filetype == ".cpp" or filetype == ".cc" then kind = "cxx" - elseif filetype == ".m" then kind = "mm" - elseif filetype == ".mm" then kind = "mxx" - elseif filetype == ".s" or filetype == ".asm" then kind = "as" - elseif filetype == ".swift" then kind = "sc" - end - - -- ok - return kind -end - --- make the compile command for option -function compiler._make_for_option(module, opt, srcfile, objfile, logfile) - - -- check - assert(module and opt) - - -- the flag names - local flagnames = compiler._flagnames(module._KIND) - assert(flagnames) - - -- init flags - local flags = {} - - -- add flags from the configure - compiler._addflags_from_config(module, flags, flagnames) - - -- add flags from the option - compiler._addflags_from_option(module, flags, flagnames, opt) - - -- add flags from the platform - compiler._addflags_from_platform(module, flags, flagnames) - - -- add flags from the compiler - compiler._addflags_from_compiler(module, flags, flagnames) - - -- remove repeat - flags = utils.unique(flags) - - -- execute the compile command - return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile) -end - --- get the compiler from the given source file -function compiler.get(srcfile) - - -- get the compiler kind - local kind = compiler._kind(srcfile) - if not kind then - return nil, string.format("unknown source file: %s", srcfile) - end - - -- get compiler from the source file type - local module = tools.get(kind) - if module then - - -- invalid compiler - if not module.command_compile then - return nil, string.format("invalid compiler for %s", kind) - end - - -- save kind - module._KIND = kind - else - return nil, string.format("unknown compiler for %s", kind) - end - - -- ok? - return module -end - --- make the compile command -function compiler.make(module, target, srcfile, objfile, logfile) - - -- check - assert(module and target) - - -- the flag names - local flagnames = compiler._flagnames(module._KIND) - assert(flagnames) - - -- init flags - local flags = {} - - -- add flags from the configure - compiler._addflags_from_config(module, flags, flagnames) - - -- add flags from the target - compiler._addflags_from_target(module, flags, flagnames, target) - - -- add flags from the platform - compiler._addflags_from_platform(module, flags, flagnames) - - -- add flags from the compiler - compiler._addflags_from_compiler(module, flags, flagnames, target.kind) - - -- remove repeat - flags = utils.unique(flags) - - -- make the compile command - return module:command_compile(srcfile, objfile, table.concat(flags, " "):trim(), logfile) -end - --- check include for the project option -function compiler.check_include(opt, include, srcpath, objpath) - - -- check - assert(opt and srcpath and objpath) - - -- open the checking source file - local srcfile = io.openmk(srcpath) - if not srcfile then return end - - -- make include - if include then - srcfile:write(string.format("#include <%s>\n\n", include)) - end - - -- make the main function header - srcfile:write("int main(int argc, char** argv)\n") - srcfile:write("{\n") - srcfile:write(" return 0;\n") - srcfile:write("}\n") - - -- exit this file - srcfile:close() - - -- get the compiler - local module = compiler.get(srcpath) - if not module then return end - - -- execute the compile command - return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- check function for the project option -function compiler.check_function(opt, interface, srcpath, objpath) - - -- check - assert(opt and interface) - - -- open the checking source file - local srcfile = io.openmk(srcpath) - if not srcfile then return end - - -- get the compiler - local module = compiler.get(srcpath) - if not module then return end - - -- make includes - local includes = nil - if module._KIND == "cc" then includes = opt.cincludes - elseif module._KIND == "cxx" then includes = opt.cxxincludes - end - if includes then - for _, include in ipairs(utils.wrap(includes)) do - srcfile:write(string.format("#include <%s>\n", include)) - end - srcfile:write("\n") - end - - -- make the main function header - srcfile:write("int main(int argc, char** argv)\n") - srcfile:write("{\n") - - -- make interfaces - srcfile:write(string.format(" volatile void* p%s = (void*)&%s;\n\n", interface, interface)) - - -- make the main function tailer - srcfile:write(" return 0;\n") - srcfile:write("}\n") - - -- exit this file - srcfile:close() - - -- execute the compile command - return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- check typedef for the project option -function compiler.check_typedef(opt, typedef, srcpath, objpath) - - -- check - assert(opt and typedef) - - -- open the checking source file - local srcfile = io.openmk(srcpath) - if not srcfile then return end - - -- get the compiler - local module = compiler.get(srcpath) - if not module then return end - - -- make includes - local includes = nil - if module._KIND == "cc" then includes = opt.cincludes - elseif module._KIND == "cxx" then includes = opt.cxxincludes - end - if includes then - for _, include in ipairs(utils.wrap(includes)) do - srcfile:write(string.format("#include <%s>\n", include)) - end - srcfile:write("\n") - end - - -- make the main function header - srcfile:write("int main(int argc, char** argv)\n") - srcfile:write("{\n") - - -- make interfaces - srcfile:write(string.format(" typedef %s __type_xxx;\n\n", typedef)) - - -- make the main function tailer - srcfile:write(" return 0;\n") - srcfile:write("}\n") - - -- exit this file - srcfile:close() - - -- execute the compile command - return module:main(compiler._make_for_option(module, opt, srcpath, objpath, utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- return module: compiler -return compiler diff --git a/xmake/scripts/base/config.lua b/xmake/scripts/base/config.lua deleted file mode 100644 index 3cea6a652..000000000 --- a/xmake/scripts/base/config.lua +++ /dev/null @@ -1,395 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file config.lua --- - --- define module: config -local config = config or {} - --- load modules -local io = require("base/io") -local os = require("base/os") -local utils = require("base/utils") -local option = require("base/option") -local global = require("base/global") - --- make configure for the current target -function config._make(configs) - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- init current target configure - local current = {} - - -- get configs from the default configure - if configs._DEFAULTS then - for k, v in pairs(configs._DEFAULTS) do - if type(v) ~= "string" or v ~= "auto" then current[k] = v end - end - end - - -- get configs from the global configure - if global._CURRENT then - for k, v in pairs(global._CURRENT) do - current[k] = v - end - end - - -- get configs from all targets - for k, v in pairs(configs) do - if type(k) == "string" and not k:find("^_%u+") then - current[k] = v - end - end - - -- get configs from the current target - if configs._TARGETS and current.target ~= "all" then - - -- get the target config - local target_config = configs._TARGETS[current.target] - if target_config then - - -- merge it - for k, v in pairs(target_config) do - current[k] = v - end - end - end - - -- ok? - return current -end - --- get the configure file -function config._file() - - -- get it - return config.directory() .. "/xmake.conf" -end - --- need configure? -function config._need(name) - return name and name ~= "target" and name ~= "file" and name ~= "project" and name ~= "verbose" and name ~= "clean" -end - --- get the current target scope -function config._target() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check - local configs = config._CONFIGS - assert(configs) - - -- the target name - local name = options.target or options._DEFAULTS.target - assert(name and type(name) == "string") - - -- for all targets? - if name == "all" then - return configs - elseif configs._TARGETS then - -- get it - return configs._TARGETS[name] - end -end - --- get the given configure from the current -function config.get(name) - - -- the configure has been not loaded - if not config._CURRENT then return end - - -- get it - return config._CURRENT[name] -end - --- set the given configure to the current -function config.set(name, value) - - -- check - assert(config._CURRENT and name) - - -- get the current target - local target = config._target() - assert(target) - - -- set it to the current target configure for saving to file - target[name] = value - - -- set it to the current configure - config._CURRENT[name] = value -end - --- the given configure need probe automatically -function config.auto(name) - - -- the configs - local configs = config._CONFIGS - assert(configs) - - -- need probe it automatically? - if configs._DEFAULTS then - local value = configs._DEFAULTS[name] - if value then - if type(value) == "string" and value == "auto" then - return true - end - end - end - - -- need not probe it if have been setted manually - if config._CURRENT and nil ~= config._CURRENT[name] then - return false - end - - -- attempt to probe it if not exists - return true -end - --- get the configure directory -function config.directory() - - -- the directory - local dir = xmake._PROJECT_DIR .. "/.xmake" - - -- create it directly first if not exists - if not os.isdir(dir) then - assert(os.mkdir(dir)) - end - - -- get it - return dir -end - --- save xmake.conf -function config.save() - - -- the configs - local configs = config._CONFIGS - assert(configs) - - -- save to the configure file - return io.save(config._file(), configs) -end - -function config.load() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check - assert(option._MENU) - assert(option._MENU.config) - - -- the target name - local name = options.target or options._DEFAULTS.target - if not name then - return "no given target name!" - end - - -- does not clean the cached configure? - if not options.clean then - - -- load and execute the xmake.xconf - local filepath = config._file() - if os.isfile(filepath) then - - -- load the configure file - local configs, errors = io.load(filepath) - - -- exists local configures? - if configs then - - -- save configs - config._CONFIGS = configs - - -- make the current target configs - local current = config._make(configs) - - -- clear configs and mark as "rebuild" and "reconfig" if the host has been changed - if (current and current.host ~= xmake._HOST) then - - -- clear configs and mark as "rebuild" - config._CONFIGS = { __rebuild = true } - - -- mark as "reconfig" if the current action is not "config" - if options._ACTION ~= "config" then - config._RECONFIG = true - end - end - - -- clear configs and mark as "rebuild" if the plat has been changed - if current and current.plat and options.plat and current.plat ~= options.plat then - - -- clear configs and mark as "rebuild" - config._CONFIGS = { __rebuild = true } - end - - -- mark as "rebuild" if the arch has been changed - if current and current.arch and options.arch and current.arch ~= options.arch then - - -- mark as "rebuild" - config._CONFIGS.__rebuild = true - end - - -- mark as "rebuild" if the mode has been changed - if current and current.mode and options.mode and current.mode ~= options.mode then - - -- mark as "rebuild" - config._CONFIGS.__rebuild = true - end - elseif errors then - -- error - utils.error(errors) - end - end - end - - -- init configs if not exists - if not config._CONFIGS then - -- clear configs and mark as "rebuild" - config._CONFIGS = { __rebuild = true } - - -- mark as "reconfig" if the current action is not "config" - if options._ACTION ~= "config" then - config._RECONFIG = true - end - end - - -- the configs - local configs = config._CONFIGS - - -- mark as "rebuild" if clean the cached configure - if options.clean then - configs.__rebuild = true - end - - -- init the defaults - local defaults = nil - if not configs._DEFAULTS then - if config._RECONFIG then defaults = option.defaults("config") - elseif options._ACTION == "config" then defaults = options._DEFAULTS - end - if defaults then - for k, v in pairs(defaults) do - - -- check - assert(type(k) == "string") - - -- skip some options - if config._need(k) then - - -- save the default option - configs._DEFAULTS = configs._DEFAULTS or {} - configs._DEFAULTS[k] = v - end - end - end - end - defaults = configs._DEFAULTS - - -- init targets - configs._TARGETS = configs._TARGETS or {} - if name ~= "all" then - configs._TARGETS[name] = configs._TARGETS[name] or {} - end - - -- get the current target scope - local target = config._target() - assert(target and type(target) == "table") - - -- merge xmake._OPTIONS to target - if options._ACTION == "config" then - for k, v in pairs(options) do - - -- check - assert(type(k) == "string") - - -- skip some options - if not k:startswith("_") and config._need(k) then - - -- save the option to the target - target[k] = v - - -- remove it from the defaults, because we have setted it manually - if defaults then defaults[k] = nil end - end - end - end - - -- make the current config - config._CURRENT = config._make(config._CONFIGS) -end - --- clear up and remove all auto values -function config.clearup() - - -- clear up the current configure - local current = config._CURRENT - if current then - for k, v in pairs(current) do - if type(v) == "string" and v == "auto" then - current[k] = nil - end - end - end - - -- clear up the current target configure - local target = config._target() - if target then - for k, v in pairs(target) do - if type(v) == "string" and v == "auto" then - target[k] = nil - end - end - end - -end - --- reload configure -function config.reload() - - -- clear the old configure - config._CURRENT = nil - config._CONFIGS = nil - - -- load it - return config.load() -end - --- dump the current configure -function config.dump() - - -- check - assert(config._CURRENT) - - -- dump - utils.dump(config._CURRENT, "__%w*", "configure") - -end - --- return module: config -return config diff --git a/xmake/scripts/base/global.lua b/xmake/scripts/base/global.lua deleted file mode 100644 index 0017590c6..000000000 --- a/xmake/scripts/base/global.lua +++ /dev/null @@ -1,246 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file global.lua --- - --- define module: global -local global = global or {} - --- load modules -local io = require("base/io") -local os = require("base/os") -local utils = require("base/utils") -local option = require("base/option") - --- make configure -function global._make() - - -- the configs - local configs = global._CONFIGS - assert(configs) - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- init current global configure - global._CURRENT = global._CURRENT or {} - local current = global._CURRENT - - -- make current global configure - for k, v in pairs(configs) do - if type(k) == "string" and not k:find("^_%u+") then - current[k] = v - end - end -end - --- get the configure file -function global._file() - - -- get it - return global.directory() .. "/xmake.conf" -end - --- need configure? -function global._need(name) - return name and name ~= "verbose" and name ~= "clean" -end - --- get the given configure from the current -function global.get(name) - - -- check - assert(global._CURRENT) - - -- the value - local value = global._CURRENT[name] - if value and value == "auto" then - value = nil - end - - -- get it - return value -end - --- set the given configure to the current -function global.set(name, value) - - -- check - assert(global._CURRENT and global._CONFIGS) - assert(name and value and type(value) ~= "table") - - -- set it to the current configure - global._CURRENT[name] = value - - -- set it to the configure for saving to file - global._CONFIGS[name] = value - -end - --- get the global configure directory -function global.directory() - - -- the directory - local dir = path.translate("~/.xmake") - - -- create it directly first if not exists - if not os.isdir(dir) then - assert(os.mkdir(dir)) - end - - -- get it - return dir -end - --- save xmake.conf -function global.save() - - -- the configs - local configs = global._CONFIGS - assert(configs) - - -- save to the configure file - return io.save(global._file(), configs) -end - --- load xmake.conf -function global.load() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- check - assert(option._MENU) - assert(option._MENU.global) - - -- get all configure names - local i = 1 - local configures = {} - for _, o in ipairs(option._MENU.global.options) do - local name = o[2] - if global._need(name) then - configures[i] = name - i = i + 1 - end - end - - -- does not clean the cached configure? - if not options.clean then - - -- load and execute the xmake.conf - local filepath = global._file() - if os.isfile(filepath) then - - -- load the configure file - local configs, errors = io.load(filepath) - - -- exists local configures? - if configs then - -- save configs - global._CONFIGS = configs - elseif errors then - -- error - utils.error(errors) - end - end - end - - -- init configs - global._CONFIGS = global._CONFIGS or {} - local configs = global._CONFIGS - - -- xmake global? - if options._ACTION == "global" then - - -- merge xmake._OPTIONS to the global configure - for k, v in pairs(options) do - - -- check - assert(type(k) == "string") - - -- need configure it? - if not k:startswith("_") and global._need(k) then - configs[k] = v - end - end - - -- merge the default global configure options to the global configure - local defaults = options._DEFAULTS - if defaults then - for k, v in pairs(defaults) do - - -- check - assert(type(k) == "string") - - -- need configure it? - if global._need(k) then - - -- save the default option - if nil == configs[k] then - configs[k] = v - end - end - end - end - end - - -- make the current global - global._make() -end - --- clear up and remove all auto values -function global.clearup() - - -- clear up the current configure - local current = global._CURRENT - if current then - for k, v in pairs(current) do - if v and type(v) and v == "auto" then - current[k] = nil - end - end - end - - -- clear up the configure - local configs = global._CONFIGS - if configs then - for k, v in pairs(configs) do - if v and type(v) and v == "auto" then - configs[k] = nil - end - end - end -end - --- dump the current configure -function global.dump() - - -- check - assert(global._CURRENT) - - -- dump - utils.dump(global._CURRENT, "__%w*", "configure") - -end - --- return module: global -return global diff --git a/xmake/scripts/base/install.lua b/xmake/scripts/base/install.lua deleted file mode 100644 index 9fc41a14a..000000000 --- a/xmake/scripts/base/install.lua +++ /dev/null @@ -1,143 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file install.lua --- - --- define module: install -local install = install or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- install target from the project script -function install._done_from_project(target) - - -- check - assert(target) - - -- install it using the project script first - local installscript = target.installscript - if type(installscript) == "function" then - - -- remove it - target.installscript = nil - - -- install it - return installscript(target) - end - - -- continue - return 0 -end - --- install target from the platform script -function install._done_from_platform(target) - - -- check - assert(target) - - -- the platform install script file - local installscript = nil - local scriptfile = platform.directory() .. "/install.lua" - if os.isfile(scriptfile) then - - -- load the install script - local script, errors = loadfile(scriptfile) - if script then - installscript = script() - if type(installscript) == "table" and installscript.main then - installscript = installscript.main - end - else - utils.error(errors) - end - end - - -- install it - if type(installscript) == "function" then - return installscript(target) - end - - -- continue - return 0 -end - --- install target from the given target configure -function install._done(target) - - -- check - assert(target) - - -- install it from the project script - local ok = install._done_from_project(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- install it from the platform script - local ok = install._done_from_platform(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- ok - return true -end - --- get the configure file -function install._file() - - -- get it - return config.directory() .. "/install.conf" -end - --- done install from the configure -function install.done(configs) - - -- check - assert(configs) - - -- install targets - for _, target in pairs(configs) do - - -- install it - if not install._done(target) then - -- errors - utils.error("install %s failed!", target.name) - return false - end - - end - - -- save to the configure file - return io.save(install._file(), configs) -end - --- load the install configure -function install.load() - - -- load it - return io.load(install._file()) -end - --- return module: install -return install diff --git a/xmake/scripts/base/io.lua b/xmake/scripts/base/io.lua deleted file mode 100644 index 66b23911a..000000000 --- a/xmake/scripts/base/io.lua +++ /dev/null @@ -1,324 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file io.lua --- - --- define module: io -local io = io or {} - --- load modules -local path = require("base/path") -local utils = require("base/utils") - --- save object with the level -function io._save_with_level(file, object, level) - - -- save string - if type(object) == "string" then - file:write(string.format("%q", object)) - -- save boolean - elseif type(object) == "boolean" then - file:write(tostring(object)) - -- save number - elseif type(object) == "number" then - file:write(object) - -- save table - elseif type(object) == "table" then - - -- save head - file:write("\n") - for l = 1, level do - file:write(" ") - end - file:write("{\n") - - -- save body - local i = 0 - for k, v in pairs(object) do - - -- save spaces and separator - for l = 1, level do - file:write(" ") - end - - file:write(utils.ifelse(i == 0, " ", ", ")) - - -- save key - if type(k) == "string" then - file:write(string.format("[%q]", k), " = ") - end - - -- save value - if not io._save_with_level(file, v, level + 1) then - return false - end - - -- save newline - file:write("\n") - i = i + 1 - end - - -- save tail - for l = 1, level do - file:write(" ") - end - file:write("}\n") - else - -- error - utils.error("invalid object type: %s", type(object)) - return false - end - - -- ok - return true -end - --- save object to given file -function io._save(file, object) - - -- save it - return io._save_with_level(file, object, 0) -end - --- create directory and open a writable file -function io.openmk(filepath) - - -- check - assert(filepath) - - -- get the file directory - local dir = path.directory(filepath) - - -- ensure the file directory - if not os.isdir(dir) then os.mkdir(dir) end - - -- open it - return io.open(filepath, "w") -end - --- read all data from file -function io.readall(filepath) - - -- open file - local file = io.open(filepath, "r") - if not file then - -- error - return nil, string.format("open %s failed!", filepath) - end - - -- read all - local data = file:read("*all") - - -- exit file - file:close() - - -- ok? - return data -end - --- write all data to file -function io.writall(filepath, data) - - -- open file - local file = io.open(filepath, "w") - if not file then - -- error - return false, string.format("open %s failed!", filepath) - end - - -- write all - file:write(data) - - -- exit file - file:close() - - -- ok? - return true -end - --- save object the the given filepath -function io.save(filepath, object) - - -- open the file - local file = io.openmk(filepath) - if not file then - -- error - return false, string.format("open %s failed!", filepath) - end - - -- save object to file - if not io._save(file, object) then - -- error - file:close() - return false, string.format("save %s failed!", filepath) - end - - -- close file - file:close() - - -- ok - return true -end - --- load object from the given file -function io.load(filepath) - - -- open the file - local file = io.open(filepath, "r") - if not file then - -- error - return nil, string.format("open %s failed!", filepath) - end - - -- load data - local result = nil - local errors = nil - local data = file:read("*all") - if data and type(data) == "string" then - - -- load script - local script, errs = loadstring("return " .. data) - if script then - - -- load object - local ok, object = pcall(script) - if ok and object then - result = object - elseif object then - -- error - errors = object - else - -- error - errors = string.format("load %s failed!", filepath) - end - -- errors - else errors = errs end - end - - -- close file - file:close() - - -- ok? - return result, errors -end - --- gsub the given file and return replaced data -function io.gsub(filepath, pattern, replace) - - -- read all data from file - local data, errors = io.readall(filepath) - if not data then return nil, 0, errors end - - -- replace it - local count = 0 - if type(data) == "string" then - data, count = data:gsub(pattern, replace) - else - return nil, 0, string.format("data is not string!") - end - - -- replace ok? - if count ~= 0 then - -- write all data to file - local ok, errors = io.writall(filepath, data) - if not ok then return nil, 0, errors end - end - - -- ok - return data, count -end - --- cat the given file -function io.cat(filepath, linecount) - - -- open file - local file = io.open(filepath, "r") - if file then - - -- show file - local count = 1 - for line in file:lines() do - - -- show line - print(line) - - -- end? - if linecount and count >= linecount then - break - end - - -- update the line count - count = count + 1 - end - - -- exit file - file:close() - end -end - --- tail the given file -function io.tail(filepath, linecount) - - -- open file - local file = io.open(filepath, "r") - if file then - - -- read lines - local lines = {} - for line in file:lines() do - table.insert(lines, line) - end - - -- tail lines - local tails = {} - if #lines ~= 0 then - local count = 1 - for index = #lines, 1, -1 do - - -- show line - table.insert(tails, lines[index]) - - -- end? - if linecount and count >= linecount then - break - end - - -- update the line count - count = count + 1 - end - end - - -- show tails - if #tails ~= 0 then - for index = #tails, 1, -1 do - - -- show tail - print(tails[index]) - - end - end - - -- exit file - file:close() - end -end - --- return module: io -return io diff --git a/xmake/scripts/base/linker.lua b/xmake/scripts/base/linker.lua deleted file mode 100644 index 9a0388757..000000000 --- a/xmake/scripts/base/linker.lua +++ /dev/null @@ -1,386 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file linker.lua --- - --- define module: linker -local linker = linker or {} - --- load modules -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local config = require("base/config") -local compiler = require("base/compiler") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- map gcc flag to the given linker flag -function linker._mapflag(module, flag) - - -- check - assert(module.mapflags and flag) - - -- attempt to map it directly - local flag_mapped = module.mapflags[flag] - if flag_mapped and type(flag_mapped) == "string" then - return flag_mapped - end - - -- find and replace it using pattern - for k, v in pairs(module.mapflags) do - local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) - if type(v) == "function" then - return v(module, w) - else - return v - end - end) - if flag_mapped and count ~= 0 then - return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil) - end - end - - -- return it directly - return flag -end - --- map gcc flags to the given linker flags -function linker._mapflags(module, flags) - - -- check - assert(module) - - -- wrap flags first - flags = utils.wrap(flags) - - -- need not map flags? return it directly - if not module.mapflags then - return flags - end - - -- map flags - local flags_mapped = {} - for _, flag in pairs(flags) do - -- map it - local flag_mapped = linker._mapflag(module, flag) - if flag_mapped then - table.insert(flags_mapped, flag_mapped) - end - end - - -- ok? - return flags_mapped -end - --- get the linker flags from names -function linker._getflags(module, names, flags) - - -- check - assert(flags) - - -- the mapped flags - local flags_mapped = {} - - -- wrap it first - names = utils.wrap(names) - for _, name in ipairs(names) do - table.join2(flags_mapped, linker._mapflags(module, flags[name])) - end - - -- get it - return flags_mapped -end - - --- add flags from the links -function linker._addflags_from_links(module, flags, links) - - -- check - assert(module and flags and links) - - -- done - if module.flag_link then - for _, link in ipairs(utils.wrap(links)) do - table.join2(flags, module:flag_link(link)) - end - end -end - --- add flags from the linker -function linker._addflags_from_linker(module, flags, flagname) - - -- check - assert(module and flags and flagname) - - -- done - table.join2(flags, module[flagname]) -end - --- add flags from the compiler -function linker._addflags_from_compiler(module, flags, flagname, srcfiles) - - -- check - assert(module and flags and flagname) - - -- add the flags for compiler - local flags_for_compiler = {} - if srcfiles then - for _, srcfile in ipairs(utils.wrap(srcfiles)) do - - -- get the compiler - local c, errors = compiler.get(srcfile) - if not c then - -- error - utils.error(errors) - return - end - - -- add flags - table.join2(flags_for_compiler, c[flagname]) - end - end - - -- done - table.join2(flags, utils.unique(flags_for_compiler)) -end - --- add flags from the configure -function linker._addflags_from_config(module, flags, flagname) - - -- check - assert(module and flags and flagname) - - -- done - table.join2(flags, config.get(flagname)) -end - --- add flags from the platform -function linker._addflags_from_platform(module, flags, flagname) - - -- check - assert(module and flags and flagname) - - -- add flags - table.join2(flags, linker._mapflags(module, platform.get(flagname))) - - -- add the linkdirs flags - if module.flag_linkdir then - for _, linkdir in ipairs(utils.wrap(platform.get("linkdirs"))) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end - - -- add the links flags - if module.flag_link then - for _, link in ipairs(utils.wrap(platform.get("links"))) do - table.join2(flags, module:flag_link(link)) - end - end -end - --- add flags from the target -function linker._addflags_from_target(module, flags, flagname, target) - - -- check - assert(module and flags and flagname and target) - - -- add the target flags from the current project - table.join2(flags, linker._mapflags(module, target[flagname])) - - -- add the linkdirs flags from the current project - if module.flag_linkdir then - for _, linkdir in ipairs(utils.wrap(target.linkdirs)) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end - - -- add the links flags from the current project - if module.flag_link then - for _, link in ipairs(utils.wrap(target.links)) do - table.join2(flags, module:flag_link(link)) - end - end - - -- the options - if target.options then - for _, name in ipairs(utils.wrap(target.options)) do - - -- get option if be enabled - local opt = nil - if config.get(name) then opt = config.get("__" .. name) end - if nil ~= opt then - - -- add the flags from the option - table.join2(flags, linker._mapflags(module, opt[flagname])) - - -- add the linkdirs flags from the option - if module.flag_linkdir then - for _, linkdir in ipairs(utils.wrap(opt.linkdirs)) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end - - -- add the links flags from the option - if module.flag_link then - for _, link in ipairs(utils.wrap(opt.links)) do - table.join2(flags, module:flag_link(link)) - end - end - end - end - end - - -- add the flags from the configure - table.join2(flags, linker._mapflags(module, config.get(flagname))) - - -- add the strip flags from the current project - table.join2(flags, linker._getflags(module, target.strip, { debug = "-S" - , all = "-s" - })) -end - --- add flags from the option -function linker._addflags_from_option(module, flags, flagname, opt) - - -- check - assert(module and flags and flagname and opt) - - -- append the option flags - table.join2(flags, linker._mapflags(module, opt[flagname])) - - -- append the linkdirs flags - if opt.linkdirs and module.flag_linkdir then - for _, linkdir in ipairs(utils.wrap(opt.linkdirs)) do - table.join2(flags, module:flag_linkdir(linkdir)) - end - end -end - --- get the linker from the given kind -function linker.get(kind) - - -- check - assert(kind) - - -- get the linker name from the kind - local name = nil - if kind == "binary" then name = "ld" - elseif kind == "static" then name = "ar" - elseif kind == "shared" then name = "sh" - else return end - - -- get it - local module = tools.get(name) - - -- invalid linker? - if module and not module.command_link then - return - end - - -- ok? - return module -end - --- make the link command -function linker.make(module, target, srcfiles, objfiles, targetfile, logfile) - - -- check - assert(module and target) - - -- the target kind - local kind = target.kind or "" - - -- the flag name - local flagname = nil - if kind == "binary" then flagname = "ldflags" - elseif kind == "static" then flagname = "arflags" - elseif kind == "shared" then flagname = "shflags" - else - -- error - utils.error("unknown type for linker: %s", kind) - return - end - - -- init flags - local flags = {} - - -- add flags from the configure - linker._addflags_from_config(module, flags, flagname) - - -- add flags from the target - linker._addflags_from_target(module, flags, flagname, target) - - -- add flags from the platform - linker._addflags_from_platform(module, flags, flagname) - - -- add flags from the compiler - linker._addflags_from_compiler(module, flags, flagname, srcfiles) - - -- add flags from the linker - linker._addflags_from_linker(module, flags, flagname) - - -- remove repeat - flags = utils.unique(flags) - - -- make the link command - return module:command_link(table.concat(objfiles, " "), targetfile, table.concat(flags, " "):trim(), logfile) -end - --- check link for the project option -function linker.check_links(opt, links, sourcefile, objectfile, targetfile) - - -- check - assert(opt and links and objectfile and targetfile) - - -- get the linker - local module = linker.get("binary") - assert(module and module.flag_link) - - -- init flags - local flags = {} - - -- add flags from the configure - linker._addflags_from_config(module, flags, "ldflags") - - -- add flags from the option - linker._addflags_from_option(module, flags, "ldflags", opt) - - -- add flags from the platform - linker._addflags_from_platform(module, flags, "ldflags") - - -- add flags from the links - linker._addflags_from_links(module, flags, links) - - -- add flags from the compiler - linker._addflags_from_compiler(module, flags, "ldflags", sourcefile) - - -- add flags from the linker - linker._addflags_from_linker(module, flags, "ldflags") - - -- remove repeat - flags = utils.unique(flags) - - -- execute the link command - return module:main(module:command_link(objectfile, targetfile, table.concat(flags, " "):trim(), utils.ifelse(xmake._OPTIONS.verbose, nil, xmake._NULDEV))) -end - --- return module: linker -return linker diff --git a/xmake/scripts/base/main.lua b/xmake/scripts/base/main.lua deleted file mode 100644 index 470815701..000000000 --- a/xmake/scripts/base/main.lua +++ /dev/null @@ -1,179 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file main.lua --- - --- define module: main -local main = main or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local option = require("base/option") -local action = require("action/action") - --- init the option menu -local menu = -{ - -- title - title = xmake._VERSION .. ", The Automatic Cross-platform Build Tool" - - -- copyright -, copyright = "Copyright (C) 2015-2016 Ruki Wang, tboox.org\nCopyright (C) 2005-2014 Mike Pall, luajit.org" - - -- build project: xmake -, main = - { - -- usage - usage = "xmake [action] [options] [target]" - - -- description - , description = "Build the project if no given action." - - -- actions - , actions = action.list - - -- options - , options = - { - {'b', "build", "k", nil, "Build project. This is default building mode and optional." } - , {'u', "update", "k", nil, "Only relink and update the binary files." } - , {'r', "rebuild", "k", nil, "Rebuild the project." } - - , {} - , {'f', "file", "kv", "xmake.lua", "Read a given xmake.lua file." } - , {'P', "project", "kv", nil, "Change to the given project directory." - , "Search priority:" - , " 1. The Given Command Argument" - , " 2. The Envirnoment Variable: XMAKE_PROJECT_DIR" - , " 3. The Current Directory" } - - - , {} - , {'j', "jobs", "kv", nil, "Specifies the number of jobs to build simultaneously" } - , {'v', "verbose", "k", nil, "Print lots of verbose information." } - , {nil, "version", "k", nil, "Print the version number and exit." } - , {'h', "help", "k", nil, "Print this help message and exit." } - - , {} - , {nil, "target", "v", "all", "Build the given target." } - } - } - - -- the actions: xmake [action] -, action.menu - -} - --- done help -function main._done_help() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- done help - if options.help then - - -- print menu - option.print_menu(options._ACTION) - - -- ok - return true - - -- done version - elseif options.version then - - -- print title - if option._MENU.title then - print(option._MENU.title) - end - - -- print copyright - if option._MENU.copyright then - print(option._MENU.copyright) - end - - -- ok - return true - end -end - --- done option -function main._done_option() - - -- the options - local options = xmake._OPTIONS - assert(options) - - -- done help? - if main._done_help() then - return true - end - - -- done action - return action.done(options._ACTION or "build") -end - --- the init function for main -function main._init() - - -- init the project directory - local projectdir = option.find(xmake._ARGV, "project", "P") or xmake._PROJECT_DIR - if projectdir and not path.is_absolute(projectdir) then - projectdir = path.absolute(projectdir) - elseif projectdir then - projectdir = path.translate(projectdir) - end - xmake._PROJECT_DIR = projectdir - assert(projectdir) - - -- init the xmake.lua file path - local projectfile = option.find(xmake._ARGV, "file", "f") or xmake._PROJECT_FILE - if projectfile and not path.is_absolute(projectfile) then - projectfile = path.absolute(projectfile, projectdir) - end - xmake._PROJECT_FILE = projectfile - assert(projectfile) -end - --- the main function -function main.done() - - -- init - main._init() - - -- init option - if not option.init(xmake._ARGV, menu) then - return -1 - end - - -- done option - if not main._done_option() then - return -1 - end - - -- ok - return 0 -end - --- return module: main -return main diff --git a/xmake/scripts/base/makefile.lua b/xmake/scripts/base/makefile.lua deleted file mode 100644 index 826310d1a..000000000 --- a/xmake/scripts/base/makefile.lua +++ /dev/null @@ -1,417 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file makefile.lua --- - --- define module: makefile -local makefile = makefile or {} - --- load modules -local io = require("base/io") -local os = require("base/os") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local project = require("base/project") -local linker = require("base/linker") -local compiler = require("base/compiler") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- make object for the *.[o|obj] source file -function makefile._make_object_for_object(file, target, srcfile, objfile) - - -- get the source file type - local filetype = path.extension(srcfile) - if not filetype then return false end - - -- get the lower file type - filetype = filetype:lower() - - -- not object file? - if filetype ~= ".o" and filetype ~= ".obj" then return false end - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- make command - local cmd = string.format("xmake l cp %s %s", srcfile, objfile) - - -- make head - file:write(string.format("%s:", objfile)) - - -- make dependence - file:write(string.format(" %s\n", srcfile)) - - -- make body - file:write(string.format("\t@echo inserting%s %s\n", mode, srcfile)) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) - file:write(string.format("\t@%s\n", cmd)) - - -- make tail - file:write("\n") - - -- ok - return true -end - --- make object for the *.[a|lib] source file -function makefile._make_object_for_static(file, target, srcfile, objfile) - - -- get the source file type - local filetype = path.extension(srcfile) - if not filetype then return false end - - -- get the lower file type - filetype = filetype:lower() - - -- not static file? - if filetype ~= ".a" and filetype ~= ".lib" then return false end - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- make command - local cmd = string.format("xmake l -P %s -f %s dispatcher ex extract %s %s > %s 2>&1", xmake._PROJECT_DIR, xmake._PROJECT_FILE, srcfile:encode(), objfile:encode(), makefile._LOGFILE) - - -- make head - file:write(string.format("%s:", objfile)) - - -- make dependence - file:write(string.format(" %s\n", srcfile)) - - -- make body - file:write(string.format("\t@echo inserting%s %s\n", mode, srcfile)) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) - file:write(string.format("\t@xmake l rmdir %s\n", path.directory(objfile))) - file:write(string.format("\t@%s\n", cmd)) - - -- make tail - file:write("\n") - - -- ok - return true -end - --- make the object to the makefile -function makefile._make_object(file, target, srcfile, objfile) - - -- check - assert(file and target and srcfile and objfile) - - -- make object for the *.o/obj source file - if makefile._make_object_for_object(file, target, srcfile, objfile) then - return true - elseif makefile._make_object_for_static(file, target, srcfile, objfile) then - return true - end - - -- get the compiler - local c, errors = compiler.get(srcfile) - if not c then - -- error - utils.error(errors) - return false - end - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- get ccache - local ccache = platform.tool("ccache") - - -- make command - local cmd = compiler.make(c, target, srcfile, objfile, makefile._LOGFILE) - if ccache then - cmd = ccache:append(cmd, " ") - end - - -- make head - file:write(string.format("%s:", objfile)) - - -- make dependence - file:write(string.format(" %s\n", srcfile)) - - -- make body - file:write(string.format("\t@echo %scompiling%s %s\n", utils.ifelse(ccache, "ccache ", ""), mode, srcfile)) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", cmd:encode())) - file:write(string.format("\t@xmake l mkdir %s\n", path.directory(objfile))) - file:write(string.format("\t@%s\n", cmd)) - - -- make tail - file:write("\n") - - -- ok - return true -end - --- make all objects of the given target to the makefile -function makefile._make_objects(file, target, srcfiles, objfiles) - - -- check - assert(file and target and srcfiles and objfiles) - - -- make all objects - local i = 1 - for _, objfile in ipairs(objfiles) do - - -- make object - if not makefile._make_object(file, target, srcfiles[i], objfile) then - return false - end - - -- next - i = i + 1 - end - - -- ok - return true -end - --- make the given target to the makefile -function makefile._make_target(file, name, target) - - -- check - assert(file and name and target and target.kind) - - -- get source and object files - local srcfiles = rule.sourcefiles(target) - local objfiles = rule.objectfiles(name, target, srcfiles) - assert(srcfiles and objfiles) - - -- get source and destinate header files - local srcheaders, dstheaders = rule.headerfiles(target) - - -- get target file - local targetfile = rule.targetfile(name, target) - assert(targetfile) - - -- get the targets - local targets = project.targets() - assert(targets) - - -- get the linker from the given kind - local l = linker.get(target.kind) - if not l then - utils.error("cannot get linker with kind: %s", target.kind) - return false - end - - -- make head - file:write(string.format("%s: %s\n", name, targetfile)) - file:write(string.format("%s:", targetfile)) - - -- make dependence for the dependent targets - if target.deps then - - -- get all dependent target - local deps = utils.wrap(target.deps) - for _, dep in ipairs(deps) do - - -- the dependent target - local deptarget = targets[dep] - if not deptarget then - utils.error("the dependent target: %s is invalid!", dep) - return false - end - - -- get the dependent target file - local depfile = rule.targetfile(dep, deptarget) - assert(depfile) - - -- add dependence - file:write(" " .. depfile) - end - end - - -- make dependence for objects - for _, objfile in ipairs(objfiles) do - file:write(" " .. objfile) - end - - -- make dependence end - file:write("\n") - - -- get mode - local mode = config.get("mode") - if mode then - mode = "." .. mode - else - mode = "" - end - - -- make the command - local cmd = linker.make(l, target, srcfiles, objfiles, targetfile, makefile._LOGFILE) - - -- the verbose - local verbose = cmd:encode() - -- too long? - if verbose and #verbose > 256 then - verbose = linker.make(l, target, srcfiles, {rule.filename("*", "object")}, targetfile) - verbose = verbose:encode() - end - - -- make body - file:write(string.format("\t@echo linking%s %s\n", mode, path.filename(targetfile))) - file:write(string.format("\t@xmake l $(VERBOSE) verbose \"%s\"\n", verbose)) - file:write(string.format("\t@xmake l mkdir %s\n", path.directory(targetfile))) - file:write(string.format("\t@%s\n", cmd)) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - file:write(string.format("\t@xmake l cp %s %s\n", srcheader, dstheader)) - end - i = i + 1 - end - end - - -- make tail - file:write("\n") - - -- make objects for this target - return makefile._make_objects(file, target, srcfiles, objfiles) -end - --- make all targets to the makefile -function makefile._make_targets(file) - - -- check - assert(file) - - -- get all project targets - local targets = project.targets() - if not targets then - -- error - utils.error("not found target in this project!") - return false - end - - -- make all first - local all = "" - for name, _ in pairs(targets) do - -- append the target name to all - all = all .. " " .. name - end - file:write(string.format("all: %s\n\n", all)) - file:write(string.format(".PHONY: all %s\n\n", all)) - - -- make it for all targets - for name, target in pairs(targets) do - -- make target - if not makefile._make_target(file, name, target) then - -- error - utils.error("failed to make target %s to makefile!", name) - return false - end - - -- append the target name to all - all = all .. " " .. name - end - - -- ok - return true -end - --- make makefile in the build directory -function makefile.make() - - -- get the build directory - local buildir = config.get("buildir") - assert(buildir) - - -- init the log file - local logfile = rule.logfile() - if logfile and os.isfile(logfile) then - os.rmfile(logfile) - end - - -- save the log file - makefile._LOGFILE = logfile - assert(logfile) - - -- open the makefile - local path = rule.makefile() - local file = io.openmk(path) - if not file then - -- error - utils.error("open %s failed!", path) - return false - end - - -- make all targets to the makefile - if not makefile._make_targets(file) then - - -- error - utils.error("save %s failed!", path) - - -- close the makefile - file:close() - - -- remove the makefile - os.rm(path) - - -- failed - return false - end - - -- close the makefile - file:close() - - -- ok - return true -end - --- build target -function makefile.build(target) - - -- check - assert(target and type(target) == "string") - - -- load make - local make = tools.get("make") - if not make then - utils.error("not found the make command!") - return false - end - - -- done make - return make:main(rule.makefile(), target) -end - --- return module: makefile -return makefile diff --git a/xmake/scripts/base/option.lua b/xmake/scripts/base/option.lua deleted file mode 100644 index 1c8c35573..000000000 --- a/xmake/scripts/base/option.lua +++ /dev/null @@ -1,650 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file option.lua --- - --- define module: option -local option = option or {} - --- load modules -local utils = require("base/utils") -local table = require("base/table") - --- save the option menu -function option._save_menu(menu) - - -- translate the action menus if exists function - local submenus_all = {} - for k, submenu in pairs(menu) do - if type(submenu) == "function" then - local _submenus = submenu() - if _submenus then - for k, m in pairs(_submenus) do - submenus_all[k] = m - end - end - else - submenus_all[k] = submenu - end - end - table.copy2(menu, submenus_all) - - -- translate the actions of the main menu if exists function - if menu.main and type(menu.main.actions) == "function" then - menu.main.actions = menu.main.actions() - end - - -- translate it if exists function in the option menu - for _, submenu in pairs(menu) do - - -- exits options? - if submenu.options then - - -- translate options - local options_all = {} - for _, option in ipairs(submenu.options) do - - -- this option is function? translate it - if type(option) == "function" then - local _options = option() - if _options then - for _, o in ipairs(_options) do - table.insert(options_all, o) - end - end - else - table.insert(options_all, option) - end - end - - -- update the options - submenu.options = options_all - end - end - - -- save menu - option._MENU = menu - -end - --- init the option -function option.init(argv, menu) - - -- check - assert(argv and menu) - - -- the main menu - local main = menu.main - assert(main) - - -- init _OPTIONS - xmake._OPTIONS = {} - xmake._OPTIONS._DEFAULTS = {} - - -- save menu - option._save_menu(menu) - - -- parse _ARGV to _OPTIONS - local _iter, _s, _k = ipairs(argv) - while true do - - -- the idx and arg - local idx, arg = _iter(_s, _k) - - -- end? - _k = idx - if idx == nil then break end - - -- parse key and value - local key, value - local i = arg:find("=", 1, true) - - -- key=value? - if i then - key = arg:sub(1, i - 1) - value = arg:sub(i + 1) - -- only key? - else - key = arg - value = true - end - - -- --key? - local prefix = 0 - if key:startswith("--") then - key = key:sub(3) - prefix = 2 - -- -k? - elseif key:startswith("-") then - key = key:sub(2) - prefix = 1 - end - - -- check key - if prefix and #key == 0 then - - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- --key=value or -k value or -k? - if prefix ~= 0 then - - -- find this option - local opt = nil - for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do - - -- check - assert(o) - - -- --key? - if prefix == 2 and key == o[2] then - opt = o - break - -- k? - elseif prefix == 1 and key == o[1] then - opt = o - break - end - end - - -- not found? - if not opt then - - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- -k value? continue to get the value - if prefix == 1 and opt[3] == "kv" then - - -- get the next idx and arg - idx, arg = _iter(_s, _k) - - -- exists value? - _k = idx - if idx == nil or arg:startswith("-") then - - -- invalid option - print("invalid option: " .. utils.ifelse(idx, arg, key)) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- get value - value = arg - end - - -- check mode - if (opt[3] == "k" and type(value) ~= "boolean") or (opt[3] == "kv" and type(value) ~= "string") then - - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - -- value is "true" or "false", translate it - if type(value) == "string" then - if value == "true" then value = true - elseif value == "false" then value = false - end - end - - -- save option - xmake._OPTIONS[utils.ifelse(prefix == 1 and opt[2], opt[2], key)] = value - - -- action? - elseif idx == 1 then - - -- find this action - for _, action in ipairs(main.actions) do - - -- check - assert(menu[action]) - - -- ok? - if action == key or menu[action].shortname == key then - -- save this action - xmake._OPTIONS._ACTION = action - break - end - end - - -- not found? - if not xmake._OPTIONS._ACTION or not menu[xmake._OPTIONS._ACTION] then - - -- invalid action - print("invalid action: " .. key) - - -- print the main menu - option.print_main() - - -- failed - return false - - end - - -- value? - else - - -- find a value option with name - local opt = nil - for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do - - -- the mode - local mode = o[3] - - -- the name - local name = o[2] - - -- check - assert(o and ((mode ~= "v" and mode ~= "vs") or name)) - - -- is value and with name? - if mode == "v" and name and not xmake._OPTIONS[name] then - opt = o - break - -- is values and with name? - elseif mode == "vs" and name then - opt = o - break - end - end - - -- ok? save this value with name opt[2] - if opt then - - -- the mode - local mode = opt[3] - - -- the name - local name = opt[2] - - -- save value - if mode == "v" then - xmake._OPTIONS[name] = key - elseif mode == "vs" then - -- the option - local o = xmake._OPTIONS[name] - if not o then - xmake._OPTIONS[name] = {} - o = xmake._OPTIONS[name] - end - - -- append value - table.insert(o, key) - end - else - -- invalid option - print("invalid option: " .. arg) - - -- print menu - option.print_menu(xmake._OPTIONS._ACTION) - - -- failed - return false - end - - end - end - - -- init the default value - for _, o in ipairs(menu[xmake._OPTIONS._ACTION or "main"].options) do - - -- key=value? - if o[3] == "kv" then - - -- the key - local key = o[2] or o[1] - assert(key) - - -- save the default value - xmake._OPTIONS._DEFAULTS[key] = o[4] - -- value with name? - elseif o[3] == "v" and o[2] then - -- save the default value - xmake._OPTIONS._DEFAULTS[o[2]] = o[4] - end - end - - -- ok - return true -end - --- find the value of a given name from the arguments --- only for kv mode and need not check it using menu --- -function option.find(argv, name, shortname) - - -- check - assert(argv and (name or shortname)) - - -- find it - local nextvalue = false - for _, arg in ipairs(argv) do - - -- get this value - if nextvalue then return arg end - - -- --name=value? - if name and arg:startswith("--" .. name) then - - -- get value - local i = arg:find("=", 1, true) - if i then return arg:sub(i + 1) end - - -- -shortname value? - elseif shortname and arg:startswith("-" .. shortname) then - - -- get value - nextvalue = true - end - - end -end - --- get all default options from the given action -function option.defaults(action) - - -- make defaults - local defaults = {} - - -- init the default value - for _, o in ipairs(option._MENU[action or "main"].options) do - - -- key=value? - if o[3] == "kv" then - - -- the key - local key = o[2] or o[1] - assert(key) - - -- save the default value - defaults[key] = o[4] - -- value with name? - elseif o[3] == "v" and o[2] then - -- save the default value - defaults[o[2]] = o[4] - end - end - - -- ok? - return defaults -end - --- print the menu -function option.print_menu(action) - - -- no action? print main menu - if not action then - option.print_main() - return - end - - -- the menu - local menu = option._MENU - assert(menu) - - -- the action - action = menu[action] - assert(action) - - -- print title - if menu.title then - print(menu.title) - end - - -- print copyright - if menu.copyright then - print(menu.copyright) - end - - -- print usage - if action.usage then - print("") - print("Usage: " .. action.usage) - end - - -- print description - if action.description then - print("") - print(action.description) - end - - -- print options - if action.options then - option.print_options(action.options) - end -end - --- print the main menu -function option.print_main() - - -- the menu - local menu = option._MENU - assert(menu) - - -- the main menu - local main = menu.main - assert(main) - - -- print title - if menu.title then - print(menu.title) - end - - -- print copyright - if menu.copyright then - print(menu.copyright) - end - - -- print usage - if main.usage then - print("") - print("Usage: " .. main.usage) - end - - -- print description - if main.description then - print("") - print(main.description) - end - - -- print actions - if main.actions then - - -- print header - print("") - print("Actions: ") - - -- the padding spaces - local padding = 42 - - -- print actions - for _, action in ipairs(main.actions) do - - -- the action menu - local action_menu = menu[action] - - -- init the action info - local action_info = " " - if action_menu and action_menu.shortname then - action_info = action_info .. action_menu.shortname .. ", " - else - action_info = action_info .. " " - end - - -- append the action - action_info = action_info .. action - - if action_menu then - -- append spaces - for i = (#action_info), padding do - action_info = action_info .. " " - end - - -- append the action description - if action_menu.description then - action_info = action_info .. action_menu.description - end - end - - -- print action info - print(action_info) - end - end - - -- print options - if main.options then - option.print_options(main.options) - end -end - --- print the options menu -function option.print_options(options) - - -- check - assert(options) - - -- print header - print("") - print("Options: ") - - -- the padding spaces - local padding = 42 - - -- print options - for _, option in ipairs(options) do - - -- init the option info - local option_info = "" - - -- append the shortname - local shortname = option[1]; - local name = option[2]; - local mode = option[3]; - if shortname then - option_info = option_info .. " -" .. shortname - if mode == "kv" then - option_info = option_info .. " " .. utils.ifelse(name, name:upper(), "XXX") - end - end - - -- append the name - if name then - if mode == "v" then - option_info = option_info .. " " .. name - else - option_info = option_info .. utils.ifelse(shortname, ", --", " --") .. name - end - if mode == "kv" then - option_info = option_info .. "=" .. name:upper() - end - elseif mode == "v" then - option_info = option_info .. " ..." - end - - -- append spaces - for i = (#option_info), padding do - option_info = option_info .. " " - end - - -- append the option description - local description = option[5] - if description then - option_info = option_info .. description - end - - -- append the default value - local default = option[4] - if default then - option_info = option_info .. " (default: " .. tostring(default) .. ")" - end - - -- print option info - print(option_info) - - -- print more description if exists - for i = 6, 64 do - - -- the description, @note some option may be nil - local description = option[i] - if not description then break end - - -- is function? get results - if type(description) == "function" then - description = description() - end - - -- the description is string? - if type(description) == "string" then - - -- make spaces - local spaces = "" - for i = 0, padding do - spaces = spaces .. " " - end - - -- print this description - print(spaces .. description) - - -- the description is table? - elseif type(description) == "table" then - - -- print all descriptions - for _, v in pairs(description) do - - -- make spaces - local spaces = "" - for i = 0, padding do - spaces = spaces .. " " - end - - -- print this description - print(spaces .. v) - end - end - end - end -end - --- return module: option -return option diff --git a/xmake/scripts/base/os.lua b/xmake/scripts/base/os.lua deleted file mode 100644 index b08ac3820..000000000 --- a/xmake/scripts/base/os.lua +++ /dev/null @@ -1,237 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file os.lua --- - --- define module: os -local os = os or {} - --- load modules -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") - --- match files or directories --- --- @param pattern the search pattern --- uses "*" to match any part of a file or directory name, --- uses "**" to recurse into subdirectories. --- --- @param findir true: find directory, false: find file --- @return the result array and count --- --- @code --- local dirs, count = os.match("./src/*", true) --- local files, count = os.match("./src/**.c") --- local file = os.match("./src/test.c") --- @endcode --- -function os.match(pattern, findir) - - -- get the excludes - local excludes = pattern:match("|.*$") - if excludes then excludes = excludes:split("|") end - - -- translate excludes - if excludes then - local _excludes = {} - for _, exclude in ipairs(excludes) do - exclude = path.translate(exclude) - exclude = exclude:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") - exclude = exclude:gsub("%*%*", "\001") - exclude = exclude:gsub("%*", "\002") - exclude = exclude:gsub("\001", ".*") - exclude = exclude:gsub("\002", "[^/]*") - table.insert(_excludes, exclude) - end - excludes = _excludes - end - - -- translate path and remove some repeat separators - pattern = path.translate(pattern:gsub("|.*$", "")) - - -- get the root directory - local rootdir = pattern - local starpos = pattern:find("%*") - if starpos then - rootdir = rootdir:sub(1, starpos - 1) - end - rootdir = path.directory(rootdir) - - -- is recurse? - local recurse = pattern:find("**", nil, true) - - -- convert pattern to a lua pattern - pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") - pattern = pattern:gsub("%*%*", "\001") - pattern = pattern:gsub("%*", "\002") - pattern = pattern:gsub("\001", ".*") - pattern = pattern:gsub("\002", "[^/]*") - - -- patch "./" for matching ok if root directory is '.' - if rootdir == '.' then - pattern = "./" .. pattern - end - - -- find it - return os.find(rootdir, pattern, recurse, findir, excludes) -end - --- copy file or directory -function os.cp(src, dst) - - -- check - assert(src and dst) - - -- is file? - if os.isfile(src) then - - -- the destination is directory? append the filename - if os.isdir(dst) then - dst = string.format("%s/%s", dst, path.filename(src)) - end - - -- copy file - if not os.cpfile(src, dst) then - return false, string.format("cannot copy file %s to %s %s", src, dst, os.strerror()) - end - -- is directory? - elseif os.isdir(src) then - -- copy directory - if not os.cpdir(src, dst) then - return false, string.format("cannot copy directory %s to %s %s", src, dst, os.strerror()) - end - -- cp dir/*? - elseif src:find("%*") then - - -- get the root directory - local starpos = src:find("%*") - - -- match all files - local files = os.match((src:gsub("%*+", "**"))) - if files then - for _, file in ipairs(files) do - local dstfile = string.format("%s/%s", dst, file:sub(starpos)) - if not os.cpfile(file, dstfile) then - return false, string.format("cannot copy file %s to %s %s", file, dstfile, os.strerror()) - end - end - end - - -- not exists? - else - return false, string.format("cannot copy file %s, not found this file %s", src, os.strerror()) - end - - -- ok - return true -end - --- move file or directory -function os.mv(src, dst) - - -- check - assert(src and dst) - - -- exists file or directory? - if os.exists(src) then - -- move file or directory - if not os.rename(src, dst) then - return false, string.format("cannot move %s to %s %s", src, dst, os.strerror()) - end - -- not exists? - else - return false, string.format("cannot move %s to %s, not found this file %s", src, dst, os.strerror()) - end - - -- ok - return true -end - --- remove file or directory -function os.rm(file_or_dir, emptydir) - - -- check - assert(file_or_dir) - - -- is file? - if os.isfile(file_or_dir) then - -- remove file - if not os.rmfile(file_or_dir) then - return false, string.format("cannot remove file %s %s", file_or_dir, os.strerror()) - end - -- is directory? - elseif os.isdir(file_or_dir) then - -- remove directory - if not os.rmdir(file_or_dir, emptydir) then - return false, string.format("cannot remove directory %s %s", file_or_dir, os.strerror()) - end - -- not exists? - else - return false, string.format("cannot remove file %s, not found this file %s", file_or_dir, os.strerror()) - end - - -- ok - return true -end - --- change to directory -function os.cd(dir) - - -- check - assert(dir) - - -- change to the previous directory? - if dir == "-" then - -- exists the previous directory? - if os._PREDIR then - dir = os._PREDIR - os._PREDIR = nil - else - -- error - return false, string.format("not found the previous directory %s", os.strerror()) - end - end - - -- is directory? - if os.isdir(dir) then - - -- get the current directory - local current = os.curdir() - - -- change to directory - if not os.chdir(dir) then - return false, string.format("cannot change directory %s %s", dir, os.strerror()) - end - - -- save the previous directory - os._PREDIR = current - - -- not exists? - else - return false, string.format("cannot change directory %s, not found this directory %s", dir, os.strerror()) - end - - -- ok - return true -end - --- return module: os -return os diff --git a/xmake/scripts/base/package.lua b/xmake/scripts/base/package.lua deleted file mode 100644 index ffb1a0d38..000000000 --- a/xmake/scripts/base/package.lua +++ /dev/null @@ -1,314 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file package.lua --- - --- define module: package -local package = package or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- package target for the library file -function package._done_library(target) - - -- check - assert(target and target.name and target.archs) - - -- the output directory - local outputdir = target.outputdir - assert(outputdir) - - -- the plat and mode - local plat = config.get("plat") - local mode = config.get("mode") - assert(plat and mode) - - -- package it - for arch, info in pairs(target.archs) do - - -- check - assert(info.targetdir and info.targetfile) - - -- copy the library file to the output directory - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s.pkg/lib/%s/%s/%s/%s", outputdir, target.name, mode, plat, arch, path.filename(info.targetfile))) - if not ok then - utils.error(errors) - return -1 - end - - -- copy the config.h to the output directory - if info.config_h then - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s.pkg/inc/%s/%s", outputdir, target.name, plat, path.filename(info.config_h))) - if not ok then - utils.error(errors) - return -1 - end - end - end - - -- copy headers - if target.headers then - local srcheaders, dstheaders = rule.headerfiles(target, string.format("%s/%s.pkg/inc", outputdir, target.name)) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - local ok, errors = os.cp(srcheader, dstheader) - if not ok then - utils.error(errors) - return -1 - end - end - i = i + 1 - end - end - end - - -- make xmake.lua - local file = io.open(string.format("%s/%s.pkg/xmake.lua", outputdir, target.name), "w") - if file then - - -- the xmake.lua template content - local template = [[ --- add [targetname] package -add_option("[targetname]") - - -- show menu - set_option_showmenu(true) - - -- set category - set_option_category("package") - - -- set description - set_option_description("The [targetname] package") - - -- set language: c99, c++11 - set_option_languages("c99", "cxx11") - - -- add defines to config.h if checking ok - add_option_defines_h_if_ok("$(prefix)_PACKAGE_HAVE_[TARGETNAME]") - - -- add links for checking - add_option_links("[targetname]") - - -- add link directories - add_option_linkdirs("lib/$(mode)/$(plat)/$(arch)") - - -- add c includes for checking - add_option_cincludes("[targetname]/[targetname].h") - - -- add include directories - add_option_includedirs("inc/$(plat)", "inc") -]] - - -- save file - file:write((template:gsub("%[targetname%]", target.name):gsub("%[TARGETNAME%]", target.name:upper()))) - - -- exit file - file:close() - end - - -- ok - return 1 -end - --- package target for the binary file -function package._done_binary(target) - - -- check - assert(target and target.archs) - - -- the output directory - local outputdir = target.outputdir - assert(outputdir) - - -- the count of architectures - local count = 0 - for _, _ in pairs(target.archs) do count = count + 1 end - - -- package it - local ok = nil - local errors = nil - for arch, info in pairs(target.archs) do - - -- check - assert(info.targetdir and info.targetfile) - - -- copy the binary file to the output directory - if count == 1 then - ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", outputdir, path.filename(info.targetfile))) - else - ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", outputdir, rule.filename(path.basename(info.targetfile) .. "_" .. arch, "binary"))) - end - - -- ok? - if not ok then - utils.error(errors) - return -1 - end - end - - -- ok - return 1 -end - --- package target from the default script -function package._done_from_default(target) - - -- check - assert(target.kind) - - -- the package scripts - local packagescripts = - { - static = package._done_library - , shared = package._done_library - , binary = package._done_binary - } - - -- package it - local packagescript = packagescripts[target.kind] - if packagescript then return packagescript(target) end - - -- continue - return 0 -end - --- package target from the project script -function package._done_from_project(target) - - -- check - assert(target) - - -- package it using the project script first - local packagescript = target.packagescript - if type(packagescript) == "function" then - - -- remove it - target.packagescript = nil - - -- package it - return packagescript(target) - end - - -- continue - return 0 -end - --- package target from the platform script -function package._done_from_platform(target) - - -- check - assert(target) - - -- the platform package script file - local packagescript = nil - local scriptfile = platform.directory() .. "/package.lua" - if os.isfile(scriptfile) then - - -- load the package script - local script, errors = loadfile(scriptfile) - if script then - packagescript = script() - if type(packagescript) == "table" and packagescript.main then - packagescript = packagescript.main - end - else - utils.error(errors) - end - end - - -- package it - if type(packagescript) == "function" then - return packagescript(target) - end - - -- continue - return 0 -end - --- get the configure file -function package._file() - - -- get it - return config.directory() .. "/package.conf" -end - --- package target from the given target configure -function package._done(target) - - -- check - assert(target) - - -- package it from the project script - local ok = package._done_from_project(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- package it from the platform script - local ok = package._done_from_platform(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- package it from the default script - local ok = package._done_from_default(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- ok - return true -end - --- done package from the configure -function package.done(configs) - - -- check - assert(configs) - - -- package targets - for _, target in pairs(configs) do - - -- package it - if not package._done(target) then - -- errors - utils.error("package %s failed!", target.name) - return false - end - - end - - -- save to the configure file - return io.save(package._file(), configs) -end - --- load the package configure -function package.load() - - -- load it - return io.load(package._file()) -end - --- return module: package -return package diff --git a/xmake/scripts/base/path.lua b/xmake/scripts/base/path.lua deleted file mode 100644 index eb35283b2..000000000 --- a/xmake/scripts/base/path.lua +++ /dev/null @@ -1,72 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file path.lua --- - --- define module: path -local path = path or {} - --- load modules -local string = require("base/string") - --- get the directory of the path -function path.directory(p) - local i = p:find_last("[/\\]") - if i then - if i > 1 then i = i - 1 end - return p:sub(1, i) - else - return "." - end -end - --- get the filename of the path -function path.filename(p) - local i = p:find_last("[/\\]") - if i then - return p:sub(i + 1) - else - return p - end -end - --- get the basename of the path -function path.basename(p) - local name = path.filename(p) - local i = name:find_last(".", true) - if i then - return name:sub(1, i - 1) - else - return name - end -end - --- get the file extension of the path: .xxx -function path.extension(p) - local i = p:find_last(".", true) - if i then - return p:sub(i) - else - return "" - end -end - --- return module: path -return path diff --git a/xmake/scripts/base/project.lua b/xmake/scripts/base/project.lua deleted file mode 100644 index abc7897d4..000000000 --- a/xmake/scripts/base/project.lua +++ /dev/null @@ -1,1469 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file project.lua --- - --- define module: project -local project = project or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local table = require("base/table") -local config = require("base/config") -local linker = require("base/linker") -local compiler = require("base/compiler") -local platform = require("platform/platform") - --- import module -function project._api_import(env, module) - - -- import - return require("module/" .. module) -end - --- the current os is belong to the given os? -function project._api_os(env, ...) - - -- get the current os - local os = platform.os() - if not os then return false end - - -- exists this os? - for _, o in ipairs(table.join(...)) do - if o and type(o) == "string" and o == os then - return true - end - end -end - --- the current mode is belong to the given modes? -function project._api_modes(env, ...) - - -- get the current mode - local mode = config.get("mode") - if not mode then return false end - - -- exists this mode? - for _, m in ipairs(table.join(...)) do - if m and type(m) == "string" and m == mode then - return true - end - end -end - --- the current platform is belong to the given platforms? -function project._api_plats(env, ...) - - -- get the current platform - local plat = config.get("plat") - if not plat then return false end - - -- exists this platform? and escape '-' - for _, p in ipairs(table.join(...)) do - if p and type(p) == "string" and plat:find(p:gsub("%-", "%%-")) then - return true - end - end -end - --- the current platform is belong to the given architectures? -function project._api_archs(env, ...) - - -- get the current architecture - local arch = config.get("arch") - if not arch then return false end - - -- exists this architecture? and escape '-' - for _, a in ipairs(table.join(...)) do - if a and type(a) == "string" and arch:find(a:gsub("%-", "%%-")) then - return true - end - end -end - --- the current kind is belong to the given kinds? -function project._api_kind(env, ...) - - -- get the current kind - local kind = config.get("kind") - if not kind then return false end - - -- exists this kind? - for _, k in ipairs(table.join(...)) do - if k and type(k) == "string" and k == kind then - return true - end - end -end - --- enable options? -function project._api_options(env, ...) - - -- some options are enabled? - for _, o in ipairs(table.join(...)) do - if o and type(o) == "string" and config.get(o) then - return true - end - end -end - --- get all pathes and translate it -function project._api_get_pathes(...) - - -- check - assert(project._CURDIR) - - -- get all pathes - local pathes = table.join(...) - - -- translate the relative path - local results = {} - for _, p in ipairs(pathes) do - if not p:find("^%s-%$%(.-%)") and not path.is_absolute(p) then - table.insert(results, path.relative(path.absolute(p, project._CURDIR), project._PROJECT_DIR)) - else - table.insert(results, p) - end - end - - -- ok? - return results -end - --- add c function -function project._api_add_cfunc(env, module, alias, links, includes, cfunc) - - -- check - assert(env and cfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cfunc) - else - name = string.format("__%s", cfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), utils.ifelse(alias, alias, cfunc:upper())) - else - define = string.format("$(prefix)_HAVE_%s", utils.ifelse(alias, alias, cfunc:upper())) - end - - -- make option - env.add_option(name) - env.set_option_category("cfuncs") - env.add_option_cfuncs(cfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) -end - --- add c functions -function project._api_add_cfuncs(env, module, links, includes, ...) - - -- check - assert(env) - - -- done - for _, cfunc in ipairs({...}) do - - -- check - assert(cfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cfunc) - else - name = string.format("__%s", cfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), cfunc:upper()) - else - define = string.format("$(prefix)_HAVE_%s", cfunc:upper()) - end - - -- make option - env.add_option(name) - env.set_option_category("cfuncs") - env.add_option_cfuncs(cfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) - end -end - --- add c++ function -function project._api_add_cxxfunc(env, module, alias, links, includes, cxxfunc) - - -- check - assert(env and cxxfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cxxfunc) - else - name = string.format("__%s", cxxfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), utils.ifelse(alias, alias, cxxfunc:upper())) - else - define = string.format("$(prefix)_HAVE_%s", utils.ifelse(alias, alias, cxxfunc:upper())) - end - - -- make option - env.add_option(name) - env.set_option_category("cxxfuncs") - env.add_option_cxxfuncs(cxxfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cxxincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) -end - --- add c++ functions -function project._api_add_cxxfuncs(env, module, links, includes, ...) - - -- check - assert(env and module) - - -- done - for _, cxxfunc in ipairs({...}) do - - -- check - assert(cxxfunc) - - -- make the option name - local name = nil - if module ~= nil then - name = string.format("__%s_%s", module, cxxfunc) - else - name = string.format("__%s", cxxfunc) - end - - -- make the option define - local define = nil - if module ~= nil then - define = string.format("$(prefix)_%s_HAVE_%s", module:upper(), cxxfunc:upper()) - else - define = string.format("$(prefix)_HAVE_%s", cxxfunc:upper()) - end - - -- make option - env.add_option(name) - env.set_option_category("cxxfuncs") - env.add_option_cxxfuncs(cxxfunc) - if links then env.add_option_links(links) end - if includes then env.add_option_cxxincludes(includes) end - env.add_option_defines_h_if_ok(define) - - -- add this option - env.add_options(name) - end -end - --- add target -function project._api_add_target(env, name) - - -- check - assert(env and name) - - -- the targets - local targets = env._CONFIGS._TARGETS - assert(targets) - - -- init the target scope - targets[name] = targets[name] or {} - - -- switch to this target scope - env._TARGET = targets[name] -end - --- add option -function project._api_add_option(env, name) - - -- check - assert(env and name) - - -- the options - local options = env._CONFIGS._OPTIONS - assert(options) - - -- init the option scope - options[name] = options[name] or {} - - -- switch to this option scope - env._OPTION = options[name] -end - --- load all subprojects from the given directories -function project._api_add_subdirs(env, ...) - - -- check - assert(env) - - -- init mtime for files - project._MTIMES = project._MTIMES or {} - - -- save the current project file directory - local curdir = project._CURDIR - - -- get all subdirs - local subdirs = project._api_get_pathes(...) - - -- match all subdirs - local subdirs_matched = {} - for _, subdir in ipairs(subdirs) do - local dirs = os.match(subdir, true) - if dirs then table.join2(subdirs_matched, dirs) end - end - - -- done - for _, subdir in ipairs(subdirs_matched) do - if subdir and type(subdir) == "string" then - - -- the project file - local file = subdir .. "/xmake.lua" - if not path.is_absolute(file) then - file = path.absolute(file, xmake._PROJECT_DIR) - end - - -- update the current project file directory - project._CURDIR = path.directory(file) - - -- load the project script - local script = loadfile(file) - if script then - - -- bind environment - setfenv(script, env) - - -- done the project script - local ok, errors = pcall(script) - if not ok then - utils.error(errors) - assert(false) - end - - -- get mtime of the file - project._MTIMES[path.relative(file, xmake._PROJECT_DIR)] = os.mtime(file) - end - end - end - - -- restore the current project file directory - project._CURDIR = curdir - -end - --- load all subprojects from the given files -function project._api_add_subfiles(env, ...) - - -- check - assert(env) - - -- init mtime for files - project._MTIMES = project._MTIMES or {} - - -- save the current project file directory - local curdir = project._CURDIR - - -- get all subfiles - local subfiles = project._api_get_pathes(...) - - -- match all subfiles - local subfiles_matched = {} - for _, subfile in ipairs(subfiles) do - local files = os.match(subfile) - if files then table.join2(subfiles_matched, files) end - end - - -- done - for _, file in ipairs(subfiles_matched) do - if file and type(file) == "string" then - - -- the project file - if not path.is_absolute(file) then - file = path.absolute(file, xmake._PROJECT_DIR) - end - - -- update the current project file directory - project._CURDIR = path.directory(file) - - -- load the project script - local script = loadfile(file) - if script then - - -- bind environment - setfenv(script, env) - - -- done the project script - local ok, errors = pcall(script) - if not ok then - utils.error(errors) - assert(false) - end - - -- get mtime of the file - project._MTIMES[path.relative(file, xmake._PROJECT_DIR)] = os.mtime(file) - end - end - end - - -- restore the current project file directory - project._CURDIR = curdir -end - --- load all packages from the given directories -function project._api_add_pkgdirs(env, ...) - - -- get all directories - local pkgdirs = {} - local dirs = table.join(...) - for _, dir in ipairs(dirs) do - table.insert(pkgdirs, dir .. "/*.pkg") - end - - -- add all packages - project._api_add_subdirs(env, pkgdirs) -end - --- set configure values -function project._api_set_values(scope, name, ...) - - -- check - assert(scope and name) - - -- update values - scope[name] = {} - table.join2(scope[name], ...) -end - --- add configure values -function project._api_add_values(scope, name, ...) - - -- check - assert(scope and name) - - -- append values - scope[name] = scope[name] or {} - table.join2(scope[name], ...) -end - --- set configure pathes -function project._api_set_pathes(scope, name, ...) - - -- check - assert(scope and name) - - -- update pathes - scope[name] = {} - table.join2(scope[name], project._api_get_pathes(...)) -end - --- add configure pathes -function project._api_add_pathes(scope, name, ...) - - -- check - assert(scope and name) - - -- append pathes - scope[name] = scope[name] or {} - table.join2(scope[name], project._api_get_pathes(...)) -end - --- filter the configure value -function project._filter(values) - - -- check - assert(values) - - -- filter all - local newvals = {} - for _, v in ipairs(utils.wrap(values)) do - if type(v) == "string" then - v = v:gsub("%$%((.-)%)", function (w) - - -- is upper? - local isupper = false - local c = string.char(w:byte()) - if c >= 'A' and c <= 'Z' then isupper = true end - - -- attempt to get it directly from the configure - local r = config.get(w) - if not r or type(r) ~= "string" then - - -- attempt to get it from the configure and the lower key - w = w:lower() - r = config.get(w) - if not r or type(r) ~= "string" then - - -- get the other keys - if w == "projectdir" then r = xmake._PROJECT_DIR - elseif w == "os" then r = platform.os() - end - end - end - - -- upper? - if r and type(r) == "string" and isupper then - r = r:upper() - end - - -- ok? - return r - end) - end - table.insert(newvals, v) - end - - -- ok? - return newvals -end - --- make configure for the given target_name -function project._makeconf_for_target(target_name, target) - - -- check - assert(target_name and target) - - -- get the target configure file - local config_h = target.config_h - if not config_h then - return true - end - - -- translate file path - if not path.is_absolute(config_h) then - config_h = path.absolute(config_h, xmake._PROJECT_DIR) - else - config_h = path.translate(config_h) - end - - -- the prefix - local prefix = target.config_h_prefix or (target_name:upper() .. "_CONFIG") - - -- open the file - local file = project._CONFILES[config_h] or io.openmk(config_h) - assert(file) - - -- make the head - if project._CONFILES[config_h] then file:write("\n") end - file:write(string.format("#ifndef %s_H\n", prefix)) - file:write(string.format("#define %s_H\n", prefix)) - file:write("\n") - - -- make version - if target.version then - file:write("// version\n") - file:write(string.format("#define %s_VERSION \"%s\"\n", prefix, target.version)) - local i = 1 - local m = {"MAJOR", "MINOR", "ALTER"} - for v in target.version:gmatch("%d+") do - file:write(string.format("#define %s_VERSION_%s %s\n", prefix, m[i], v)) - i = i + 1 - if i > 3 then break end - end - file:write(string.format("#define %s_VERSION_BUILD %s\n", prefix, os.date("%Y%m%d%H%M", os.time()))) - file:write("\n") - end - - -- make the defines - local defines = {} - if target.defines_h then table.join2(defines, target.defines_h) end - - -- make the undefines - local undefines = {} - if target.undefines_h then table.join2(undefines, target.undefines_h) end - - -- the options - if target.options then - for _, name in ipairs(utils.wrap(target.options)) do - - -- get option if be enabled - local opt = nil - if config.get(name) then opt = config.get("__" .. name) end - if nil ~= opt then - - -- get the option defines - if opt.defines_h_if_ok then table.join2(defines, opt.defines_h_if_ok) end - - -- get the option undefines - if opt.undefines_h_if_ok then table.join2(undefines, opt.undefines_h_if_ok) end - - end - end - end - - -- make the defines - if #defines ~= 0 then - file:write("// defines\n") - for _, define in ipairs(defines) do - file:write(string.format("#define %s 1\n", define:gsub("=", " "):gsub("%$%((.-)%)", function (w) if w == "prefix" then return prefix end end))) - end - file:write("\n") - end - - -- make the undefines - if #undefines ~= 0 then - file:write("// undefines\n") - for _, undefine in ipairs(undefines) do - file:write(string.format("#undef %s\n", undefine:gsub("%$%((.-)%)", function (w) if w == "prefix" then return prefix end end))) - end - file:write("\n") - end - - -- make the tail - file:write("#endif\n") - - -- cache the file - project._CONFILES[config_h] = file - - -- ok - return true -end - --- make the configure file for the given target and dependents -function project._makeconf_for_target_and_deps(target_name) - - -- the targets - local targets = project.targets() - assert(targets) - - -- the target - local target = targets[target_name] - assert(target) - - -- make configure for the target - if not project._makeconf_for_target(target_name, target) then - return false - end - - -- exists the dependent targets? - if target.deps then - local deps = utils.wrap(target.deps) - for _, dep in ipairs(deps) do - if not project._makeconf_for_target_and_deps(dep) then return false end - end - end - - -- ok - return true -end - --- make targets from the project file -function project._make_targets(configs) - - -- check - assert(configs and configs._TARGETS) - - -- init - project._TARGETS = project._TARGETS or {} - local targets = project._TARGETS - - -- make all targets - for k, v in pairs(configs._TARGETS) do - targets[k] = v - end - - -- merge the root configures to all targets - for _, target in pairs(targets) do - - -- merge the setted configures - for k, v in pairs(configs._SET) do - if nil == target[k] then - target[k] = v - end - end - - -- merge the added configures - for k, v in pairs(configs._ADD) do - if nil == target[k] then - target[k] = v - else - target[k] = table.join(v, target[k]) - end - end - - -- remove repeat values and unwrap it - for k, v in pairs(target) do - - -- remove repeat first - v = utils.unique(v) - - -- filter values - v = project._filter(v) - - -- unwrap it if be only one - v = utils.unwrap(v) - - -- update it - target[k] = v - end - end - - -- init mtime for the project file - project._MTIMES = project._MTIMES or {} - project._MTIMES[path.relative(xmake._PROJECT_FILE, xmake._PROJECT_DIR)] = os.mtime(xmake._PROJECT_FILE) - - -- get the mtimes for configure - local mtimes_config = config.get("__mtimes") - if mtimes_config then - - -- check for all project files and we need reconfig and rebuild it if them have been modified - for file, mtime in pairs(project._MTIMES) do - - -- modified? reconfig and rebuild it - local mtime_old = mtimes_config[file] - if not mtime_old or mtime > mtime_old then - config._RECONFIG = true - config.set("__rebuild", true) - break - end - end - end - - -- update mtimes - config.set("__mtimes", project._MTIMES) - - -- reconfig it? we need reprobe it - if config._RECONFIG then - project.probe() - config.clearup() - end -end - --- make option for checking links -function project._make_option_for_checking_links(opt, links, cfile, objectfile, targetfile) - - -- the links string - local links_str = table.concat(utils.wrap(links), ", ") - - -- this links has been checked? - project._CHECKED_LINKS = project._CHECKED_LINKS or {} - if project._CHECKED_LINKS[links_str] then return true end - - -- only for compile a object file - local ok = compiler.check_include(opt, nil, cfile, objectfile) - - -- check link - if ok then ok = linker.check_links(opt, links, cfile, objectfile, targetfile) end - - -- trace - utils.printf("checking for the links %s ... %s", links_str, utils.ifelse(ok, "ok", "no")) - - -- cache the result - project._CHECKED_LINKS[links_str] = ok - - -- ok? - return ok -end - --- make option for checking cincludes -function project._make_option_for_checking_cincludes(opt, cincludes, cfile, objectfile) - - -- done - for _, cinclude in ipairs(utils.wrap(cincludes)) do - - -- this cinclude has been checked? - project._CHECKED_CINCLUDES = project._CHECKED_CINCLUDES or {} - if project._CHECKED_CINCLUDES[cinclude] then return true end - - -- check cinclude - local ok = compiler.check_include(opt, cinclude, cfile, objectfile) - - -- trace - utils.printf("checking for the c include %s ... %s", cinclude, utils.ifelse(ok, "ok", "no")) - - -- cache the result - project._CHECKED_CINCLUDES[cinclude] = ok - - -- failed - if not ok then return false end - end - - -- ok - return true -end - --- make option for checking cxxincludes -function project._make_option_for_checking_cxxincludes(opt, cxxincludes, cxxfile, objectfile) - - -- done - for _, cxxinclude in ipairs(utils.wrap(cxxincludes)) do - - -- this cxxinclude has been checked? - project._CHECKED_CXXINCLUDES = project._CHECKED_CXXINCLUDES or {} - if project._CHECKED_CXXINCLUDES[cinclude] then return true end - - -- check cinclude - local ok = compiler.check_include(opt, cxxinclude, cxxfile, objectfile) - - -- trace - utils.printf("checking for the c++ include %s ... %s", cxxinclude, utils.ifelse(ok, "ok", "no")) - - -- cache the result - project._CHECKED_CXXINCLUDES[cxxinclude] = ok - - -- failed - if not ok then return false end - end - - -- ok - return true -end - --- make option for checking cfunctions -function project._make_option_for_checking_cfuncs(opt, cfuncs, cfile, objectfile, targetfile) - - -- done - for _, cfunc in ipairs(utils.wrap(cfuncs)) do - - -- check function - local ok = compiler.check_function(opt, cfunc, cfile, objectfile) - - -- check link - if ok and opt.links then ok = linker.check_links(opt, opt.links, cfile, objectfile, targetfile) end - - -- trace - utils.printf("checking for the c function %s ... %s", cfunc, utils.ifelse(ok, "ok", "no")) - - -- failed - if not ok then return false end - end - - -- ok - return true -end - --- make option for checking cxxfunctions -function project._make_option_for_checking_cxxfuncs(opt, cxxfuncs, cxxfile, objectfile, targetfile) - - -- done - for _, cxxfunc in ipairs(utils.wrap(cxxfuncs)) do - - -- check function - local ok = compiler.check_function(opt, cxxfunc, cxxfile, objectfile) - - -- check link - if ok and opt.links then ok = linker.check_links(opt, opt.links, cxxfile, objectfile, targetfile) end - - -- trace - utils.printf("checking for the c++ function %s ... %s", cxxfunc, utils.ifelse(ok, "ok", "no")) - - -- failed - if not ok then return false end - end - - -- ok - return true -end - --- make option for checking ctypes -function project._make_option_for_checking_ctypes(opt, ctypes, cfile, objectfile, targetfile) - - -- done - for _, ctype in ipairs(utils.wrap(ctypes)) do - - -- check type - local ok = compiler.check_typedef(opt, ctype, cfile, objectfile) - - -- trace - utils.printf("checking for the c type %s ... %s", ctype, utils.ifelse(ok, "ok", "no")) - - -- failed - if not ok then return false end - end - - -- ok - return true -end - --- make option for checking cxxtypes -function project._make_option_for_checking_cxxtypes(opt, cxxtypes, cxxfile, objectfile, targetfile) - - -- done - for _, cxxtype in ipairs(utils.wrap(cxxtypes)) do - - -- check type - local ok = compiler.check_typedef(opt, cxxtype, cxxfile, objectfile) - - -- trace - utils.printf("checking for the c++ type %s ... %s", cxxtype, utils.ifelse(ok, "ok", "no")) - - -- failed - if not ok then return false end - end - - -- ok - return true -end - --- make option -function project._make_option(name, opt, cfile, cxxfile, objectfile, targetfile) - - -- remove repeat values and unwrap it - for k, v in pairs(opt) do - - -- remove repeat first - v = utils.unique(v) - - -- filter values - v = project._filter(v) - - -- unwrap it if be only one - v = utils.unwrap(v) - - -- update it - opt[k] = v - end - - -- check links - if opt.links and not project._make_option_for_checking_links(opt, opt.links, cfile, objectfile, targetfile) then return end - - -- check ctypes - if opt.ctypes and not project._make_option_for_checking_ctypes(opt, opt.ctypes, cfile, objectfile, targetfile) then return end - - -- check cxxtypes - if opt.cxxtypes and not project._make_option_for_checking_cxxtypes(opt, opt.cxxtypes, cxxfile, objectfile, targetfile) then return end - - -- check includes and functions - if opt.cincludes or opt.cxxincludes then - - -- check cincludes - if opt.cincludes and not project._make_option_for_checking_cincludes(opt, opt.cincludes, cfile, objectfile) then return end - - -- check cxxincludes - if opt.cxxincludes and not project._make_option_for_checking_cxxincludes(opt, opt.cxxincludes, cxxfile, objectfile) then return end - - -- check cfuncs - if opt.cfuncs and not project._make_option_for_checking_cfuncs(opt, opt.cfuncs, cfile, objectfile, targetfile) then return end - - -- check cxxfuncs - if opt.cxxfuncs and not project._make_option_for_checking_cxxfuncs(opt, opt.cxxfuncs, cxxfile, objectfile, targetfile) then return end - - end - - -- ok - return opt -end - --- make options from the project file -function project._make_options(configs) - - -- check - assert(configs and configs._OPTIONS) - - -- the source file path - local cfile = os.tmpdir() .. "/__checking.c" - local cxxfile = os.tmpdir() .. "/__checking.cpp" - - -- the object file path - local objectfile = os.tmpdir() .. "/" .. rule.filename("__checking", "object") - - -- the target file path - local targetfile = os.tmpdir() .. "/" .. rule.filename("__checking", "binary") - - -- make all options - for k, v in pairs(configs._OPTIONS) do - - -- this option need be probed automatically? - if config.auto(k) then - - -- make option - local o = project._make_option(k, v, cfile, cxxfile, objectfile, targetfile) - if o then - - -- enable this option - config.set(k, true) - - -- save this option to configure - config.set("__" .. k, o) - - else - - -- disable this option - config.set(k, false) - - -- clear this option to configure - config.set("__" .. k, nil) - - end - - elseif nil == config.get("__" .. k) then - - -- save this option to configure - config.set("__" .. k, v) - end - end - - -- remove files - os.rm(cfile) - os.rm(cxxfile) - os.rm(objectfile) - os.rm(targetfile) - -end - --- only load options from the the project file -function project._load_options(file) - - -- check - assert(file) - - -- load the project script - local script = loadfile(file) - if not script then - return string.format("load %s failed!", file) - end - - -- set the current project file directory - project._CURDIR = path.directory(file) - - -- bind the new environment - local newenv = {_CONFIGS = {_OPTIONS = {}}} - setmetatable(newenv, {__index = function(tbl, key) - local val = rawget(tbl, key) - if nil == val then val = rawget(_G, key) end - if nil == val then return function(...) end end - return val - end}) - setfenv(script, newenv) - - -- register import - newenv.import = function (module) return project._api_import(newenv, module) end - - -- register interfaces for the condition - newenv.os = function (...) return project._api_os(newenv, ...) end - newenv.kind = function (...) return project._api_kind(newenv, ...) end - newenv.modes = function (...) return project._api_modes(newenv, ...) end - newenv.plats = function (...) return project._api_plats(newenv, ...) end - newenv.archs = function (...) return project._api_archs(newenv, ...) end - - -- register interfaces for the option - newenv.set_option = function (...) return project._api_add_option(newenv, ...) end - newenv.add_option = function (...) return project._api_add_option(newenv, ...) end - - -- register interfaces for the subproject files - newenv.add_subdirs = function (...) return project._api_add_subdirs(newenv, ...) end - newenv.add_subfiles = function (...) return project._api_add_subfiles(newenv, ...) end - - -- register interfaces for the functions - newenv.add_cfunc = function (...) return project._api_add_cfunc(newenv, ...) end - newenv.add_cfuncs = function (...) return project._api_add_cfuncs(newenv, ...) end - newenv.add_cxxfunc = function (...) return project._api_add_cxxfunc(newenv, ...) end - newenv.add_cxxfuncs = function (...) return project._api_add_cxxfuncs(newenv, ...) end - - -- register interfaces for the package files - newenv.add_pkgdirs = function (...) return project._api_add_pkgdirs(newenv, ...) end - newenv.add_pkgs = function (...) return project._api_add_subdirs(newenv, ...) end - - -- register interfaces for setting option values - local interfaces = { "enable" - , "showmenu" - , "category" - , "warnings" - , "optimize" - , "languages" - , "description"} - - for _, interface in ipairs(interfaces) do - newenv["set_option_" .. interface] = function (...) return project._api_set_values(newenv._OPTION, interface, ...) end - end - - -- register interfaces for adding option values - interfaces = { "links" - , "cincludes" - , "cxxincludes" - , "cfuncs" - , "cxxfuncs" - , "ctypes" - , "cxxtypes" - , "cflags" - , "cxflags" - , "cxxflags" - , "ldflags" - , "vectorexts" - , "defines" - , "defines_if_ok" - , "defines_h_if_ok" - , "undefines" - , "undefines_if_ok" - , "undefines_h_if_ok"} - - for _, interface in ipairs(interfaces) do - newenv["add_option_" .. interface] = function (...) return project._api_add_values(newenv._OPTION, interface, ...) end - end - - -- register interfaces for adding option pathes - interfaces = { "linkdirs" - , "includedirs"} - - for _, interface in ipairs(interfaces) do - newenv["add_option_" .. interface] = function (...) return project._api_add_pathes(newenv._OPTION, interface, ...) end - end - - -- done the project script - local ok, errors = pcall(script) - if not ok then - return nil, errors - end - - -- get the project configure - return newenv._CONFIGS -end - --- only load targets from the project file -function project._load_targets(file) - - -- check - assert(file) - - -- load the project script - local script = loadfile(file) - if not script then - return string.format("load %s failed!", file) - end - - -- set the current project file directory - project._CURDIR = path.directory(file) - - -- bind the new environment - local newenv = {_CONFIGS = {_SET = {}, _ADD = {}, _TARGETS = {}}} - setmetatable(newenv, {__index = function(tbl, key) - local val = rawget(tbl, key) - if nil == val then val = rawget(_G, key) end - if nil == val and type(key) == "string" and (key:startswith("add_option") or key:startswith("set_option")) then - return function(...) end - end - return val - end}) - setfenv(script, newenv) - - -- register import - newenv.import = function (module) return project._api_import(newenv, module) end - - -- register interfaces for the condition - newenv.os = function (...) return project._api_os(newenv, ...) end - newenv.kind = function (...) return project._api_kind(newenv, ...) end - newenv.modes = function (...) return project._api_modes(newenv, ...) end - newenv.plats = function (...) return project._api_plats(newenv, ...) end - newenv.archs = function (...) return project._api_archs(newenv, ...) end - newenv.options = function (...) return project._api_options(newenv, ...) end - - -- register interfaces for the target - newenv.set_target = function (...) return project._api_add_target(newenv, ...) end - newenv.add_target = function (...) return project._api_add_target(newenv, ...) end - - -- register interfaces for the subproject files - newenv.add_subdirs = function (...) return project._api_add_subdirs(newenv, ...) end - newenv.add_subfiles = function (...) return project._api_add_subfiles(newenv, ...) end - - -- register interfaces for the functions - newenv.add_cfunc = function (...) return project._api_add_cfunc(newenv, ...) end - newenv.add_cfuncs = function (...) return project._api_add_cfuncs(newenv, ...) end - newenv.add_cxxfunc = function (...) return project._api_add_cxxfunc(newenv, ...) end - newenv.add_cxxfuncs = function (...) return project._api_add_cxxfuncs(newenv, ...) end - - -- register interfaces for the package files - newenv.add_pkgdirs = function (...) return project._api_add_pkgdirs(newenv, ...) end - newenv.add_pkgs = function (...) return project._api_add_subdirs(newenv, ...) end - - -- register interfaces for setting values - local interfaces = { "kind" - , "config_h_prefix" - , "version" - , "strip" - , "options" - , "symbols" - , "warnings" - , "optimize" - , "languages" - , "runscript" - , "installscript" - , "packagescript"} - - for _, interface in ipairs(interfaces) do - newenv["set_" .. interface] = function (...) return project._api_set_values(newenv._TARGET or newenv._CONFIGS._SET, interface, ...) end - end - - -- register interfaces for setting pathes - local interfaces = { "headerdir" - , "targetdir" - , "objectdir" - , "config_h"} - - for _, interface in ipairs(interfaces) do - newenv["set_" .. interface] = function (...) return project._api_set_pathes(newenv._TARGET or newenv._CONFIGS._SET, interface, ...) end - end - - -- register interfaces for adding values - interfaces = { "deps" - , "links" - , "cflags" - , "cxflags" - , "cxxflags" - , "mflags" - , "mxflags" - , "mxxflags" - , "ldflags" - , "shflags" - , "options" - , "defines" - , "undefines" - , "defines_h" - , "undefines_h" - , "languages" - , "vectorexts"} - for _, interface in ipairs(interfaces) do - newenv["add_" .. interface] = function (...) return project._api_add_values(newenv._TARGET or newenv._CONFIGS._ADD, interface, ...) end - end - - -- register interfaces for adding pathes - interfaces = { "files" - , "headers" - , "linkdirs" - , "includedirs"} - for _, interface in ipairs(interfaces) do - newenv["add_" .. interface] = function (...) return project._api_add_pathes(newenv._TARGET or newenv._CONFIGS._ADD, interface, ...) end - end - - -- done the project script - local ok, errors = pcall(script) - if not ok then - return nil, errors - end - - -- get the project configure - return newenv._CONFIGS -end - --- get the current configure for targets -function project.targets() - - -- check - assert(project._TARGETS) - - -- return it - return project._TARGETS -end - --- probe the project -function project.probe() - - -- load the options from the the project file - local configs, errors = project._load_options(xmake._PROJECT_FILE) - if not configs then - return errors - end - - -- make the options from the the project file - project._make_options(configs) -end - --- load the project -function project.load() - - -- load the targets from the the project file - local configs, errors = project._load_targets(xmake._PROJECT_FILE) - if not configs then - return errors - end - - -- make the targets from the the project file - project._make_targets(configs) -end - --- reload the project -function project.reload() - - -- clear it first - project._MTIMES = nil - project._TARGETS = nil - project._CONFILES = nil - project._CURDIR = nil - - -- load it - return project.load() -end - --- dump the current configure -function project.dump() - - -- check - assert(project._TARGETS) - - -- dump - if xmake._OPTIONS.verbose then - utils.dump(project._TARGETS) - end - -end - --- make the configure file for the given target -function project.makeconf(target_name) - - -- init files - project._CONFILES = project._CONFILES or {} - - -- the target name - if target_name and target_name ~= "all" then - -- make configure for the target and dependents - if not project._makeconf_for_target_and_deps(target_name) then return false end - else - - -- the targets - local targets = project.targets() - assert(targets) - - -- make configure for the targets - for target_name, target in pairs(targets) do - if not project._makeconf_for_target(target_name, target) then return false end - end - end - - -- exit files - for _, file in pairs(project._CONFILES) do - file:close() - end - project._CONFILES = nil - - -- ok - return true -end - --- check target -function project.checktarget(target_name) - - -- the targets - local targets = project.targets() - - -- invalid target? - if target_name and target_name ~= "all" and targets and not targets[target_name] then - utils.error("invalid target: %s!", target_name) - return false - elseif not target_name then - utils.error("no target!") - return false - end - - -- ok - return true -end - --- get the project menu -function project.menu() - - -- attempt to load project configure - local configs = nil - local errors = nil - local projectfile = xmake._PROJECT_FILE - if projectfile and os.isfile(projectfile) then - configs, errors = project._load_options(projectfile) - end - - -- failed? - if not configs then - if errors then utils.error(errors) end - return {} - end - - -- the options - local options = configs._OPTIONS - if not options then return {} end - - -- arrange options by category - local options_by_category = {} - for name, opt in pairs(options) do - - -- make the category - local category = "default" - if opt.category then category = utils.unwrap(opt.category) end - options_by_category[category] = options_by_category[category] or {} - - -- append option to the current category - options_by_category[category][name] = opt - end - - -- make menu by category - local menu = {} - for k, opts in pairs(options_by_category) do - - -- insert options - local first = true - for name, opt in pairs(opts) do - - -- show menu? - if opt.showmenu then - - -- the default value - local default = "auto" - if opt.enable ~= nil then - default = utils.unwrap(opt.enable) - end - - -- is first? - if first then - - -- insert a separator - table.insert(menu, {}) - - -- not first - first = false - end - - -- append it - if opt.description then - table.insert(menu, {nil, name, "kv", default, utils.unwrap(opt.description)}) - else - table.insert(menu, {nil, name, "kv", default, nil}) - end - end - end - end - - -- ok? - return menu -end - --- return module: project -return project diff --git a/xmake/scripts/base/rule.lua b/xmake/scripts/base/rule.lua deleted file mode 100644 index b3dc1825c..000000000 --- a/xmake/scripts/base/rule.lua +++ /dev/null @@ -1,300 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file rule.lua --- - --- define module: rule -local rule = rule or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local table = require("base/table") -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- get the building log file path -function rule.logfile() - - -- the logdir - local logdir = config.get("buildir") or os.tmpdir() - assert(logdir) - - -- get it - return path.translate(logdir .. "/.build.log") -end - --- get the filename from the given name and kind -function rule.filename(name, kind) - - -- check - assert(name and kind) - - -- get format - local format = platform.format(kind) or {"", ""} - - -- make it - return format[1] .. name .. format[2] -end - --- get the makefile path -function rule.makefile() - - -- get the build directory - local buildir = config.get("buildir") - assert(buildir) - - -- get it - return path.translate(buildir .. "/makefile") -end - --- get configure file for the given target -function rule.config_h(target) - - -- get the target configure file - local config_h = target.config_h - if config_h then - -- translate file path - if not path.is_absolute(config_h) then - config_h = path.absolute(config_h, xmake._PROJECT_DIR) - else - config_h = path.translate(config_h) - end - end - - -- ok? - return config_h -end - --- get the temporary backup directory for package -function rule.backupdir(target_name, arch) - - -- the temporary directory - local tmpdir = os.tmpdir() - assert(tmpdir) - - -- the project name - local project_name = path.basename(xmake._PROJECT_DIR) - assert(project_name) - - -- make it - return string.format("%s/.xmake/%s/pkgfiles/%s/%s", tmpdir, project_name, target_name, arch) -end - --- get target file for the given target -function rule.targetfile(target_name, target, buildir) - - -- check - assert(target_name and target and target.kind) - - -- the target directory - local targetdir = target.targetdir or buildir or config.get("buildir") - assert(targetdir and type(targetdir) == "string") - - -- the target file name - local filename = rule.filename(target_name, target.kind) - assert(filename) - - -- make the target file path - return targetdir .. "/" .. filename -end - --- get object files for the given source files -function rule.objectdir(target_name, target, buildir) - - -- check - assert(target_name and target) - - -- the object directory - local objectdir = target.objectdir - if not objectdir then - - -- the build directory - if not buildir then - buildir = config.get("buildir") - end - assert(buildir) - - -- make the default object directory - objectdir = buildir .. "/.objs" - end - - -- ok? - return objectdir -end - --- get object files for the given source files -function rule.objectfiles(target_name, target, sourcefiles, buildir) - - -- check - assert(target_name and target and sourcefiles) - - -- the object directory - local objectdir = rule.objectdir(target_name, target, buildir) - assert(objectdir and type(objectdir) == "string") - - -- make object files - local i = 1 - local objectfiles = {} - for _, sourcefile in ipairs(sourcefiles) do - - -- translate: [lib]xxx*.[a|lib] => xxx/*.[o|obj] object file - sourcefile = sourcefile:gsub(rule.filename("(%w+)", "static"):gsub("%.", "%%.") .. "$", "%1/*") - - -- make object file - local objectfile = string.format("%s/%s/%s/%s", objectdir, target_name, path.directory(sourcefile), rule.filename(path.basename(sourcefile), "object")) - - -- translate path - -- - -- .e.g - -- - -- src/xxx.c - -- project/xmake.lua - -- build/.objs - -- - -- objectfile: project/build/.objs/xxxx/../../xxx.c will be out of range for objectdir - -- - -- we need replace '..' to '__' in this case - -- - objectfile = (path.translate(objectfile):gsub("%.%.", "__")) - - -- save it - objectfiles[i] = objectfile - i = i + 1 - - end - - -- ok? - return objectfiles -end - --- get the source files from the given target -function rule.sourcefiles(target) - - -- check - assert(target) - - -- no files? - if not target.files then - return {} - end - - -- wrap files first - local targetfiles = utils.wrap(target.files) - - -- match files - local i = 1 - local sourcefiles = {} - for _, targetfile in ipairs(targetfiles) do - - -- normalize *.[o|obj] filename - targetfile = targetfile:gsub("([%w%*]+)%.obj|", rule.filename("%1|", "object")) - targetfile = targetfile:gsub("([%w%*]+)%.obj$", rule.filename("%1", "object")) - targetfile = targetfile:gsub("([%w%*]+)%.o|", rule.filename("%1|", "object")) - targetfile = targetfile:gsub("([%w%*]+)%.o$", rule.filename("%1", "object")) - - -- normalize [lib]*.[a|lib] filename - targetfile = targetfile:gsub("([%w%*]+)%.lib|", rule.filename("%1|", "static")) - targetfile = targetfile:gsub("([%w%*]+)%.lib$", rule.filename("%1", "static")) - targetfile = targetfile:gsub("lib([%w%*]+)%.a|", rule.filename("%1|", "static")) - targetfile = targetfile:gsub("lib([%w%*]+)%.a$", rule.filename("%1", "static")) - - -- match source files - local files = os.match(targetfile) - if #files == 0 then - utils.warning("cannot match add_files(\"%s\")", targetfile) - end - - -- process source files - for _, file in ipairs(files) do - - -- convert to the relative path - if path.is_absolute(file) then - file = path.relative(file, xmake._PROJECT_DIR) - end - - -- save it - sourcefiles[i] = file - i = i + 1 - - end - end - - -- remove repeat files - sourcefiles = utils.unique(sourcefiles) - - -- ok? - return sourcefiles -end - --- get the header files from the given target -function rule.headerfiles(target, headerdir) - - -- check - assert(target) - - -- no headers? - local headers = target.headers - if not headers then return end - - -- get the headerdir - if not headerdir then headerdir = target.headerdir or config.get("buildir") end - assert(headerdir) - - -- get the source pathes and destinate pathes - local srcheaders = {} - local dstheaders = {} - for _, header in ipairs(utils.wrap(headers)) do - - -- get the root directory - local rootdir = header:gsub("%(.*%)", ""):gsub("|.*$", "") - - -- remove '(' and ')' - local srcpathes = header:gsub("[%(%)]", "") - if srcpathes then - - -- get the source pathes - srcpathes = os.match(srcpathes) - if srcpathes then - - -- add the source headers - table.join2(srcheaders, srcpathes) - - -- add the destinate headers - for _, srcpath in ipairs(srcpathes) do - - -- the header - local dstheader = path.absolute(path.relative(srcpath, rootdir), headerdir) - assert(dstheader) - - -- add it - table.insert(dstheaders, dstheader) - end - end - end - end - - -- ok? - return srcheaders, dstheaders -end - --- return module: rule -return rule diff --git a/xmake/scripts/base/string.lua b/xmake/scripts/base/string.lua deleted file mode 100644 index b4be08cfa..000000000 --- a/xmake/scripts/base/string.lua +++ /dev/null @@ -1,115 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file string.lua --- - --- define module: string -local string = string or {} - --- find the last substring with the given pattern -function string.find_last(self, pattern, plain) - - -- find the last substring - local curr = 0 - repeat - local next = self:find(pattern, curr + 1, plain) - if next then - curr = next - end - until (not next) - - -- found? - if curr > 0 then - return curr - end -end - --- split string with the given pattern -function string.split(self, pattern) - - -- split it - local list = {} - self:gsub("[^" .. pattern .."]+", function(v) table.insert(list, v) end ) - return list -end - --- trim the spaces -function string.trim(self) - return (self:gsub("^%s*(.-)%s*$", "%1")) -end - --- trim the left spaces -function string.ltrim(self) - return (self:gsub("^%s*", "")) -end - --- trim the right spaces -function string.rtrim(self) - local n = #self - while n > 0 and s:find("^%s", n) do n = n - 1 end - return self:sub(1, n) -end - --- append a substring with a given separator -function string.append(self, substr, separator) - - -- check - assert(self) - - -- not substr? return self - if not substr then - return self - end - - -- append it - local s = self - if #s == 0 then - s = substr - else - s = string.format("%s%s%s", s, separator or "", substr) - end - - -- ok - return s -end - --- encode: ' ', '=', '\"', '<' -function string.encode(self) - - -- null? - if self == nil then return end - - -- done - return (self:gsub("[%s=\"<]", function (w) return string.format("%%%x", w:byte()) end)) -end - --- decode: ' ', '=', '\"' -function string.decode(self) - - -- null? - if self == nil then return end - - -- done - return (self:gsub("%%(%x%x)", function (w) return string.char(tonumber(w, 16)) end)) -end - - --- return module: string -return string diff --git a/xmake/scripts/base/table.lua b/xmake/scripts/base/table.lua deleted file mode 100644 index 52b726412..000000000 --- a/xmake/scripts/base/table.lua +++ /dev/null @@ -1,99 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file table.lua --- - --- define module: table -local table = table or {} - --- join all objects and tables -function table.join(...) - - -- done - local args = {...} - local result = {} - for _, t in ipairs(args) do - if type(t) == "table" then - for k, v in pairs(t) do - if type(k) == "number" then table.insert(result, v) - else result[k] = v end - end - else - table.insert(result, t) - end - end - - -- ok? - return result -end - --- join all objects and tables to self -function table.join2(self, ...) - - -- check - assert(self and type(self) == "table") - - -- done - local args = {...} - for _, t in ipairs(args) do - if type(t) == "table" then - for k, v in pairs(t) do - if type(k) == "number" then table.insert(self, v) - else self[k] = v end - end - else - table.insert(self, t) - end - end - - -- ok? - return self -end - --- clear the table -function table.clear(self) - - -- check - assert(self and type(self) == "table") - - -- clear it - for k in next, self do - rawset(self, k, nil) - end -end - --- copy the table to self -function table.copy2(self, copied) - - -- check - assert(self and copied) - - -- clear self first - table.clear(self) - - -- copy it - for k, v in pairs(copied) do - self[k] = v - end - -end - --- return module: table -return table diff --git a/xmake/scripts/base/template.lua b/xmake/scripts/base/template.lua deleted file mode 100644 index c02b135c3..000000000 --- a/xmake/scripts/base/template.lua +++ /dev/null @@ -1,77 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file template.lua --- - --- define module: template -local template = template or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") - --- get the language list -function template.languages() - - -- make list - local list = {} - - -- get the language list - local languages = os.match(xmake._TEMPLATES_DIR .. "/*", true) - if languages then - for _, v in ipairs(languages) do - table.insert(list, path.basename(v)) - end - end - - -- ok? - return list -end - --- load all templates from the given language -function template.loadall(language) - - -- check - assert(language) - - -- load all templates - local modules = {} - local templates = os.match(string.format("%s/%s/**/_template.lua", xmake._TEMPLATES_DIR, language)) - if templates then - for _, t in ipairs(templates) do - local script = assert(loadfile(t)) - if script then - local module = script() - if module then - module._DIRECTORY = path.directory(t) - table.insert(modules, module) - end - end - end - end - - -- ok? - return modules -end - - --- return module: template -return template diff --git a/xmake/scripts/base/uninstall.lua b/xmake/scripts/base/uninstall.lua deleted file mode 100644 index 304b73c92..000000000 --- a/xmake/scripts/base/uninstall.lua +++ /dev/null @@ -1,104 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file uninstall.lua --- - --- define module: uninstall -local uninstall = uninstall or {} - --- load modules -local os = require("base/os") -local io = require("base/io") -local rule = require("base/rule") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local platform = require("platform/platform") - --- uninstall target from the platform script -function uninstall._done_from_platform(target) - - -- check - assert(target) - - -- the platform uninstall script file - local uninstallscript = nil - local scriptfile = platform.directory() .. "/uninstall.lua" - if os.isfile(scriptfile) then - - -- load the uninstall script - local script, errors = loadfile(scriptfile) - if script then - uninstallscript = script() - if type(uninstallscript) == "table" and uninstallscript.main then - uninstallscript = uninstallscript.main - end - else - utils.error(errors) - end - end - - -- uninstall it - if type(uninstallscript) == "function" then - return uninstallscript(target) - end - - -- continue - return 0 -end - --- uninstall target from the given target configure -function uninstall._done(target) - - -- check - assert(target) - - -- uninstall it from the platform script - local ok = uninstall._done_from_platform(target) - if ok ~= 0 then return utils.ifelse(ok == 1, true, false) end - - -- ok - return true -end - --- done uninstall from the configure -function uninstall.done(configs) - - -- check - assert(configs) - - -- uninstall targets - for _, target in pairs(configs) do - - -- uninstall it - if not uninstall._done(target) then - -- errors - utils.error("uninstall %s failed!", target.name) - return false - end - - end - - -- ok - return true -end - --- return module: uninstall -return uninstall diff --git a/xmake/scripts/base/utils.lua b/xmake/scripts/base/utils.lua deleted file mode 100644 index fd1f053d6..000000000 --- a/xmake/scripts/base/utils.lua +++ /dev/null @@ -1,258 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file utils.lua --- - --- define module: utils -local utils = utils or {} - --- the printf function -function utils.printf(msg, ...) - - -- check - assert(msg) - - -- trace - print(string.format(msg, ...)) -end - --- the verbose function -function utils.verbose(msg, ...) - - if xmake._OPTIONS.verbose then - - -- check - assert(msg) - - -- trace - print(string.format(msg, ...)) - end -end - --- the error function -function utils.error(msg, ...) - - -- check - assert(msg) - - -- trace - print("error: " .. string.format(msg, ...)) -end - --- the warning function -function utils.warning(msg, ...) - - -- check - assert(msg) - - -- trace - print("warning: " .. string.format(msg, ...)) -end - --- ifelse, a? b : c -function utils.ifelse(a, b, c) - if a then return b else return c end -end - --- dump object with the level -function utils._dump_with_level(object, exclude, level) - - -- dump string - if type(object) == "string" then - io.write(string.format("%q", object)) - -- dump boolean - elseif type(object) == "boolean" then - io.write(tostring(object)) - -- dump number - elseif type(object) == "number" then - io.write(object) - -- dump function - elseif type(object) == "function" then - io.write("") - -- dump table - elseif type(object) == "table" then - - -- dump head - io.write("\n") - for l = 1, level do - io.write(" ") - end - io.write("{\n") - - -- dump body - local i = 0 - for k, v in pairs(object) do - - -- exclude some keys - if not exclude or type(k) ~= "string" or not k:find(exclude) then - - -- dump spaces and separator - for l = 1, level do - io.write(" ") - end - - io.write(utils.ifelse(i == 0, " ", ", ")) - - -- dump key - if type(k) == "string" then - io.write(k, " = ") - end - - -- dump value - if not utils._dump_with_level(v, exclude, level + 1) then - return false - end - - -- dump newline - io.write("\n") - i = i + 1 - end - end - - -- dump tail - for l = 1, level do - io.write(" ") - end - io.write("}\n") - else - -- error - utils.error("invalid object type: %s", type(object)) - return false - end - - -- ok - return true -end - --- dump object -function utils.dump(object, exclude, prefix) - - -- dump prefix - if prefix then - io.write(prefix) - end - - -- dump it - utils._dump_with_level(object, exclude, 0) - - -- return it - return object -end - --- unwrap object if be only one -function utils.unwrap(object) - - -- check - assert(object) - - -- unwrap it - if type(object) == "table" and table.getn(object) == 1 then - for _, v in pairs(object) do - return v - end - end - - -- ok - return object -end - --- wrap object to table -function utils.wrap(object) - - -- no object? - if not object then - return {} - end - - -- wrap it if not table - if type(object) ~= "table" then - return {object} - end - - -- ok - return object -end - --- remove repeat from the given array -function utils.unique(array) - - -- check - assert(array) - - -- remove repeat - if type(array) == "table" then - - -- not only one? - if table.getn(array) ~= 1 then - - -- done - local exists = {} - local unique = {} - for _, v in ipairs(array) do - if type(v) == "string" then - if not exists[v] then - exists[v] = true - table.insert(unique, v) - end - else - if not exists["\"" .. v .. "\""] then - exists["\"" .. v .. "\""] = true - table.insert(unique, v) - end - end - end - - -- update it - array = unique - end - end - - -- ok - return array -end - --- call functions -function utils.call(funcs, pred, ...) - - -- check - assert(funcs) - - -- call all - for _, func in ipairs(utils.wrap(funcs)) do - - -- check - assert(type(func) == "function") - - -- call it - local result = func(...) - - -- exists predicate? - if pred and type(pred) == "function" then - if not pred(name, result) then return false end - -- failed? - elseif not result then return false end - end - - -- ok - return true -end - --- return module: utils -return utils diff --git a/xmake/scripts/module/os.lua b/xmake/scripts/module/os.lua deleted file mode 100644 index 3689086f2..000000000 --- a/xmake/scripts/module/os.lua +++ /dev/null @@ -1,46 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file os.lua --- - --- load modules -local io = require("base/io") -local os = require("base/os") - --- define module: _os -local _os = _os or {} - --- cat the given file -function _os.cat(filepath, linecount) - - -- cat it - return io.cat(filepath, linecount) -end - --- only copy the interfaces of os -for k, v in pairs(os) do - if type(v) == "function" then - _os[k] = v - end -end - --- return module: _os -return _os - diff --git a/xmake/scripts/module/path.lua b/xmake/scripts/module/path.lua deleted file mode 100644 index 9de905667..000000000 --- a/xmake/scripts/module/path.lua +++ /dev/null @@ -1,25 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file path.lua --- - --- return module: path -return require("base/path") - diff --git a/xmake/scripts/module/project.lua b/xmake/scripts/module/project.lua deleted file mode 100644 index f3f726c6f..000000000 --- a/xmake/scripts/module/project.lua +++ /dev/null @@ -1,73 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file project.lua --- - --- define module: project -local project = project or {} - --- load modules -local rule = require("base/rule") -local config = require("base/config") - --- get the build directory -function project.buildir() - - -- get it - return config.get("buildir") -end - --- get the project directory -function project.projectdir() - - -- get it - return xmake._PROJECT_DIR -end - --- get the log file -function project.logfile() - - -- get it - return rule.logfile() -end - --- get the current platform -function project.plat() - - -- get it - return config.get("plat") -end - --- get the current architecture -function project.arch() - - -- get it - return config.get("arch") -end - --- get the current mode -function project.mode() - - -- get it - return config.get("mode") -end - --- return module: project -return project diff --git a/xmake/scripts/module/string.lua b/xmake/scripts/module/string.lua deleted file mode 100644 index 60d3408cf..000000000 --- a/xmake/scripts/module/string.lua +++ /dev/null @@ -1,24 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file string.lua --- - --- return module: string -return require("base/string") diff --git a/xmake/scripts/module/utils.lua b/xmake/scripts/module/utils.lua deleted file mode 100644 index ab4d2c96f..000000000 --- a/xmake/scripts/module/utils.lua +++ /dev/null @@ -1,24 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file utils.lua --- - --- return module: utils -return require("base/utils") diff --git a/xmake/scripts/platform/android/android.lua b/xmake/scripts/platform/android/android.lua deleted file mode 100644 index 15e3c33a2..000000000 --- a/xmake/scripts/platform/android/android.lua +++ /dev/null @@ -1,120 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file android.lua --- - --- define module: android -local android = android or {} - --- load modules -local config = require("base/config") - --- init host -android._HOST = xmake._HOST - --- init os -android._OS = "android" - --- init architectures -android._ARCHS = {"armv5te", "armv6", "armv7-a", "armv8-a", "arm64-v8a"} - --- make configure -function android.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".so"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.as = config.get("as") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - - -- init flags - local arch = config.get("arch") - if arch:startswith("arm64") then - configs.cxflags = {} - configs.asflags = {} - configs.ldflags = {"-llog"} - configs.shflags = {"-llog"} - else - configs.cxflags = { "-march=" .. arch, "-mthumb"} - configs.asflags = { "-march=" .. arch, "-mthumb"} - configs.ldflags = { "-march=" .. arch, "-llog", "-mthumb"} - configs.shflags = { "-march=" .. arch, "-llog", "-mthumb"} - end - - -- add flags for the sdk directory of ndk - local ndk = config.get("ndk") - local ndk_sdkver = config.get("ndk_sdkver") - if ndk and ndk_sdkver then - local ndk_sdkdir = path.translate(string.format("%s/platforms/android-%d", ndk, ndk_sdkver)) - if arch:startswith("arm64") then - table.insert(configs.cxflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) - table.insert(configs.asflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) - table.insert(configs.ldflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) - table.insert(configs.shflags, string.format("--sysroot=%s/arch-arm64", ndk_sdkdir)) - else - table.insert(configs.cxflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) - table.insert(configs.asflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) - table.insert(configs.ldflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) - table.insert(configs.shflags, string.format("--sysroot=%s/arch-arm", ndk_sdkdir)) - end - end - -end - --- get the option menu for action: xmake config or global -function android.menu(action) - - -- init config option menu - android._MENU_CONFIG = android._MENU_CONFIG or - { {} - , {nil, "ndk", "kv", nil, "The NDK Directory" } - , {nil, "ndk_sdkver", "kv", "auto", "The SDK Version for NDK" } - , } - - -- init global option menu - android._MENU_GLOBAL = android._MENU_GLOBAL or - { {} - , {nil, "ndk", "kv", nil, "The NDK Directory" } - , {nil, "ndk_sdkver", "kv", "auto", "The SDK Version for NDK" } - , } - - -- get the option menu - if action == "config" then - return android._MENU_CONFIG - elseif action == "global" then - return android._MENU_GLOBAL - end -end - --- return module: android -return android diff --git a/xmake/scripts/platform/android/prober.lua b/xmake/scripts/platform/android/prober.lua deleted file mode 100644 index a6446e0e1..000000000 --- a/xmake/scripts/platform/android/prober.lua +++ /dev/null @@ -1,269 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", "armv7-a") - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the sdk version for ndk -function prober._probe_ndk_sdkver(configs) - - -- ok? - local ndk_sdkver = configs.get("ndk_sdkver") - if ndk_sdkver then return true end - - -- get the ndk - local ndk = configs.get("ndk") - if ndk then - - -- match all sdk directories - local sdkdirs = os.match(ndk .. "/platforms/android-*", true) - if sdkdirs then - - -- get the max version - local version_maxn = 0 - for _, sdkdir in ipairs(sdkdirs) do - local filename = path.filename(sdkdir) - local version, count = filename:gsub("android%-", "") - if count > 0 then - version = tonumber(version) - if version > version_maxn then version_maxn = version end - end - end - - -- save the version - if version_maxn > 0 then ndk_sdkver = version_maxn end - end - end - - -- probe ok? update it - if type(ndk_sdkver) == "number" and ndk_sdkver > 0 then - - -- save it - configs.set("ndk_sdkver", ndk_sdkver) - - -- trace - utils.printf("checking for the SDK version of NDK ... %s", string.format("android-%d", ndk_sdkver)) - else - - -- trace - utils.printf("checking for the SDK version of NDK ... no") - end - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolpath(configs, kind, cross, name, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- attempt to get it from the given cross toolchains - local toolpath = nil - local toolchains = configs.get("toolchains") - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to get it from the ndk - if not toolpath then - local ndk = configs.get("ndk") - if ndk then - - -- match all toolchains - local arch = configs.get("arch") - if arch and arch:startswith("arm64") then - toolchains = os.match(string.format("%s/toolchains/aarch64-linux-android-**/prebuilt/*/bin/%s%s", ndk, cross, name)) - else - toolchains = os.match(string.format("%s/toolchains/arm-linux-androideabi-**/prebuilt/*/bin/%s%s", ndk, cross, name)) - end - - -- probe the tool path - if toolchains then - for _, filepath in ipairs(toolchains) do - toolpath = tools.probe(cross .. name, path.directory(filepath)) - if toolpath then break end - end - end - end - end - - -- probe ok? update it - if toolpath then configs.set(kind, toolpath) end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- failed? - if not toolpath and not configs.get("ndk") then - utils.error("checking for the NDK directory ... no") - utils.error(" - xmake config --ndk=xxx") - utils.error("or - xmake global --ndk=xxx") - return false - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- init prefix - local prefix = "arm-linux-androideabi-" - local arch = configs.get("arch") - if arch and arch:startswith("arm64") then - prefix = "aarch64-linux-android-" - end - - -- done - if not prober._probe_toolpath(configs, "cc", prefix, "gcc", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", prefix, "g++", "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", prefix, "gcc", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", prefix, "g++", "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", prefix, "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", prefix, "g++", "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", prefix, "swiftc", "the swift compiler") then return false end - - -- ok - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_make - , prober._probe_ccache - , prober._probe_ndk_sdkver - , prober._probe_toolchains} - , nil - , config) - -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_make - , prober._probe_ccache - , prober._probe_ndk_sdkver} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/iphoneos/iphoneos.lua b/xmake/scripts/platform/iphoneos/iphoneos.lua deleted file mode 100644 index f9147945c..000000000 --- a/xmake/scripts/platform/iphoneos/iphoneos.lua +++ /dev/null @@ -1,141 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file iphoneos.lua --- - --- define module: iphoneos -local iphoneos = iphoneos or {} - --- load modules -local config = require("base/config") - --- init host -iphoneos._HOST = "macosx" - --- init os -iphoneos._OS = "ios" - --- init architectures -iphoneos._ARCHS = {"armv7", "armv7s", "arm64"} - --- make configure -function iphoneos.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".dylib"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.mm = config.get("mm") - configs.tools.mxx = config.get("mxx") - configs.tools.as = config.get("as") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - configs.tools.lipo = config.get("lipo") - - -- init target minimal version - local target_minver = config.get("target_minver") - assert(target_minver) - - -- init flags for architecture - local archflags = nil - local arch = config.get("arch") - if arch then archflags = "-arch " .. arch end - configs.cxflags = { archflags, "-miphoneos-version-min=" .. target_minver } - configs.mxflags = { archflags, "-miphoneos-version-min=" .. target_minver } - configs.asflags = { archflags, "-miphoneos-version-min=" .. target_minver } - configs.ldflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-miphoneos-version-min=" .. target_minver } - configs.shflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-miphoneos-version-min=" .. target_minver } - if arch then - configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } - end - - -- init flags for the xcode sdk directory - local xcode_dir = config.get("xcode_dir") - local xcode_sdkver = config.get("xcode_sdkver") - if xcode_dir and xcode_sdkver then - - -- init flags - local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS" .. xcode_sdkver .. ".sdk" - table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) - - -- save swift link directory - config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos") - end - -end - --- get the option menu for action: xmake config or global -function iphoneos.menu(action) - - -- init config option menu - iphoneos._MENU_CONFIG = iphoneos._MENU_CONFIG or - { {} - , {nil, "mm", "kv", nil, "The Objc Compiler" } - , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } - , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } - , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } - , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } - , {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } - , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- init global option menu - iphoneos._MENU_GLOBAL = iphoneos._MENU_GLOBAL or - { {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- get the option menu - if action == "config" then - return iphoneos._MENU_CONFIG - elseif action == "global" then - return iphoneos._MENU_GLOBAL - end -end - - --- return module: iphoneos -return iphoneos diff --git a/xmake/scripts/platform/iphoneos/package.lua b/xmake/scripts/platform/iphoneos/package.lua deleted file mode 100644 index 1e46ddadc..000000000 --- a/xmake/scripts/platform/iphoneos/package.lua +++ /dev/null @@ -1,76 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file package.lua --- - --- define module: package -local package = package or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local string = require("base/string") -local platform = require("platform/platform") - --- package target -function package.main(target) - - -- check - assert(target and target.name) - - -- the count of architectures - local count = 0 - for _, _ in pairs(target.archs) do count = count + 1 end - if count < 2 then return 0 end - - -- get the lipo tool - local lipo = platform.tool("lipo") - if not lipo then return 0 end - - -- make universal info - local universal = {} - universal.targetdir = rule.backupdir(target.name, "universal") - universal.targetfile = rule.targetfile(target.name, target) - if not universal.targetdir or not universal.targetfile then return 0 end - - -- make the universal directory - os.mkdir(path.directory(string.format("%s/%s", universal.targetdir, universal.targetfile))) - - -- make the lipo command - local cmd = lipo .. " -create" - for arch, info in pairs(target.archs) do - cmd = string.format("%s -arch %s %s/%s", cmd, arch, info.targetdir, info.targetfile) - end - cmd = string.format("%s -output %s/%s", cmd, universal.targetdir, universal.targetfile) - - -- make the universal target - if 0 ~= os.execute(cmd) then return 0 end - - -- ok - target.archs.universal = universal - - -- continue - return 0 -end - --- return module: package -return package diff --git a/xmake/scripts/platform/iphoneos/prober.lua b/xmake/scripts/platform/iphoneos/prober.lua deleted file mode 100644 index 0b4d10dc8..000000000 --- a/xmake/scripts/platform/iphoneos/prober.lua +++ /dev/null @@ -1,310 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", "armv7") - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the xcode application directory -function prober._probe_xcode(configs) - - -- get the xcode directory - local xcode_dir = configs.get("xcode_dir") - - -- ok? - if xcode_dir then return true end - - -- clear it first - xcode_dir = nil - - -- attempt to get the default directory - if not xcode_dir then - if os.isdir("/Applications/Xcode.app") then - xcode_dir = "/Applications/Xcode.app" - end - end - - -- attempt to match the other directories - if not xcode_dir then - local dirs = os.match("/Applications/Xcode*.app", true) - if dirs and table.getn(dirs) ~= 0 then - xcode_dir = dirs[1] - end - end - - -- probe ok? update it - if xcode_dir then - -- save it - configs.set("xcode_dir", xcode_dir) - - -- trace - utils.printf("checking for the Xcode application directory ... %s", xcode_dir) - else - -- failed - utils.error("checking for the Xcode application directory ... no") - utils.error(" - xmake config --xcode_dir=xxx") - utils.error("or - xmake global --xcode_dir=xxx") - return false - end - - -- ok - return true -end - --- probe the xcode sdk version -function prober._probe_xcode_sdkver(configs) - - -- get the xcode sdk version - local xcode_sdkver = configs.get("xcode_sdkver") - - -- ok? - if xcode_sdkver then return true end - - -- clear it first - xcode_sdkver = nil - - -- attempt to match the directory - if not xcode_sdkver then - local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk", true) - if dirs then - for _, dir in ipairs(dirs) do - xcode_sdkver = string.match(dir, "%d+%.%d+") - if xcode_sdkver then break end - end - end - end - - -- probe ok? update it - if xcode_sdkver then - - -- save it - configs.set("xcode_sdkver", xcode_sdkver) - - -- trace - utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) - else - -- failed - utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) - utils.error(" - xmake config --xcode_sdkver=xxx") - utils.error("or - xmake global --xcode_sdkver=xxx") - return false - end - - -- ok - return true -end - --- probe the target minimal version -function prober._probe_target_minver(configs) - - -- get the target minimal version - local target_minver = configs.get("target_minver") - - -- ok? - if target_minver then return true end - - -- init the default target minimal version - configs.set("target_minver", "7.0") - - -- trace - utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, cross, names, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- done - local toolpath = nil - local toolchains = configs.get("toolchains") - for _, name in ipairs(utils.wrap(names)) do - - -- attempt to get it from the given cross toolchains - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to run it directly - if not toolpath then - toolpath = tools.probe(cross .. name) - end - - -- probe ok? - if toolpath then - - -- update config - configs.set(kind, toolpath) - - -- end - break - end - - end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- done - if not prober._probe_toolpath(configs, "cc", "xcrun -sdk iphoneos ", "clang", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "mm", "xcrun -sdk iphoneos ", "clang", "the objc compiler") then return false end - if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the objc++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", xmake._SCRIPTS_DIR .. "/tools/gas-preprocessor.pl xcrun -sdk iphoneos ", "clang", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", "xcrun -sdk iphoneos ", "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", "xcrun -sdk iphoneos ", {"clang++", "clang"}, "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", "xcrun -sdk iphoneos ", "swiftc", "the swift compiler") then return false end - if not prober._probe_toolpath(configs, "lipo", "xcrun -sdk iphoneos ", "lipo", "the universal files creater") then return false end - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_xcode - , prober._probe_xcode_sdkver - , prober._probe_target_minver - , prober._probe_make - , prober._probe_ccache - , prober._probe_toolchains} - , nil - , config) - -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_xcode - , prober._probe_make - , prober._probe_ccache} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/iphonesimulator/iphonesimulator.lua b/xmake/scripts/platform/iphonesimulator/iphonesimulator.lua deleted file mode 100644 index 4ceeb3eca..000000000 --- a/xmake/scripts/platform/iphonesimulator/iphonesimulator.lua +++ /dev/null @@ -1,138 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file iphonesimulator.lua --- - --- define module: iphonesimulator -local iphonesimulator = iphonesimulator or {} - --- load modules -local config = require("base/config") - --- init host -iphonesimulator._HOST = "macosx" - --- init os -iphonesimulator._OS = "ios" - --- init architectures -iphonesimulator._ARCHS = {"i386", "x86_64"} - --- make configure -function iphonesimulator.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".dylib"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.mm = config.get("mm") - configs.tools.mxx = config.get("mxx") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - - -- init target minimal version - local target_minver = config.get("target_minver") - assert(target_minver) - - -- init flags for architecture - local archflags = nil - local arch = config.get("arch") - if arch then archflags = "-arch " .. arch end - configs.cxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } - configs.mxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } - configs.asflags = { archflags, "-mios-simulator-version-min=" .. target_minver } - configs.ldflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } - configs.shflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } - if arch then - configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } - end - - -- init flags for the xcode sdk directory - local xcode_dir = config.get("xcode_dir") - local xcode_sdkver = config.get("xcode_sdkver") - if xcode_dir and xcode_sdkver then - - -- init flags - local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator" .. xcode_sdkver .. ".sdk" - table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) - - -- save swift link directory - config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator") - end -end - --- get the option menu for action: xmake config or global -function iphonesimulator.menu(action) - - -- init config option menu - iphonesimulator._MENU_CONFIG = iphonesimulator._MENU_CONFIG or - { {} - , {nil, "mm", "kv", nil, "The Objc Compiler" } - , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } - , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } - , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } - , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } - , {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } - , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- init global option menu - iphonesimulator._MENU_GLOBAL = iphonesimulator._MENU_GLOBAL or - { {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- get the option menu - if action == "config" then - return iphonesimulator._MENU_CONFIG - elseif action == "global" then - return iphonesimulator._MENU_GLOBAL - end -end - - --- return module: iphonesimulator -return iphonesimulator diff --git a/xmake/scripts/platform/iphonesimulator/prober.lua b/xmake/scripts/platform/iphonesimulator/prober.lua deleted file mode 100644 index a4c69c72a..000000000 --- a/xmake/scripts/platform/iphonesimulator/prober.lua +++ /dev/null @@ -1,308 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", "x86_64") - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the xcode application directory -function prober._probe_xcode(configs) - - -- get the xcode directory - local xcode_dir = configs.get("xcode_dir") - - -- ok? - if xcode_dir then return true end - - -- clear it first - xcode_dir = nil - - -- attempt to get the default directory - if not xcode_dir then - if os.isdir("/Applications/Xcode.app") then - xcode_dir = "/Applications/Xcode.app" - end - end - - -- attempt to match the other directories - if not xcode_dir then - local dirs = os.match("/Applications/Xcode*.app", true) - if dirs and table.getn(dirs) ~= 0 then - xcode_dir = dirs[1] - end - end - - -- probe ok? update it - if xcode_dir then - -- save it - configs.set("xcode_dir", xcode_dir) - - -- trace - utils.printf("checking for the Xcode application directory ... %s", xcode_dir) - else - -- failed - utils.error("checking for the Xcode application directory ... no") - utils.error(" - xmake config --xcode_dir=xxx") - utils.error("or - xmake global --xcode_dir=xxx") - return false - end - - -- ok - return true -end - --- probe the xcode sdk version -function prober._probe_xcode_sdkver(configs) - - -- get the xcode sdk version - local xcode_sdkver = configs.get("xcode_sdkver") - - -- ok? - if xcode_sdkver then return true end - - -- clear it first - xcode_sdkver = nil - - -- attempt to match the directory - if not xcode_sdkver then - local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator*.sdk", true) - if dirs then - for _, dir in ipairs(dirs) do - xcode_sdkver = string.match(dir, "%d+%.%d+") - if xcode_sdkver then break end - end - end - end - - -- probe ok? update it - if xcode_sdkver then - - -- save it - configs.set("xcode_sdkver", xcode_sdkver) - - -- trace - utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) - else - -- failed - utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) - utils.error(" - xmake config --xcode_sdkver=xxx") - utils.error("or - xmake global --xcode_sdkver=xxx") - return false - end - - -- ok - return true -end - --- probe the target minimal version -function prober._probe_target_minver(configs) - - -- get the target minimal version - local target_minver = configs.get("target_minver") - - -- ok? - if target_minver then return true end - - -- init the default target minimal version - configs.set("target_minver", "7.0") - - -- trace - utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, cross, names, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- done - local toolpath = nil - local toolchains = configs.get("toolchains") - for _, name in ipairs(utils.wrap(names)) do - - -- attempt to get it from the given cross toolchains - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to run it directly - if not toolpath then - toolpath = tools.probe(cross .. name) - end - - -- probe ok? - if toolpath then - - -- update config - configs.set(kind, toolpath) - - -- end - break - end - - end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- done - if not prober._probe_toolpath(configs, "cc", "xcrun -sdk iphonesimulator ", "clang", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "mm", "xcrun -sdk iphonesimulator ", "clang", "the objc compiler") then return false end - if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the objc++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", "xcrun -sdk iphonesimulator ", "clang", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", "xcrun -sdk iphonesimulator ", "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", "xcrun -sdk iphonesimulator ", {"clang++", "clang"}, "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", "xcrun -sdk iphonesimulator ", "swiftc", "the swift compiler") then return false end - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_xcode - , prober._probe_xcode_sdkver - , prober._probe_target_minver - , prober._probe_make - , prober._probe_ccache - , prober._probe_toolchains} - , nil - , config) -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_xcode - , prober._probe_make - , prober._probe_ccache} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/linux/install.lua b/xmake/scripts/platform/linux/install.lua deleted file mode 100644 index 870cf5040..000000000 --- a/xmake/scripts/platform/linux/install.lua +++ /dev/null @@ -1,182 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file install.lua --- - --- define module: install -local install = install or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local string = require("base/string") -local platform = require("platform/platform") - --- install target for the library file -function install._done_library(target) - - -- check - assert(target and target.name and target.archs) - - -- the output directory - local outputdir = target.outputdir or "/usr/local" - assert(outputdir) - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- make the library directory - local librarydir = outputdir .. "/lib" - if not os.isdir(librarydir) then - if not os.mkdir(librarydir) then - utils.error("create directory %s failed", librarydir) - return -1 - end - end - - -- copy the library file to the library directory - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", librarydir, path.filename(info.targetfile))) - if not ok then - utils.error(errors) - return -1 - end - - -- make the include directory - local includedir = outputdir .. "/include" - if not os.isdir(includedir) then - if not os.mkdir(includedir) then - utils.error("create directory %s failed", includedir) - return -1 - end - end - - -- copy the config.h to the output directory - if info.config_h then - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h))) - if not ok then - utils.error(errors) - return -1 - end - - -- update the config.h - info.config_h = string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h)) - end - - -- copy headers - if target.headers then - local srcheaders, dstheaders = rule.headerfiles(target, includedir) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - local ok, errors = os.cp(srcheader, dstheader) - if not ok then - utils.error(errors) - return -1 - end - end - i = i + 1 - end - end - - -- update the headers - target.headers = dstheaders - end - - -- update the target directory and file - info.targetdir = librarydir - info.targetfile = path.filename(info.targetfile) - - -- ok - return 1 -end - --- install target for the binary file -function install._done_binary(target) - - -- check - assert(target and target.archs) - - -- the output directory - local outputdir = target.outputdir or "/usr/local" - assert(outputdir) - - -- make the binary directory - local binarydir = outputdir .. "/bin" - if not os.isdir(binarydir) then - if not os.mkdir(binarydir) then - utils.error("create directory %s failed", binarydir) - return -1 - end - end - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- copy the binary file to the binary directory - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), binarydir) - if not ok then - utils.error(errors) - return -1 - end - - -- update the target directory and file - info.targetdir = binarydir - info.targetfile = path.filename(info.targetfile) - - -- ok - return 1 -end - --- install target -function install.main(target) - - -- check - assert(target and target.kind) - - -- the install scripts - local installscripts = - { - static = install._done_library - , shared = install._done_library - , binary = install._done_binary - } - - -- install it - local installscript = installscripts[target.kind] - if installscript then return installscript(target) end - - -- continue - return 0 -end - --- return module: install -return install diff --git a/xmake/scripts/platform/linux/linux.lua b/xmake/scripts/platform/linux/linux.lua deleted file mode 100644 index 406dc5c58..000000000 --- a/xmake/scripts/platform/linux/linux.lua +++ /dev/null @@ -1,103 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file linux.lua --- - --- define module: linux -local linux = linux or {} - --- load modules -local config = require("base/config") - --- init host -linux._HOST = "linux" - --- init os -linux._OS = "linux" - --- init architectures -linux._ARCHS = {"i386", "x86_64"} - --- make configure -function linux.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".so"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.mm = config.get("mm") - configs.tools.mxx = config.get("mxx") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - - -- cross toolchains? - if config.get("cross") then return end - - -- init flags for architecture - local archflags = nil - local arch = config.get("arch") - if arch then - if arch == "x86_64" then archflags = "-m64" - elseif arch == "i386" then archflags = "-m32" - else archflags = "-arch " .. arch - end - end - configs.cxflags = { archflags } - configs.mxflags = { archflags } - configs.asflags = { archflags } - configs.ldflags = { archflags } - configs.shflags = { archflags } - - -- init linkdirs and includedirs - configs.linkdirs = {"/usr/lib", "/usr/local/lib"} - configs.includedirs = {"/usr/include", "/usr/local/include"} - -end - --- get the option menu for action: xmake config or global -function linux.menu(action) - - -- init config option menu - linux._MENU_CONFIG = linux._MENU_CONFIG or {} - - -- init global option menu - linux._MENU_GLOBAL = linux._MENU_GLOBAL or {} - - -- get the option menu - if action == "config" then - return linux._MENU_CONFIG - elseif action == "global" then - return linux._MENU_GLOBAL - end -end - --- return module: linux -return linux diff --git a/xmake/scripts/platform/linux/prober.lua b/xmake/scripts/platform/linux/prober.lua deleted file mode 100644 index 4e50b13cf..000000000 --- a/xmake/scripts/platform/linux/prober.lua +++ /dev/null @@ -1,198 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - if configs.get("cross") then - configs.set("arch", "none") - else - configs.set("arch", xmake._ARCH) - end - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, cross, names, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- done - local toolpath = nil - local toolchains = configs.get("toolchains") - for _, name in ipairs(utils.wrap(names)) do - - -- attempt to get it from the given cross toolchains - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to run it directly - if not toolpath then - toolpath = tools.probe(cross .. name) - end - - -- probe ok? - if toolpath then - - -- update config - configs.set(kind, toolpath) - - -- end - break - end - - end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- done - if not prober._probe_toolpath(configs, "cc", "", "gcc", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", "", {"g++", "gcc"}, "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", "", "gcc", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", "", {"g++", "gcc"}, "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", "", "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", "", {"g++", "gcc"}, "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", "", "swiftc", "the swift compiler") then return false end - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_make - , prober._probe_ccache - , prober._probe_toolchains} - , nil - , config) -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_make - , prober._probe_ccache} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/linux/uninstall.lua b/xmake/scripts/platform/linux/uninstall.lua deleted file mode 100644 index 468692620..000000000 --- a/xmake/scripts/platform/linux/uninstall.lua +++ /dev/null @@ -1,134 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file uninstall.lua --- - --- define module: uninstall -local uninstall = uninstall or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local string = require("base/string") -local platform = require("platform/platform") - --- uninstall target for the library file -function uninstall._done_library(target) - - -- check - assert(target and target.name and target.archs) - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- remove the target file - local targetfile = info.targetdir .. "/" .. info.targetfile - if os.isfile(targetfile) then - local ok, errors = os.rm(targetfile) - if not ok then - utils.error(errors) - return -1 - end - end - - -- remove config.h - if info.config_h and os.isfile(info.config_h) then - local ok, errors = os.rm(info.config_h) - if not ok then - utils.error(errors) - return -1 - end - end - - -- remove headers - if target.headers then - for _, header in ipairs(target.headers) do - if os.isfile(header) then - local ok, errors = os.rm(header) - if not ok then - utils.error(errors) - return -1 - end - end - end - end - - -- ok - return 1 -end - --- uninstall target for the binary file -function uninstall._done_binary(target) - - -- check - assert(target and target.archs) - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- the target file - local targetfile = info.targetdir .. "/" .. info.targetfile - if not os.isfile(targetfile) then return 1 end - - -- remove the target file - local ok, errors = os.rm(targetfile) - if not ok then - utils.error(errors) - return -1 - end - - -- ok - return 1 -end - --- uninstall target -function uninstall.main(target) - - -- check - assert(target and target.kind) - - -- the uninstall scripts - local uninstallscripts = - { - static = uninstall._done_library - , shared = uninstall._done_library - , binary = uninstall._done_binary - } - - -- uninstall it - local uninstallscript = uninstallscripts[target.kind] - if uninstallscript then return uninstallscript(target) end - - -- continue - return 0 -end - --- return module: uninstall -return uninstall diff --git a/xmake/scripts/platform/macosx/install.lua b/xmake/scripts/platform/macosx/install.lua deleted file mode 100644 index 870cf5040..000000000 --- a/xmake/scripts/platform/macosx/install.lua +++ /dev/null @@ -1,182 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file install.lua --- - --- define module: install -local install = install or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local string = require("base/string") -local platform = require("platform/platform") - --- install target for the library file -function install._done_library(target) - - -- check - assert(target and target.name and target.archs) - - -- the output directory - local outputdir = target.outputdir or "/usr/local" - assert(outputdir) - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- make the library directory - local librarydir = outputdir .. "/lib" - if not os.isdir(librarydir) then - if not os.mkdir(librarydir) then - utils.error("create directory %s failed", librarydir) - return -1 - end - end - - -- copy the library file to the library directory - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), string.format("%s/%s", librarydir, path.filename(info.targetfile))) - if not ok then - utils.error(errors) - return -1 - end - - -- make the include directory - local includedir = outputdir .. "/include" - if not os.isdir(includedir) then - if not os.mkdir(includedir) then - utils.error("create directory %s failed", includedir) - return -1 - end - end - - -- copy the config.h to the output directory - if info.config_h then - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.config_h), string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h))) - if not ok then - utils.error(errors) - return -1 - end - - -- update the config.h - info.config_h = string.format("%s/%s/%s", includedir, target.name, path.filename(info.config_h)) - end - - -- copy headers - if target.headers then - local srcheaders, dstheaders = rule.headerfiles(target, includedir) - if srcheaders and dstheaders then - local i = 1 - for _, srcheader in ipairs(srcheaders) do - local dstheader = dstheaders[i] - if dstheader then - local ok, errors = os.cp(srcheader, dstheader) - if not ok then - utils.error(errors) - return -1 - end - end - i = i + 1 - end - end - - -- update the headers - target.headers = dstheaders - end - - -- update the target directory and file - info.targetdir = librarydir - info.targetfile = path.filename(info.targetfile) - - -- ok - return 1 -end - --- install target for the binary file -function install._done_binary(target) - - -- check - assert(target and target.archs) - - -- the output directory - local outputdir = target.outputdir or "/usr/local" - assert(outputdir) - - -- make the binary directory - local binarydir = outputdir .. "/bin" - if not os.isdir(binarydir) then - if not os.mkdir(binarydir) then - utils.error("create directory %s failed", binarydir) - return -1 - end - end - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- copy the binary file to the binary directory - local ok, errors = os.cp(string.format("%s/%s", info.targetdir, info.targetfile), binarydir) - if not ok then - utils.error(errors) - return -1 - end - - -- update the target directory and file - info.targetdir = binarydir - info.targetfile = path.filename(info.targetfile) - - -- ok - return 1 -end - --- install target -function install.main(target) - - -- check - assert(target and target.kind) - - -- the install scripts - local installscripts = - { - static = install._done_library - , shared = install._done_library - , binary = install._done_binary - } - - -- install it - local installscript = installscripts[target.kind] - if installscript then return installscript(target) end - - -- continue - return 0 -end - --- return module: install -return install diff --git a/xmake/scripts/platform/macosx/macosx.lua b/xmake/scripts/platform/macosx/macosx.lua deleted file mode 100644 index 088a01c18..000000000 --- a/xmake/scripts/platform/macosx/macosx.lua +++ /dev/null @@ -1,140 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file macosx.lua --- - --- define module: macosx -local macosx = macosx or {} - --- load modules -local config = require("base/config") - --- init host -macosx._HOST = "macosx" - --- init os -macosx._OS = "macosx" - --- init architectures -macosx._ARCHS = {"i386", "x86_64"} - --- make configure -function macosx.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".dylib"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.mm = config.get("mm") - configs.tools.mxx = config.get("mxx") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - - -- init target minimal version - local target_minver = config.get("target_minver") - assert(target_minver) - - -- init flags for architecture - local archflags = nil - local arch = config.get("arch") - if arch then archflags = "-arch " .. arch end - configs.cxflags = { archflags, "-fpascal-strings", "-fmessage-length=0" } - configs.mxflags = { archflags, "-fpascal-strings", "-fmessage-length=0" } - configs.asflags = { archflags } - configs.ldflags = { archflags, "-mmacosx-version-min=" .. target_minver, "-stdlib=libc++", "-lz" } - configs.shflags = { archflags, "-mmacosx-version-min=" .. target_minver, "-stdlib=libc++", "-lz" } - if arch then - configs.scflags = { string.format("-target %s-apple-macosx%s", arch, target_minver) } - end - - -- init flags for the xcode sdk directory - local xcode_dir = config.get("xcode_dir") - local xcode_sdkver = config.get("xcode_sdkver") - if xcode_dir and xcode_sdkver then - - -- init flags - local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX" .. xcode_sdkver .. ".sdk" - table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) - - -- save swift link directory - config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx") - end - - -- init linkdirs - configs.linkdirs = {"/usr/lib", "/usr/local/lib"} - - -- init includedirs - -- - -- @note - -- cannot use configs.includedirs because the swift/objc compiler will compile code failed - table.insert(configs.cxflags, "-I/usr/include") - table.insert(configs.cxflags, "-I/usr/local/include") - -end - --- get the option menu for action: xmake config or global -function macosx.menu(action) - - -- init config option menu - macosx._MENU_CONFIG = macosx._MENU_CONFIG or - { {} - , {nil, "mm", "kv", nil, "The Objc Compiler" } - , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } - , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } - , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } - , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } - , {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } - , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } - , } - - -- init global option menu - macosx._MENU_GLOBAL = macosx._MENU_GLOBAL or - { {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , } - - -- get the option menu - if action == "config" then - return macosx._MENU_CONFIG - elseif action == "global" then - return macosx._MENU_GLOBAL - end -end - --- return module: macosx -return macosx diff --git a/xmake/scripts/platform/macosx/prober.lua b/xmake/scripts/platform/macosx/prober.lua deleted file mode 100644 index e2571fdd9..000000000 --- a/xmake/scripts/platform/macosx/prober.lua +++ /dev/null @@ -1,307 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", xmake._ARCH) - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the xcode application directory -function prober._probe_xcode(configs) - - -- get the xcode directory - local xcode_dir = configs.get("xcode_dir") - - -- ok? - if xcode_dir then return true end - - -- clear it first - xcode_dir = nil - - -- attempt to get the default directory - if not xcode_dir then - if os.isdir("/Applications/Xcode.app") then - xcode_dir = "/Applications/Xcode.app" - end - end - - -- attempt to match the other directories - if not xcode_dir then - local dirs = os.match("/Applications/Xcode*.app", true) - if dirs and table.getn(dirs) ~= 0 then - xcode_dir = dirs[1] - end - end - - -- probe ok? update it - if xcode_dir then - -- save it - configs.set("xcode_dir", xcode_dir) - - -- trace - utils.printf("checking for the Xcode application directory ... %s", xcode_dir) - else - -- failed - utils.error("checking for the Xcode application directory ... no") - utils.error(" - xmake config --xcode_dir=xxx") - utils.error("or - xmake global --xcode_dir=xxx") - return false - end - - -- ok - return true -end - --- probe the xcode sdk version -function prober._probe_xcode_sdkver(configs) - - -- get the xcode sdk version - local xcode_sdkver = configs.get("xcode_sdkver") - - -- ok? - if xcode_sdkver then return true end - - -- clear it first - xcode_sdkver = nil - - -- attempt to match the directory - if not xcode_sdkver then - local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX*.sdk", true) - if dirs then - for _, dir in ipairs(dirs) do - xcode_sdkver = string.match(dir, "%d+%.%d+") - if xcode_sdkver then break end - end - end - end - - -- probe ok? update it - if xcode_sdkver then - - -- save it - configs.set("xcode_sdkver", xcode_sdkver) - - -- trace - utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) - else - -- failed - utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) - utils.error(" - xmake config --xcode_sdkver=xxx") - utils.error("or - xmake global --xcode_sdkver=xxx") - return false - end - - -- ok - return true -end - --- probe the target minimal version -function prober._probe_target_minver(configs) - - -- get the target minimal version - local target_minver = configs.get("target_minver") - - -- ok? - if target_minver then return true end - - -- init the default target minimal version - configs.set("target_minver", "10.9") - - -- trace - utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, cross, names, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- done - local toolpath = nil - local toolchains = configs.get("toolchains") - for _, name in ipairs(utils.wrap(names)) do - - -- attempt to get it from the given cross toolchains - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to run it directly - if not toolpath then - toolpath = tools.probe(cross .. name) - end - - -- probe ok? - if toolpath then - - -- update config - configs.set(kind, toolpath) - - -- end - break - end - - end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- done - if not prober._probe_toolpath(configs, "cc", "xcrun -sdk macosx ", "clang", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk macosx ", {"clang++", "clang"}, "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "mm", "xcrun -sdk macosx ", "clang", "the objc compiler") then return false end - if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk macosx ", {"clang++", "clang"}, "the objc++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", "xcrun -sdk macosx ", "clang", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", "xcrun -sdk macosx ", {"clang++", "clang"}, "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", "xcrun -sdk macosx ", "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", "xcrun -sdk macosx ", {"clang++", "clang"}, "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", "xcrun -sdk macosx ", "swiftc", "the swift compiler") then return false end - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_xcode - , prober._probe_xcode_sdkver - , prober._probe_target_minver - , prober._probe_make - , prober._probe_ccache - , prober._probe_toolchains} - , nil - , config) -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_xcode - , prober._probe_ccache} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/macosx/uninstall.lua b/xmake/scripts/platform/macosx/uninstall.lua deleted file mode 100644 index 468692620..000000000 --- a/xmake/scripts/platform/macosx/uninstall.lua +++ /dev/null @@ -1,134 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file uninstall.lua --- - --- define module: uninstall -local uninstall = uninstall or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local string = require("base/string") -local platform = require("platform/platform") - --- uninstall target for the library file -function uninstall._done_library(target) - - -- check - assert(target and target.name and target.archs) - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- remove the target file - local targetfile = info.targetdir .. "/" .. info.targetfile - if os.isfile(targetfile) then - local ok, errors = os.rm(targetfile) - if not ok then - utils.error(errors) - return -1 - end - end - - -- remove config.h - if info.config_h and os.isfile(info.config_h) then - local ok, errors = os.rm(info.config_h) - if not ok then - utils.error(errors) - return -1 - end - end - - -- remove headers - if target.headers then - for _, header in ipairs(target.headers) do - if os.isfile(header) then - local ok, errors = os.rm(header) - if not ok then - utils.error(errors) - return -1 - end - end - end - end - - -- ok - return 1 -end - --- uninstall target for the binary file -function uninstall._done_binary(target) - - -- check - assert(target and target.archs) - - -- get target info - local info = target.archs[xmake._ARCH] or target.archs["x86_64"] or target.archs["i386"] - if not info then return -1 end - - -- check - assert(info.targetdir and info.targetfile) - - -- the target file - local targetfile = info.targetdir .. "/" .. info.targetfile - if not os.isfile(targetfile) then return 1 end - - -- remove the target file - local ok, errors = os.rm(targetfile) - if not ok then - utils.error(errors) - return -1 - end - - -- ok - return 1 -end - --- uninstall target -function uninstall.main(target) - - -- check - assert(target and target.kind) - - -- the uninstall scripts - local uninstallscripts = - { - static = uninstall._done_library - , shared = uninstall._done_library - , binary = uninstall._done_binary - } - - -- uninstall it - local uninstallscript = uninstallscripts[target.kind] - if uninstallscript then return uninstallscript(target) end - - -- continue - return 0 -end - --- return module: uninstall -return uninstall diff --git a/xmake/scripts/platform/mingw/mingw.lua b/xmake/scripts/platform/mingw/mingw.lua deleted file mode 100644 index 7264489b2..000000000 --- a/xmake/scripts/platform/mingw/mingw.lua +++ /dev/null @@ -1,93 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file mingw.lua --- - --- define module: mingw -local mingw = mingw or {} - --- load modules -local config = require("base/config") - --- init host -mingw._HOST = xmake._HOST - --- init os -mingw._OS = "windows" - --- init architectures -mingw._ARCHS = {"i386", "x86_64"} - --- make configure -function mingw.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".so"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - - -- init flags for architecture - local archflags = nil - local arch = config.get("arch") - if arch then - if arch == "x86_64" then archflags = "-m64" - elseif arch == "i386" then archflags = "-m32" - else archflags = "-arch " .. arch - end - end - configs.cxflags = { archflags } - configs.asflags = { archflags } - configs.ldflags = { archflags } - configs.shflags = { archflags } - -end - --- get the option menu for action: xmake config or global -function mingw.menu(action) - - -- init config option menu - mingw._MENU_CONFIG = mingw._MENU_CONFIG or {} - - -- init global option menu - mingw._MENU_GLOBAL = mingw._MENU_GLOBAL or {} - - -- get the option menu - if action == "config" then - return mingw._MENU_CONFIG - elseif action == "global" then - return mingw._MENU_GLOBAL - end -end - --- return module: mingw -return mingw diff --git a/xmake/scripts/platform/mingw/prober.lua b/xmake/scripts/platform/mingw/prober.lua deleted file mode 100644 index 575e3a7ba..000000000 --- a/xmake/scripts/platform/mingw/prober.lua +++ /dev/null @@ -1,207 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", "i386") - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, cross, names, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- done - local toolpath = nil - local toolchains = configs.get("toolchains") - for _, name in ipairs(utils.wrap(names)) do - - -- attempt to get it from the given cross toolchains - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to run it directly - if not toolpath then - toolpath = tools.probe(cross .. name) - end - - -- probe ok? - if toolpath then - - -- update config - configs.set(kind, toolpath) - - -- end - break - end - - end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- init the default cross from the current host and architecture - local cross = "" - local arch = configs.get("arch") - if arch then - if xmake._HOST == "macosx" and arch == "i386" then - cross = "i386-mingw32-" - elseif arch == "i386" then - cross = "i686-w64-mingw32-" - elseif arch == "x86_64" then - cross = "x86_64-w64-mingw32-" - end - end - - -- done - if not prober._probe_toolpath(configs, "cc", cross, "gcc", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", cross, {"g++", "gcc"}, "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", cross, "gcc", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", cross, {"g++", "gcc"}, "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", cross, "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", cross, {"g++", "gcc"}, "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", cross, "swiftc", "the swift compiler") then return false end - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_make - , prober._probe_ccache - , prober._probe_toolchains} - , nil - , config) -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_make - , prober._probe_ccache} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/platform.lua b/xmake/scripts/platform/platform.lua deleted file mode 100644 index 38d482f44..000000000 --- a/xmake/scripts/platform/platform.lua +++ /dev/null @@ -1,385 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file platform.lua --- - --- define module: platform -local platform = platform or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local config = require("base/config") -local global = require("base/global") - --- load prober the given platform directory -function platform._load_prober(root) - - -- the platform file path - local filepath = string.format("%s/prober.lua", root) - if os.isfile(filepath) then - - -- load script - local script = loadfile(filepath) - if script then - - -- load prober - local prober = script() - if prober then - - -- ok - return prober - end - end - end -end - --- load the given platform from the given root directory -function platform._load_from(root, plat) - - -- the platform file path - local filepath = string.format("%s/platform/%s/%s.lua", root, plat, plat) - if os.isfile(filepath) then - - -- load script - local script = loadfile(filepath) - if script then - - -- load module - local module = script() - if module then - - -- save directory - module._DIRECTORY = path.directory(filepath) - assert(module._DIRECTORY) - - -- attempt to load prober - module._PROBER = platform._load_prober(module._DIRECTORY) - - -- ok - return module - end - end - end -end - --- load the given platform -function platform._load(plat) - - -- the module - platform._MODULES = platform._MODULES or {} - local module = platform._MODULES[plat] - - -- return it directory if ok - if module then return module end - - -- attempt to load it from the project configure directory - if not module then module = platform._load_from(config.directory(), plat) end - - -- attempt to load it from the global configure directory - if not module then module = platform._load_from(global.directory(), plat) end - - -- attempt to load it from the script directory - if not module then module = platform._load_from(xmake._SCRIPTS_DIR, plat) end - - -- cache it if ok - if module then - platform._MODULES[plat] = module - end - - -- ok? - return module -end - --- get the configure of the given platform -function platform._configs(plat) - - -- the configure - platform._CONFIGS = platform._CONFIGS or {} - local configs = platform._CONFIGS[plat] - - -- return it directly if exists - if configs then - return configs - end - - -- load platform - local module = platform._load(plat) - if module then - - -- init configure - platform._CONFIGS[plat]= {} - configs = platform._CONFIGS[plat] - - -- make configure - module.make(configs) - end - - -- ok? - return configs -end - --- get the current platform module -function platform.module() - - -- load it - return platform._load(config.get("plat")) -end - --- get the current platform module directory -function platform.directory() - - -- load it - local module = platform.module() - if module then - return module._DIRECTORY - end -end - --- make the current platform configure -function platform.make() - - -- get the platform - local plat = config.get("plat") - assert(plat) - - -- make and get the current platform configure - return platform._configs(plat) -end - --- get the platform os -function platform.os() - - -- get module - local module = platform.module() - if not module then return end - - -- ok? - return module._OS -end - --- get the given configure -function platform.get(name) - - -- check - assert(platform._CONFIGS) - - -- get the current platform configure - local configs = platform._configs(config.get("plat")) - if configs then - -- get it - return configs[name] - end -end - --- get the given tool -function platform.tool(name) - - -- check - assert(name) - - -- get tools - local tools = platform.get("tools") - if tools then - return tools[name] - end - -end - --- get the given format -function platform.format(kind) - - -- check - assert(kind) - - -- get formats - local formats = platform.get("formats") - if formats then - return formats[kind] - end - -end - --- dump the platform configure -function platform.dump() - - -- check - assert(platform._CONFIGS) - - -- dump - if xmake._OPTIONS.verbose then - utils.dump(platform._configs(config.get("plat"))) - end - -end - --- list all platforms -function platform.plats() - - -- return it directly if exists - if platform._PLATS then - return platform._PLATS - end - - -- make list - local list = {} - - -- get the platform list from the project configure directory - local plats = os.match(config.directory() .. "/platform/*", true) - if plats then - for _, v in ipairs(plats) do - table.insert(list, path.basename(v)) - end - end - - -- get the platform list from the global configure directory - plats = os.match(global.directory() .. "/platform/*", true) - if plats then - for _, v in ipairs(plats) do - table.insert(list, path.basename(v)) - end - end - - -- get the platform list from the script directory - plats = os.match(xmake._SCRIPTS_DIR .. "/platform/*", true) - if plats then - for _, v in ipairs(plats) do - table.insert(list, path.basename(v)) - end - end - - -- save it - platform._PLATS = list - - -- ok - return list -end - --- list all architectures -function platform.archs(plat) - - -- check - assert(plat) - - -- load all platform configs - local archs = {} - local module = platform._load(plat) - if module and module._ARCHS then - for _, arch in ipairs(module._ARCHS) do - table.insert(archs, arch) - end - end - - -- ok - return archs -end - --- get the option menu for action: xmake config or global -function platform.menu(action) - - -- check - assert(action) - - -- get all platforms - local plats = platform.plats() - assert(plats) - - -- load and merge all platform menus - local menus = {} - local exist = {} - for _, plat in ipairs(plats) do - - -- load platform - local module = platform._load(plat) - if module and module.menu then - - -- get the platform menu - local menu = module.menu(action) - if menu then - - -- exists options? - local exists = false - for _, option in ipairs(menu) do - local name = option[2] - if name and not exist[name] then - exists = true - break - end - end - - -- merge it and remove repeat if exists options - if exists then - -- get the platform menu option - for _, option in ipairs(menu) do - - -- merge it and remove repeat - local name = option[2] - if name then - if not exist[name] then - table.insert(menus, option) - exist[name] = true - end - else - table.insert(menus, option) - end - end - end - end - end - end - - -- get all platform menus - return menus -end - --- probe the platform configure -function platform.probe(is_global) - - -- probe global - if is_global then - - -- get all platforms - local plats = platform.plats() - assert(plats) - - -- probe all platforms with the current host - for _, plat in ipairs(plats) do - local module = platform._load(plat) - if module and module._PROBER and module._PROBER.global and module._HOST and module._HOST == xmake._HOST then - if not module._PROBER.global() then return false end - end - end - - -- probe config - else - -- probe it - local module = platform.module() - if module and module._PROBER and module._PROBER.config then - if not module._PROBER.config() then return false end - end - end - - -- ok - return true -end - --- return module: platform -return platform diff --git a/xmake/scripts/platform/watchos/package.lua b/xmake/scripts/platform/watchos/package.lua deleted file mode 100644 index 1e46ddadc..000000000 --- a/xmake/scripts/platform/watchos/package.lua +++ /dev/null @@ -1,76 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file package.lua --- - --- define module: package -local package = package or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local rule = require("base/rule") -local utils = require("base/utils") -local string = require("base/string") -local platform = require("platform/platform") - --- package target -function package.main(target) - - -- check - assert(target and target.name) - - -- the count of architectures - local count = 0 - for _, _ in pairs(target.archs) do count = count + 1 end - if count < 2 then return 0 end - - -- get the lipo tool - local lipo = platform.tool("lipo") - if not lipo then return 0 end - - -- make universal info - local universal = {} - universal.targetdir = rule.backupdir(target.name, "universal") - universal.targetfile = rule.targetfile(target.name, target) - if not universal.targetdir or not universal.targetfile then return 0 end - - -- make the universal directory - os.mkdir(path.directory(string.format("%s/%s", universal.targetdir, universal.targetfile))) - - -- make the lipo command - local cmd = lipo .. " -create" - for arch, info in pairs(target.archs) do - cmd = string.format("%s -arch %s %s/%s", cmd, arch, info.targetdir, info.targetfile) - end - cmd = string.format("%s -output %s/%s", cmd, universal.targetdir, universal.targetfile) - - -- make the universal target - if 0 ~= os.execute(cmd) then return 0 end - - -- ok - target.archs.universal = universal - - -- continue - return 0 -end - --- return module: package -return package diff --git a/xmake/scripts/platform/watchos/prober.lua b/xmake/scripts/platform/watchos/prober.lua deleted file mode 100644 index 7b393f925..000000000 --- a/xmake/scripts/platform/watchos/prober.lua +++ /dev/null @@ -1,310 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", "armv7") - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the xcode application directory -function prober._probe_xcode(configs) - - -- get the xcode directory - local xcode_dir = configs.get("xcode_dir") - - -- ok? - if xcode_dir then return true end - - -- clear it first - xcode_dir = nil - - -- attempt to get the default directory - if not xcode_dir then - if os.isdir("/Applications/Xcode.app") then - xcode_dir = "/Applications/Xcode.app" - end - end - - -- attempt to match the other directories - if not xcode_dir then - local dirs = os.match("/Applications/Xcode*.app", true) - if dirs and table.getn(dirs) ~= 0 then - xcode_dir = dirs[1] - end - end - - -- probe ok? update it - if xcode_dir then - -- save it - configs.set("xcode_dir", xcode_dir) - - -- trace - utils.printf("checking for the Xcode application directory ... %s", xcode_dir) - else - -- failed - utils.error("checking for the Xcode application directory ... no") - utils.error(" - xmake config --xcode_dir=xxx") - utils.error("or - xmake global --xcode_dir=xxx") - return false - end - - -- ok - return true -end - --- probe the xcode sdk version -function prober._probe_xcode_sdkver(configs) - - -- get the xcode sdk version - local xcode_sdkver = configs.get("xcode_sdkver") - - -- ok? - if xcode_sdkver then return true end - - -- clear it first - xcode_sdkver = nil - - -- attempt to match the directory - if not xcode_sdkver then - local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS*.sdk", true) - if dirs then - for _, dir in ipairs(dirs) do - xcode_sdkver = string.match(dir, "%d+%.%d+") - if xcode_sdkver then break end - end - end - end - - -- probe ok? update it - if xcode_sdkver then - - -- save it - configs.set("xcode_sdkver", xcode_sdkver) - - -- trace - utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) - else - -- failed - utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) - utils.error(" - xmake config --xcode_sdkver=xxx") - utils.error("or - xmake global --xcode_sdkver=xxx") - return false - end - - -- ok - return true -end - --- probe the target minimal version -function prober._probe_target_minver(configs) - - -- get the target minimal version - local target_minver = configs.get("target_minver") - - -- ok? - if target_minver then return true end - - -- init the default target minimal version - configs.set("target_minver", "7.0") - - -- trace - utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, cross, names, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- done - local toolpath = nil - local toolchains = configs.get("toolchains") - for _, name in ipairs(utils.wrap(names)) do - - -- attempt to get it from the given cross toolchains - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to run it directly - if not toolpath then - toolpath = tools.probe(cross .. name) - end - - -- probe ok? - if toolpath then - - -- update config - configs.set(kind, toolpath) - - -- end - break - end - - end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- done - if not prober._probe_toolpath(configs, "cc", "xcrun -sdk watchos ", "clang", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk watchos ", {"clang++", "clang"}, "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "mm", "xcrun -sdk watchos ", "clang", "the objc compiler") then return false end - if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk watchos ", {"clang++", "clang"}, "the objc++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", xmake._SCRIPTS_DIR .. "/tools/gas-preprocessor.pl xcrun -sdk watchos ", "clang", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", "xcrun -sdk watchos ", {"clang++", "clang"}, "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", "xcrun -sdk watchos ", "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", "xcrun -sdk watchos ", {"clang++", "clang"}, "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", "xcrun -sdk watchos ", "swiftc", "the swift compiler") then return false end - if not prober._probe_toolpath(configs, "lipo", "xcrun -sdk watchos ", "lipo", "the universal files creater") then return false end - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_xcode - , prober._probe_xcode_sdkver - , prober._probe_target_minver - , prober._probe_make - , prober._probe_ccache - , prober._probe_toolchains} - , nil - , config) - -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_xcode - , prober._probe_make - , prober._probe_ccache} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/watchos/watchos.lua b/xmake/scripts/platform/watchos/watchos.lua deleted file mode 100644 index 9551084f8..000000000 --- a/xmake/scripts/platform/watchos/watchos.lua +++ /dev/null @@ -1,141 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file watchos.lua --- - --- define module: watchos -local watchos = watchos or {} - --- load modules -local config = require("base/config") - --- init host -watchos._HOST = "macosx" - --- init os -watchos._OS = "ios" - --- init architectures -watchos._ARCHS = {"armv7", "armv7s", "arm64"} - --- make configure -function watchos.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".dylib"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.mm = config.get("mm") - configs.tools.mxx = config.get("mxx") - configs.tools.as = config.get("as") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - configs.tools.lipo = config.get("lipo") - - -- init target minimal version - local target_minver = config.get("target_minver") - assert(target_minver) - - -- init flags for architecture - local archflags = nil - local arch = config.get("arch") - if arch then archflags = "-arch " .. arch end - configs.cxflags = { archflags, "-mwatchos-version-min=" .. target_minver } - configs.mxflags = { archflags, "-mwatchos-version-min=" .. target_minver } - configs.asflags = { archflags, "-mwatchos-version-min=" .. target_minver } - configs.ldflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-mwatchos-version-min=" .. target_minver } - configs.shflags = { archflags, "-ObjC", "-lstdc++", "-fobjc-link-runtime", "-mwatchos-version-min=" .. target_minver } - if arch then - configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } - end - - -- init flags for the xcode sdk directory - local xcode_dir = config.get("xcode_dir") - local xcode_sdkver = config.get("xcode_sdkver") - if xcode_dir and xcode_sdkver then - - -- init flags - local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS" .. xcode_sdkver .. ".sdk" - table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) - - -- save swift link directory - config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/watchos") - end - -end - --- get the option menu for action: xmake config or global -function watchos.menu(action) - - -- init config option menu - watchos._MENU_CONFIG = watchos._MENU_CONFIG or - { {} - , {nil, "mm", "kv", nil, "The Objc Compiler" } - , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } - , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } - , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } - , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } - , {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } - , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- init global option menu - watchos._MENU_GLOBAL = watchos._MENU_GLOBAL or - { {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- get the option menu - if action == "config" then - return watchos._MENU_CONFIG - elseif action == "global" then - return watchos._MENU_GLOBAL - end -end - - --- return module: watchos -return watchos diff --git a/xmake/scripts/platform/watchsimulator/prober.lua b/xmake/scripts/platform/watchsimulator/prober.lua deleted file mode 100644 index d33059c36..000000000 --- a/xmake/scripts/platform/watchsimulator/prober.lua +++ /dev/null @@ -1,308 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") -local config = require("base/config") -local global = require("base/global") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", "x86_64") - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the xcode application directory -function prober._probe_xcode(configs) - - -- get the xcode directory - local xcode_dir = configs.get("xcode_dir") - - -- ok? - if xcode_dir then return true end - - -- clear it first - xcode_dir = nil - - -- attempt to get the default directory - if not xcode_dir then - if os.isdir("/Applications/Xcode.app") then - xcode_dir = "/Applications/Xcode.app" - end - end - - -- attempt to match the other directories - if not xcode_dir then - local dirs = os.match("/Applications/Xcode*.app", true) - if dirs and table.getn(dirs) ~= 0 then - xcode_dir = dirs[1] - end - end - - -- probe ok? update it - if xcode_dir then - -- save it - configs.set("xcode_dir", xcode_dir) - - -- trace - utils.printf("checking for the Xcode application directory ... %s", xcode_dir) - else - -- failed - utils.error("checking for the Xcode application directory ... no") - utils.error(" - xmake config --xcode_dir=xxx") - utils.error("or - xmake global --xcode_dir=xxx") - return false - end - - -- ok - return true -end - --- probe the xcode sdk version -function prober._probe_xcode_sdkver(configs) - - -- get the xcode sdk version - local xcode_sdkver = configs.get("xcode_sdkver") - - -- ok? - if xcode_sdkver then return true end - - -- clear it first - xcode_sdkver = nil - - -- attempt to match the directory - if not xcode_sdkver then - local dirs = os.match(configs.get("xcode_dir") .. "/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator*.sdk", true) - if dirs then - for _, dir in ipairs(dirs) do - xcode_sdkver = string.match(dir, "%d+%.%d+") - if xcode_sdkver then break end - end - end - end - - -- probe ok? update it - if xcode_sdkver then - - -- save it - configs.set("xcode_sdkver", xcode_sdkver) - - -- trace - utils.printf("checking for the Xcode SDK version for %s ... %s", configs.get("plat"), xcode_sdkver) - else - -- failed - utils.error("checking for the Xcode SDK version for %s ... no", configs.get("plat")) - utils.error(" - xmake config --xcode_sdkver=xxx") - utils.error("or - xmake global --xcode_sdkver=xxx") - return false - end - - -- ok - return true -end - --- probe the target minimal version -function prober._probe_target_minver(configs) - - -- get the target minimal version - local target_minver = configs.get("target_minver") - - -- ok? - if target_minver then return true end - - -- init the default target minimal version - configs.set("target_minver", "7.0") - - -- trace - utils.printf("checking for the target minimal version ... %s", configs.get("target_minver")) - - -- ok - return true -end - --- probe the make -function prober._probe_make(configs) - - -- ok? - local make = configs.get("make") - if make then return true end - - -- probe the make path - make = tools.probe("make", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if make then configs.set("make", make) end - - -- trace - utils.printf("checking for the make ... %s", utils.ifelse(make, make, "no")) - - -- ok - return true -end - --- probe the ccache -function prober._probe_ccache(configs) - - -- ok? - local ccache_enable = configs.get("ccache") - if ccache_enable and configs.get("__ccache") then return true end - - -- disable? - if type(ccache_enable) == "boolean" and not ccache_enable then - configs.set("__ccache", nil) - return true - end - - -- probe the ccache path - local ccache_path = tools.probe("ccache", {"/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin"}) - - -- probe ok? update it - if ccache_path then - configs.set("ccache", true) - configs.set("__ccache", ccache_path) - else - configs.set("ccache", false) - end - - -- trace - utils.printf("checking for the ccache ... %s", utils.ifelse(ccache_path, ccache_path, "no")) - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, cross, names, description) - - -- check - assert(kind) - - -- get the cross - cross = configs.get("cross") or cross - - -- done - local toolpath = nil - local toolchains = configs.get("toolchains") - for _, name in ipairs(utils.wrap(names)) do - - -- attempt to get it from the given cross toolchains - if toolchains then - toolpath = tools.probe(cross .. (configs.get(kind) or name), toolchains) - end - - -- attempt to get it directly from the configure - if not toolpath then - toolpath = configs.get(kind) - end - - -- attempt to run it directly - if not toolpath then - toolpath = tools.probe(cross .. name) - end - - -- probe ok? - if toolpath then - - -- update config - configs.set(kind, toolpath) - - -- end - break - end - - end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- done - if not prober._probe_toolpath(configs, "cc", "xcrun -sdk watchsimulator ", "clang", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "mm", "xcrun -sdk watchsimulator ", "clang", "the objc compiler") then return false end - if not prober._probe_toolpath(configs, "mxx", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the objc++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", "xcrun -sdk watchsimulator ", "clang", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", "xcrun -sdk watchsimulator ", "ar", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", "xcrun -sdk watchsimulator ", {"clang++", "clang"}, "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "sc", "xcrun -sdk watchsimulator ", "swiftc", "the swift compiler") then return false end - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_xcode - , prober._probe_xcode_sdkver - , prober._probe_target_minver - , prober._probe_make - , prober._probe_ccache - , prober._probe_toolchains} - , nil - , config) -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_xcode - , prober._probe_make - , prober._probe_ccache} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/watchsimulator/watchsimulator.lua b/xmake/scripts/platform/watchsimulator/watchsimulator.lua deleted file mode 100644 index a13bfde1e..000000000 --- a/xmake/scripts/platform/watchsimulator/watchsimulator.lua +++ /dev/null @@ -1,138 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file watchsimulator.lua --- - --- define module: watchsimulator -local watchsimulator = watchsimulator or {} - --- load modules -local config = require("base/config") - --- init host -watchsimulator._HOST = "macosx" - --- init os -watchsimulator._OS = "ios" - --- init architectures -watchsimulator._ARCHS = {"i386", "x86_64"} - --- make configure -function watchsimulator.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"lib", ".a"} - configs.formats.object = {"", ".o"} - configs.formats.shared = {"lib", ".dylib"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.ccache = config.get("__ccache") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.mm = config.get("mm") - configs.tools.mxx = config.get("mxx") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.ex = config.get("ar") - configs.tools.sc = config.get("sc") - - -- init target minimal version - local target_minver = config.get("target_minver") - assert(target_minver) - - -- init flags for architecture - local archflags = nil - local arch = config.get("arch") - if arch then archflags = "-arch " .. arch end - configs.cxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } - configs.mxflags = { archflags, "-mios-simulator-version-min=" .. target_minver } - configs.asflags = { archflags, "-mios-simulator-version-min=" .. target_minver } - configs.ldflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } - configs.shflags = { archflags, "-Xlinker -objc_abi_version", "-Xlinker 2 -stdlib=libc++", "-Xlinker -no_implicit_dylibs", "-fobjc-link-runtime", "-mios-simulator-version-min=" .. target_minver } - if arch then - configs.scflags = { string.format("-target %s-apple-ios%s", arch, target_minver) } - end - - -- init flags for the xcode sdk directory - local xcode_dir = config.get("xcode_dir") - local xcode_sdkver = config.get("xcode_sdkver") - if xcode_dir and xcode_sdkver then - - -- init flags - local xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/WatchSimulator.platform/Developer/SDKs/WatchSimulator" .. xcode_sdkver .. ".sdk" - table.insert(configs.cxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.asflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.mxflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.ldflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.shflags, "-isysroot " .. xcode_sdkdir) - table.insert(configs.scflags, "-sdk " .. xcode_sdkdir) - - -- save swift link directory - config.set("__swift_linkdirs", xcode_dir .. "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/watchsimulator") - end -end - --- get the option menu for action: xmake config or global -function watchsimulator.menu(action) - - -- init config option menu - watchsimulator._MENU_CONFIG = watchsimulator._MENU_CONFIG or - { {} - , {nil, "mm", "kv", nil, "The Objc Compiler" } - , {nil, "mxx", "kv", nil, "The Objc++ Compiler" } - , {nil, "mflags", "kv", nil, "The Objc Compiler Flags" } - , {nil, "mxflags", "kv", nil, "The Objc/c++ Compiler Flags" } - , {nil, "mxxflags", "kv", nil, "The Objc++ Compiler Flags" } - , {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {nil, "xcode_sdkver", "kv", "auto", "The SDK Version for Xcode" } - , {nil, "target_minver", "kv", "auto", "The Target Minimal Version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- init global option menu - watchsimulator._MENU_GLOBAL = watchsimulator._MENU_GLOBAL or - { {} - , {nil, "xcode_dir", "kv", "auto", "The Xcode Application Directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - , } - - -- get the option menu - if action == "config" then - return watchsimulator._MENU_CONFIG - elseif action == "global" then - return watchsimulator._MENU_GLOBAL - end -end - - --- return module: watchsimulator -return watchsimulator diff --git a/xmake/scripts/platform/windows/prober.lua b/xmake/scripts/platform/windows/prober.lua deleted file mode 100644 index 40d214efd..000000000 --- a/xmake/scripts/platform/windows/prober.lua +++ /dev/null @@ -1,300 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local io = require("base/io") -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") -local global = require("base/global") -local tools = require("tools/tools") -local platform = require("platform/platform") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.get("arch") - - -- ok? - if arch then return true end - - -- init the default architecture - configs.set("arch", "x86") - - -- trace - utils.printf("checking for the architecture ... %s", configs.get("arch")) - - -- ok - return true -end - --- probe the vs version -function prober._probe_vs_version(configs) - - -- get the vs version - local vs = configs.get("vs") - - -- ok? - if vs then return true end - - -- clear it first - vs = nil - - -- make the map table - local map = - { - VS140COMNTOOLS = "2015" - , VS120COMNTOOLS = "2013" - , VS110COMNTOOLS = "2012" - , VS100COMNTOOLS = "2010" - , VS90COMNTOOLS = "2008" - , VS80COMNTOOLS = "2005" - , VS71COMNTOOLS = "2003" - , VS70COMNTOOLS = "7.0" - , VS60COMNTOOLS = "6.0" - , VS50COMNTOOLS = "5.0" - , VS42COMNTOOLS = "4.2" - } - - -- attempt to get it from the envirnoment variable - if not vs then - for k, v in pairs(map) do - if os.getenv(k) then - vs = v - break - end - end - end - - -- probe ok? update it - if vs then - -- save it - configs.set("vs", vs) - - -- trace - utils.printf("checking for the Microsoft Visual Studio version ... %s", vs) - else - -- failed - utils.error("checking for the Microsoft Visual Studio version ... no") - utils.error(" - xmake config --vs=xxx") - utils.error("or - xmake global --vs=xxx") - return false - end - - -- ok - return true -end - --- probe the vs path -function prober._probe_vs_path(configs) - - -- ok? - if configs.get("__vsenv_path") then return true end - - -- get the vs version - local vs = configs.get("vs") - assert(vs) - - -- make the map table - local map = - { - ["2015"] = "VS140COMNTOOLS" - , ["2013"] = "VS120COMNTOOLS" - , ["2012"] = "VS110COMNTOOLS" - , ["2010"] = "VS100COMNTOOLS" - , ["2008"] = "VS90COMNTOOLS" - , ["2005"] = "VS80COMNTOOLS" - , ["2003"] = "VS71COMNTOOLS" - , ["7.0"] = "VS70COMNTOOLS" - , ["6.0"] = "VS60COMNTOOLS" - , ["5.0"] = "VS50COMNTOOLS" - , ["4.2"] = "VS42COMNTOOLS" - } - - -- attempt to get the vs directory from the envirnoment variable - local vsdir = map[vs] - if vsdir then - vsdir = os.getenv(vsdir) - end - if vsdir then - vsdir = vsdir .. "\\..\\.." - end - if not os.isdir(vsdir) then - -- error - utils.error("not found %s", vsdir) - return false - end - - -- the vcvarsall.bat path - local vcvarsall = vsdir .. "\\VC\\vcvarsall.bat" - if not os.isfile(vcvarsall) then - -- error - utils.error("not found %s", vcvarsall) - return false - end - - -- get the temporary directory - local tmpdir = os.tmpdir() - assert(tmpdir) - - -- make the call(vcvarsall.bat) file - local callpath = tmpdir .. "\\call_vcvarsall.bat" - local callfile = io.openmk(callpath) - assert(callfile) - - -- make call scripts - callfile:write("@echo off\n") - callfile:write(string.format("call \"%s\" %s > nul\n", vcvarsall, configs.get("arch"))) - callfile:write("echo return \n") - callfile:write("echo { \n") - callfile:write("echo path = \"%path%\"\n") - callfile:write("echo , lib = \"%lib%\"\n") - callfile:write("echo , libpath = \"%libpath%\"\n") - callfile:write("echo , include = \"%include%\"\n") - callfile:write("echo , devenvdir = \"%devenvdir%\"\n") - callfile:write("echo , vsinstalldir = \"%vsinstalldir%\"\n") - callfile:write("echo , vcinstalldir = \"%vcinstalldir%\"\n") - callfile:write("echo } \n") - - -- close the file - callfile:close() - - -- execute the call(vsvars32.bat) file and get all envirnoment variables - local cmd = io.popen(callpath) - local results = cmd:read("*all") - cmd:close() - - -- translate '\' => '\\' - results = results:gsub("\\", "\\\\") - - -- get all envirnoment variables - local variables = assert(loadstring(results))() - if not variables or not variables.path then - return false - end - - -- save the variables - for k, v in pairs(variables) do - configs.set("__vsenv_" .. k, v) - end - - -- ok - return true -end - --- probe the tool path -function prober._probe_toolpath(configs, kind, name, description) - - -- check - assert(kind) - - -- attempt to get it directly from the configure - local toolpath = configs.get(kind) - if toolpath then return true end - - -- make cmd - local cmd = string.format("%s > %s 2>&1", name, xmake._NULDEV) - if kind == "ld" then - cmd = string.format("%s nul > %s 2>&1", name, xmake._NULDEV) - end - - -- attempt to run it directly first - if not toolpath and os.execute(cmd) ~= 1 then - toolpath = name - end - - -- probe ok? update it - if toolpath then configs.set(kind, toolpath) end - - -- trace - if toolpath then - utils.printf("checking for %s (%s) ... %s", description, kind, path.filename(toolpath)) - else - utils.printf("checking for %s (%s) ... no", description, kind) - end - - -- failed? - if not toolpath and (kind == "cc" or kind == "ld" or kind == "make") then - return false - end - - -- ok - return true -end - --- probe the toolchains -function prober._probe_toolchains(configs) - - -- the windows module - local windows = platform.module() - assert(windows) - - -- enter envirnoment - windows.enter() - - -- done - if not prober._probe_toolpath(configs, "cc", "cl.exe", "the c compiler") then return false end - if not prober._probe_toolpath(configs, "cxx", "cl.exe", "the c++ compiler") then return false end - if not prober._probe_toolpath(configs, "as", "ml.exe", "the assember") then return false end - if not prober._probe_toolpath(configs, "ld", "link.exe", "the linker") then return false end - if not prober._probe_toolpath(configs, "ar", "link.exe -lib", "the static library linker") then return false end - if not prober._probe_toolpath(configs, "sh", "link.exe -dll", "the shared library linker") then return false end - if not prober._probe_toolpath(configs, "ex", "lib.exe", "the library extractor") then return false end - if not prober._probe_toolpath(configs, "make", "nmake.exe", "the make") then return false end - - -- leave envirnoment - windows.leave() - - -- ok - return true -end - --- probe the project configure -function prober.config() - - -- call all probe functions - return utils.call( { prober._probe_arch - , prober._probe_vs_version - , prober._probe_vs_path - , prober._probe_toolchains} - , nil - , config) -end - --- probe the global configure -function prober.global() - - -- call all probe functions - return utils.call( { prober._probe_vs_version - , prober._probe_vs_path} - , nil - , global) -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/windows/tools/cl.lua b/xmake/scripts/platform/windows/tools/cl.lua deleted file mode 100644 index 299960bb8..000000000 --- a/xmake/scripts/platform/windows/tools/cl.lua +++ /dev/null @@ -1,139 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file cl.lua --- - --- define module: cl -local cl = cl or {} - --- load modules -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") -local platform = require("platform/platform") - --- init the compiler -function cl.init(self, name) - - -- save name - self.name = name or "cl.exe" - - -- init cxflags - self.cxflags = { "-nologo", "-Gd", "-MP4", "-D_MBCS", "-D_CRT_SECURE_NO_WARNINGS"} - - -- init flags map - self.mapflags = - { - -- optimize - ["-O0"] = "-Od" - , ["-O3"] = "-Ot" - , ["-Ofast"] = "-Ox" - , ["-fomit-frame-pointer"] = "-Oy" - - -- symbols - , ["-g"] = "-Z7" - , ["-fvisibility=.*"] = "" - - -- warnings - , ["-Wall"] = "-W3" -- = "-Wall" will enable too more warnings - , ["-W1"] = "-W1" - , ["-W2"] = "-W2" - , ["-W3"] = "-W3" - , ["-Werror"] = "-WX" - , ["%-Wno%-error=.*"] = "" - , ["%-fno%-.*"] = "" - - -- vectorexts - , ["-mmmx"] = "-arch:MMX" - , ["-msse"] = "-arch:SSE" - , ["-msse2"] = "-arch:SSE2" - , ["-msse3"] = "-arch:SSE3" - , ["-mssse3"] = "-arch:SSSE3" - , ["-mavx"] = "-arch:AVX" - , ["-mavx2"] = "-arch:AVX2" - , ["-mfpu=.*"] = "" - - -- language - , ["-ansi"] = "" - , ["-std=c99"] = "-TP" -- compile as c++ files because msvc only support c89 - , ["-std=gnu99"] = "-TP" -- compile as c++ files because msvc only support c89 - , ["-std=.*"] = "" - - -- others - , ["-ftrapv"] = "" - , ["-fsanitize=address"] = "" - } - -end - --- make the compiler command -function cl.command_compile(self, srcfile, objfile, flags, logfile) - - -- redirect - local redirect = "" - if logfile then redirect = string.format(" > %s 2>&1", logfile) end - - -- make it - return string.format("%s -c %s -Fo%s %s%s", self.name, flags, objfile, srcfile, redirect) -end - --- make the define flag -function cl.flag_define(self, define) - - -- make it - return "-D" .. define:gsub("\"", "\\\"") -end - --- make the undefine flag -function cl.flag_undefine(self, undefine) - - -- make it - return "-U" .. undefine -end - --- make the includedir flag -function cl.flag_includedir(self, includedir) - - -- make it - return "-I" .. includedir -end - --- the main function -function cl.main(self, cmd) - - -- the windows module - local windows = platform.module() - assert(windows) - - -- enter envirnoment - windows.enter() - - -- execute it - local ok = os.execute(cmd) - - -- leave envirnoment - windows.leave() - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: cl -return cl diff --git a/xmake/scripts/platform/windows/tools/lib.lua b/xmake/scripts/platform/windows/tools/lib.lua deleted file mode 100644 index 1d94152cc..000000000 --- a/xmake/scripts/platform/windows/tools/lib.lua +++ /dev/null @@ -1,138 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file lib.lua --- - --- define module: lib -local lib = lib or {} - --- load modules -local io = require("base/io") -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") -local platform = require("platform/platform") - --- init the compiler -function lib.init(self, name) - - -- save name - self.name = name or "lib.exe" - -end - --- extract the static library to object files -function lib.extract(self, ...) - - -- check - local args = ... - assert(#args == 2 and self.name) - - -- get library and object file path - local libfile = args[1] - local objfile = args[2] - assert(libfile and objfile) - - -- get object directory - local objdir = path.directory(objfile) - if not os.isdir(objdir) then os.mkdir(objdir) end - if not os.isdir(objdir) then - utils.error("%s not found!", objdir) - return false - end - - -- the windows module - local windows = platform.module() - assert(windows) - - -- enter envirnoment - windows.enter() - - -- list object files - local file = io.popen(string.format("%s -nologo -list %s", self.name, libfile)) - if not file then - utils.error("extract %s to %s failed!", libfile, objdir) - windows.leave() - return false - end - - -- extrace all object files - for line in file:lines() do - - -- is object file? - if line:find("%.obj") then - - -- init command - local out = path.translate(string.format("%s\\%s", objdir, path.filename(line))) - - -- repeat? rename it - if os.isfile(out) then - for i = 0, 10 do - out = path.translate(string.format("%s\\%d_%s", objdir, i, path.filename(line))) - if not os.isfile(out) then break end - end - end - - -- init command - local cmd = string.format("%s -nologo -extract:%s -out:%s %s", self.name, line, out, libfile) - - -- extract it - if 0 ~= os.execute(cmd) then - utils.error("extract %s to %s failed!", libfile, objdir) - windows.leave() - return false - end - end - end - - -- exit file - file:close() - - -- leave envirnoment - windows.leave() - - -- ok - return true -end - --- the main function -function lib.main(self, cmd) - - -- the windows module - local windows = platform.module() - assert(windows) - - -- enter envirnoment - windows.enter() - - -- execute it - local ok = os.execute(cmd) - - -- leave envirnoment - windows.leave() - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: lib -return lib diff --git a/xmake/scripts/platform/windows/tools/link.lua b/xmake/scripts/platform/windows/tools/link.lua deleted file mode 100644 index 66476fa41..000000000 --- a/xmake/scripts/platform/windows/tools/link.lua +++ /dev/null @@ -1,128 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file link.lua --- - --- define module: link -local link = link or {} - --- load modules -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") -local platform = require("platform/platform") - --- init the compiler -function link.init(self, name) - - -- save name - self.name = name or "link.exe" - - -- the architecture - local arch = config.get("arch") - assert(arch) - - -- init flags for architecture - local flags_arch = "" - if arch == "x86" then flags_arch = "-machine:x86" - elseif arch == "x64" or arch == "amd64" or arch == "x86_amd64" then flags_arch = "-machine:x64" - end - - -- init ldflags - self.ldflags = { "-nologo" - , "-dynamicbase" - , "-nxcompat" - , flags_arch} - - -- init arflags - self.arflags = {"-nologo", flags_arch} - - -- init shflags - self.shflags = {"-nologo", flags_arch} - - -- init flags map - self.mapflags = - { - -- strip - ["-s"] = "" - , ["-S"] = "" - - -- others - , ["-ftrapv"] = "" - , ["-fsanitize=address"] = "" - } - -end - --- make the linker command -function link.command_link(self, objfiles, targetfile, flags, logfile) - - -- redirect - local redirect = "" - if logfile then redirect = string.format(" > %s 2>&1", logfile) end - - -- make it - local cmd = string.format("%s %s -out:%s %s%s", self.name, flags, targetfile, objfiles, redirect) - - -- too long? - if #cmd > 256 then - cmd = string.format("%s%s @<<\n%s -out:%s %s\n<<", self.name, redirect, flags, targetfile, objfiles) - end - - -- ok? - return cmd -end - --- make the link flag -function link.flag_link(self, link) - - -- make it - return link .. ".lib" -end - --- make the linkdir flag -function link.flag_linkdir(self, linkdir) - - -- make it - return "-libpath:" .. linkdir -end - --- the main function -function link.main(self, cmd) - - -- the windows module - local windows = platform.module() - assert(windows) - - -- enter envirnoment - windows.enter() - - -- execute it - local ok = os.execute(cmd) - - -- leave envirnoment - windows.leave() - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: link -return link diff --git a/xmake/scripts/platform/windows/tools/ml.lua b/xmake/scripts/platform/windows/tools/ml.lua deleted file mode 100644 index 5a6034320..000000000 --- a/xmake/scripts/platform/windows/tools/ml.lua +++ /dev/null @@ -1,132 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file ml.lua --- - --- define module: ml -local ml = ml or {} - --- load modules -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") -local platform = require("platform/platform") - --- init the compiler -function ml.init(self, name) - - -- save name - self.name = name or "ml.exe" - - -- init asflags - self.asflags = { "-nologo", "-Gd", "-MP4", "-D_MBCS", "-D_CRT_SECURE_NO_WARNINGS"} - - -- init flags map - self.mapflags = - { - -- optimize - ["-O0"] = "-Od" - , ["-O3"] = "-Ot" - , ["-Ofast"] = "-Ox" - , ["-fomit-frame-pointer"] = "-Oy" - - -- symbols - , ["-g"] = "-Z7" - , ["-fvisibility=.*"] = "" - - -- warnings - , ["-Wall"] = "-W3" -- = "-Wall" will enable too more warnings - , ["-W1"] = "-W1" - , ["-W2"] = "-W2" - , ["-W3"] = "-W3" - , ["-Werror"] = "-WX" - , ["%-Wno%-error=.*"] = "" - - -- vectorexts - , ["-mmmx"] = "-arch:MMX" - , ["-msse"] = "-arch:SSE" - , ["-msse2"] = "-arch:SSE2" - , ["-msse3"] = "-arch:SSE3" - , ["-mssse3"] = "-arch:SSSE3" - , ["-mavx"] = "-arch:AVX" - , ["-mavx2"] = "-arch:AVX2" - , ["-mfpu=.*"] = "" - - -- others - , ["-ftrapv"] = "" - , ["-fsanitize=address"] = "" - } - -end - --- make the compiler command -function ml.command_compile(self, srcfile, objfile, flags, logfile) - - -- redirect - local redirect = "" - if logfile then redirect = string.format(" > %s 2>&1", logfile) end - - -- make it - return string.format("%s -c %s -Fo%s %s%s", self.name, flags, objfile, srcfile, redirect) -end - --- make the define flag -function ml.flag_define(self, define) - - -- make it - return "-D" .. define:gsub("\"", "\\\"") -end - --- make the undefine flag -function ml.flag_undefine(self, undefine) - - -- make it - return "-U" .. undefine -end - --- make the includedir flag -function ml.flag_includedir(self, includedir) - - -- make it - return "-I" .. includedir -end - --- the main function -function ml.main(self, cmd) - - -- the windows module - local windows = platform.module() - assert(windows) - - -- enter envirnoment - windows.enter() - - -- execute it - local ok = os.execute(cmd) - - -- leave envirnoment - windows.leave() - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: ml -return ml diff --git a/xmake/scripts/platform/windows/tools/nmake.lua b/xmake/scripts/platform/windows/tools/nmake.lua deleted file mode 100644 index 3dddc7cf2..000000000 --- a/xmake/scripts/platform/windows/tools/nmake.lua +++ /dev/null @@ -1,74 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file nmake.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") -local platform = require("platform/platform") - --- define module: nmake -local nmake = nmake or {} - --- the init function -function nmake.init(self, name) - - -- save name - self.name = name or "nmake.exe" - - -- is verbose? - self._VERBOSE = utils.ifelse(xmake._OPTIONS.verbose, "-v", "") - -end - --- the main function -function nmake.main(self, mkfile, target) - - -- the windows module - local windows = platform.module() - assert(windows) - - -- enter envirnoment - windows.enter() - - -- make command - local cmd = nil - if mkfile and os.isfile(mkfile) then - cmd = string.format("%s /nologo /f %s %s VERBOSE=%s", self.name, mkfile, target or "", self._VERBOSE) - else - cmd = string.format("%s /nologo %s VERBOSE=%s", self.name, target or "", self._VERBOSE) - end - - -- done - local ok = os.execute(cmd) - - -- leave envirnoment - windows.leave() - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: nmake -return nmake diff --git a/xmake/scripts/platform/windows/windows.lua b/xmake/scripts/platform/windows/windows.lua deleted file mode 100644 index 794358dc1..000000000 --- a/xmake/scripts/platform/windows/windows.lua +++ /dev/null @@ -1,144 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file windows.lua --- - --- define module: windows -local windows = windows or {} - --- load modules -local os = require("base/os") -local config = require("base/config") - --- init host -windows._HOST = "windows" - --- init os -windows._OS = "windows" - --- init architectures -windows._ARCHS = {"x86", "x64", "amd64", "x86_amd64"} - --- enter the given environment -function windows._enter(name) - - -- check - assert(name) - - -- get the pathes for the vs environment - local old = nil - local new = config.get("__vsenv_" .. name) - if new then - - -- get the current pathes - old = os.getenv(name) or "" - - -- append the current pathes - new = new .. ";" .. old - - -- update the pathes for the environment - os.setenv(name, new) - end - - -- return the previous environment - return old; -end - --- leave the given environment -function windows._leave(name, old) - - -- check - assert(name) - - -- restore the previous environment - if old then - os.setenv(name, old) - end -end - --- enter environment -function windows.enter() - - -- enter the vs environment - windows._pathes = windows._enter("path") - windows._libs = windows._enter("lib") - windows._includes = windows._enter("include") - windows._libpathes = windows._enter("libpath") - -end - --- leave environment -function windows.leave() - - -- leave the vs environment - windows._leave("path", windows._pathes) - windows._leave("lib", windows._libs) - windows._leave("include", windows._includes) - windows._leave("libpath", windows._libpathes) - -end --- make configure -function windows.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"", ".lib"} - configs.formats.object = {"", ".obj"} - configs.formats.shared = {"", ".dll"} - configs.formats.binary = {"", ".exe"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = config.get("make") - configs.tools.cc = config.get("cc") - configs.tools.cxx = config.get("cxx") - configs.tools.ld = config.get("ld") - configs.tools.ar = config.get("ar") - configs.tools.sh = config.get("sh") - configs.tools.as = config.get("as") - configs.tools.ex = config.get("ex") -end - --- get the option menu for action: xmake config or global -function windows.menu(action) - - -- init config option menu - windows._MENU_CONFIG = windows._MENU_CONFIG or - { {} - , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } - , } - - -- init global option menu - windows._MENU_GLOBAL = windows._MENU_GLOBAL or - { {} - , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } - , } - - -- get the option menu - if action == "config" then - return windows._MENU_CONFIG - elseif action == "global" then - return windows._MENU_GLOBAL - end -end - - --- return module: windows -return windows diff --git a/xmake/scripts/tools/ar.lua b/xmake/scripts/tools/ar.lua deleted file mode 100644 index 75e63f83d..000000000 --- a/xmake/scripts/tools/ar.lua +++ /dev/null @@ -1,114 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file ar.lua --- - --- define module: ar -local ar = ar or {} - --- load modules -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") - --- init the linker -function ar.init(self, name) - - -- save name - self.name = name or "ar" - - -- init arflags - self.arflags = { "-crs" } - -end - --- make the link command -function ar.command_link(self, objfiles, targetfile, flags, logfile) - - -- redirect - local redirect = "" - if logfile then redirect = string.format(" > %s 2>&1", logfile) end - - -- make it - return string.format("%s %s %s %s%s", self.name, flags, targetfile, objfiles, redirect) -end - --- extract the static library to object files -function ar.extract(self, ...) - - -- check - local args = ... - assert(#args == 2 and self.name) - - -- get library and object file path - local libfile = args[1] - local objfile = args[2] - assert(libfile and objfile) - - -- get object directory - local objdir = path.directory(objfile) - if not os.isdir(objdir) then os.mkdir(objdir) end - if not os.isdir(objdir) then - utils.error("%s not found!", objdir) - return false - end - - -- absolute the library path - libfile = path.absolute(libfile) - assert(libfile) - - -- enter the object directory - ok, errors = os.cd(objdir) - if not ok then - utils.error(errors) - return false - end - - -- extract it - local ok = self:main(string.format("%s -x %s", self.name, libfile)) - if not ok then - utils.error("extract %s to %s failed!", libfile, objdir) - return false - end - - -- leave the object directory - ok, errors = os.cd("-") - if not ok then - utils.error(errors) - return false - end - - -- ok - return true -end - - --- the main function -function ar.main(self, cmd) - - -- execute it - local ok = os.execute(cmd) - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: ar -return ar diff --git a/xmake/scripts/tools/cat.lua b/xmake/scripts/tools/cat.lua deleted file mode 100644 index 32fea4e24..000000000 --- a/xmake/scripts/tools/cat.lua +++ /dev/null @@ -1,43 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file cat.lua --- - --- define module: cat -local cat = cat or {} - --- load modules -local io = require("base/io") -local os = require("base/os") - --- the main function -function cat.main(self, ...) - - -- cat all - for _, v in ipairs(...) do - if os.isfile(v) then io.cat(v) end - end - - -- ok - return true -end - --- return module: cat -return cat diff --git a/xmake/scripts/tools/clang++.lua b/xmake/scripts/tools/clang++.lua deleted file mode 100644 index 37352dec4..000000000 --- a/xmake/scripts/tools/clang++.lua +++ /dev/null @@ -1,38 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file clang.lua --- - --- load modules -local gcc = require("tools/gcc") - --- define module: clang++ -local clangxx = clangxx or {} - --- only copy the interfaces of gcc to clang++ -for k, v in pairs(gcc) do - if type(v) == "function" then - clangxx[k] = v - end -end - --- return module: clang++ -return clangxx - diff --git a/xmake/scripts/tools/clang.lua b/xmake/scripts/tools/clang.lua deleted file mode 100644 index 280ae73a6..000000000 --- a/xmake/scripts/tools/clang.lua +++ /dev/null @@ -1,38 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file clang.lua --- - --- load modules -local gcc = require("tools/gcc") - --- define module: clang -local clang = clang or {} - --- only copy the interfaces of gcc to clang -for k, v in pairs(gcc) do - if type(v) == "function" then - clang[k] = v - end -end - --- return module: clang -return clang - diff --git a/xmake/scripts/tools/cp.lua b/xmake/scripts/tools/cp.lua deleted file mode 100644 index 1b3ba9843..000000000 --- a/xmake/scripts/tools/cp.lua +++ /dev/null @@ -1,44 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file cp.lua --- - --- define module: cp -local cp = cp or {} - --- load modules -local os = require("base/os") - --- the main function -function cp.main(self, ...) - - -- cp it - local pathes = ... - if pathes and table.getn(pathes) == 2 then - return os.cp(pathes[1], pathes[2]) - end - - -- failed - return false - -end - --- return module: cp -return cp diff --git a/xmake/scripts/tools/dispatcher.lua b/xmake/scripts/tools/dispatcher.lua deleted file mode 100644 index d019937ec..000000000 --- a/xmake/scripts/tools/dispatcher.lua +++ /dev/null @@ -1,80 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file dispatcher.lua --- - --- define module: dispatcher -local dispatcher = dispatcher or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local tools = require("tools/tools") - --- the main function --- --- dispatcher toolname toolpath action arguments ... -function dispatcher.main(self, ...) - - -- check - local args = ... - assert(#args >= 2) - - -- get tool kind and action name - local tool_kind = args[1] - local action_name = args[2] - assert(tool_kind and action_name) - - -- get the tool - local tool = tools.get(tool_kind) - if tool then - - -- load action - local action = tool[action_name] - if action then - - -- init arguments for action - local action_args = {} - for i = 3, #args do - table.insert(action_args, args[i]:decode()) - end - - -- done action - if not action(tool, action_args) then - utils.error("run action %s failed!", action_name) - assert(false) - end - else - utils.error("load action %s failed!", action_name) - assert(false) - end - - else - assert(false) - end - - -- ok - return true -end - --- return module: dispatcher -return dispatcher diff --git a/xmake/scripts/tools/echo.lua b/xmake/scripts/tools/echo.lua deleted file mode 100644 index dbfa67426..000000000 --- a/xmake/scripts/tools/echo.lua +++ /dev/null @@ -1,44 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file echo.lua --- - --- define module: echo -local echo = echo or {} - --- load modules -local io = require("base/io") -local string = require("base/string") - --- the main function -function echo.main(self, ...) - - -- echo all - for _, v in ipairs(...) do - io.write(string.format("%s ", v:decode())) - end - io.write("\n") - - -- ok - return true -end - --- return module: echo -return echo diff --git a/xmake/scripts/tools/g++.lua b/xmake/scripts/tools/g++.lua deleted file mode 100644 index 64970b039..000000000 --- a/xmake/scripts/tools/g++.lua +++ /dev/null @@ -1,38 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file g++.lua --- - --- load modules -local gcc = require("tools/gcc") - --- define module: gxx -local gxx = gxx or {} - --- only copy the interfaces of gcc to g++ -for k, v in pairs(gcc) do - if type(v) == "function" then - gxx[k] = v - end -end - --- return module: g++ -return gxx - diff --git a/xmake/scripts/tools/gas-preprocessor.pl b/xmake/scripts/tools/gas-preprocessor.pl deleted file mode 100755 index 98dfe4ad9..000000000 --- a/xmake/scripts/tools/gas-preprocessor.pl +++ /dev/null @@ -1,1025 +0,0 @@ -#!/usr/bin/env perl -# by David Conrad -# This code is licensed under GPLv2 or later; go to gnu.org to read it -# (not that it much matters for an asm preprocessor) -# usage: set your assembler to be something like "perl gas-preprocessor.pl gcc" -use strict; - -# Apple's gas is ancient and doesn't support modern preprocessing features like -# .rept and has ugly macro syntax, among other things. Thus, this script -# implements the subset of the gas preprocessor used by x264 and ffmpeg -# that isn't supported by Apple's gas. - -my %canonical_arch = ("aarch64" => "aarch64", "arm64" => "aarch64", - "arm" => "arm", - "powerpc" => "powerpc", "ppc" => "powerpc"); - -my %comments = ("aarch64" => '//', - "arm" => '@', - "powerpc" => '#'); - -my @gcc_cmd; -my @preprocess_c_cmd; - -my $comm; -my $arch; -my $as_type = "apple-gas"; - -my $fix_unreq = $^O eq "darwin"; -my $force_thumb = 0; - -my $arm_cond_codes = "eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo"; - -my $usage_str = " -$0\n -Gas-preprocessor.pl converts assembler files using modern GNU as syntax for -Apple's ancient gas version or clang's incompatible integrated assembler. The -conversion is regularly tested for Libav, x264 and vlc. Other projects might -use different features which are not correctly handled. - -Options for this program needs to be separated with ' -- ' from the assembler -command. Following options are currently supported: - - -help - this usage text - -arch - target architecture - -as-type - one value out of {{,apple-}{gas,clang},armasm} - -fix-unreq - -no-fix-unreq - -force-thumb - assemble as thumb regardless of the input source - (note, this is incomplete and only works for sources - it explicitly was tested with) -"; - -sub usage() { - print $usage_str; -} - -while (@ARGV) { - my $opt = shift; - - if ($opt =~ /^-(no-)?fix-unreq$/) { - $fix_unreq = $1 ne "no-"; - } elsif ($opt eq "-force-thumb") { - $force_thumb = 1; - } elsif ($opt eq "-arch") { - $arch = shift; - die "unknown arch: '$arch'\n" if not exists $comments{$arch}; - } elsif ($opt eq "-as-type") { - $as_type = shift; - die "unknown as type: '$as_type'\n" if $as_type !~ /^((apple-)?(gas|clang)|armasm)$/; - } elsif ($opt eq "-help") { - usage(); - exit 0; - } elsif ($opt eq "--" ) { - @gcc_cmd = @ARGV; - } elsif ($opt =~ /^-/) { - die "option '$opt' is not known. See '$0 -help' for usage information\n"; - } else { - push @gcc_cmd, $opt, @ARGV; - } - last if (@gcc_cmd); -} - -if (grep /\.c$/, @gcc_cmd) { - # C file (inline asm?) - compile - @preprocess_c_cmd = (@gcc_cmd, "-S"); -} elsif (grep /\.[sS]$/, @gcc_cmd) { - # asm file, just do C preprocessor - @preprocess_c_cmd = (@gcc_cmd, "-E"); -} elsif (grep /-(v|-version|dumpversion)/, @gcc_cmd) { - # pass -v/--version along, used during probing. Matching '-v' might have - # uninteded results but it doesn't matter much if gas-preprocessor or - # the compiler fails. - exec(@gcc_cmd); -} else { - die "Unrecognized input filetype"; -} -if ($as_type eq "armasm") { - - $preprocess_c_cmd[0] = "cpp"; - - @preprocess_c_cmd = grep ! /^-nologo$/, @preprocess_c_cmd; - # Remove -ignore XX parameter pairs from preprocess_c_cmd - my $index = 1; - while ($index < $#preprocess_c_cmd) { - if ($preprocess_c_cmd[$index] eq "-ignore" and $index + 1 < $#preprocess_c_cmd) { - splice(@preprocess_c_cmd, $index, 2); - next; - } - $index++; - } - if (grep /^-MM$/, @preprocess_c_cmd) { - system(@preprocess_c_cmd) == 0 or die "Error running preprocessor"; - exit 0; - } -} - -# if compiling, avoid creating an output file named '-.o' -if ((grep /^-c$/, @gcc_cmd) && !(grep /^-o/, @gcc_cmd)) { - foreach my $i (@gcc_cmd) { - if ($i =~ /\.[csS]$/) { - my $outputfile = $i; - $outputfile =~ s/\.[csS]$/.o/; - push(@gcc_cmd, "-o"); - push(@gcc_cmd, $outputfile); - last; - } - } -} -# replace only the '-o' argument with '-', avoids rewriting the make dependency -# target specified with -MT to '-' -my $index = 1; -while ($index < $#preprocess_c_cmd) { - if ($preprocess_c_cmd[$index] eq "-o") { - $index++; - $preprocess_c_cmd[$index] = "-"; - } - $index++; -} - -my $tempfile; -if ($as_type ne "armasm") { - @gcc_cmd = map { /\.[csS]$/ ? qw(-x assembler -) : $_ } @gcc_cmd; -} else { - @preprocess_c_cmd = grep ! /^-c$/, @preprocess_c_cmd; - @preprocess_c_cmd = grep ! /^-m/, @preprocess_c_cmd; - - @preprocess_c_cmd = grep ! /^-G/, @preprocess_c_cmd; - @preprocess_c_cmd = grep ! /^-W/, @preprocess_c_cmd; - @preprocess_c_cmd = grep ! /^-Z/, @preprocess_c_cmd; - @preprocess_c_cmd = grep ! /^-fp/, @preprocess_c_cmd; - @preprocess_c_cmd = grep ! /^-EHsc$/, @preprocess_c_cmd; - @preprocess_c_cmd = grep ! /^-O/, @preprocess_c_cmd; - - @gcc_cmd = grep ! /^-G/, @gcc_cmd; - @gcc_cmd = grep ! /^-W/, @gcc_cmd; - @gcc_cmd = grep ! /^-Z/, @gcc_cmd; - @gcc_cmd = grep ! /^-fp/, @gcc_cmd; - @gcc_cmd = grep ! /^-EHsc$/, @gcc_cmd; - @gcc_cmd = grep ! /^-O/, @gcc_cmd; - - my @outfiles = grep /\.(o|obj)$/, @gcc_cmd; - $tempfile = $outfiles[0].".asm"; - - # Remove most parameters from gcc_cmd, which actually is the armasm command, - # which doesn't support any of the common compiler/preprocessor options. - @gcc_cmd = grep ! /^-D/, @gcc_cmd; - @gcc_cmd = grep ! /^-U/, @gcc_cmd; - @gcc_cmd = grep ! /^-m/, @gcc_cmd; - @gcc_cmd = grep ! /^-M/, @gcc_cmd; - @gcc_cmd = grep ! /^-c$/, @gcc_cmd; - @gcc_cmd = grep ! /^-I/, @gcc_cmd; - @gcc_cmd = map { /\.S$/ ? $tempfile : $_ } @gcc_cmd; -} - -# detect architecture from gcc binary name -if (!$arch) { - if ($gcc_cmd[0] =~ /(arm64|aarch64|arm|powerpc|ppc)/) { - $arch = $1; - } else { - # look for -arch flag - foreach my $i (1 .. $#gcc_cmd-1) { - if ($gcc_cmd[$i] eq "-arch" and - $gcc_cmd[$i+1] =~ /(arm64|aarch64|arm|powerpc|ppc)/) { - $arch = $1; - } - } - } -} - -# assume we're not cross-compiling if no -arch or the binary doesn't have the arch name -$arch = qx/arch/ if (!$arch); - -die "Unknown target architecture '$arch'" if not exists $canonical_arch{$arch}; - -$arch = $canonical_arch{$arch}; -$comm = $comments{$arch}; -my $inputcomm = $comm; -$comm = ";" if $as_type =~ /armasm/; - -my %ppc_spr = (ctr => 9, - vrsave => 256); - -open(INPUT, "-|", @preprocess_c_cmd) || die "Error running preprocessor"; - -if ($ENV{GASPP_DEBUG}) { - open(ASMFILE, ">&STDOUT"); -} else { - if ($as_type ne "armasm") { - open(ASMFILE, "|-", @gcc_cmd) or die "Error running assembler"; - } else { - open(ASMFILE, ">", $tempfile); - } -} - -my $current_macro = ''; -my $macro_level = 0; -my $rept_level = 0; -my %macro_lines; -my %macro_args; -my %macro_args_default; -my $macro_count = 0; -my $altmacro = 0; -my $in_irp = 0; - -my $num_repts; -my @rept_lines; - -my @irp_args; -my $irp_param; - -my @ifstack; - -my %symbols; - -my @sections; - -my %literal_labels; # for ldr , = -my $literal_num = 0; -my $literal_expr = ".word"; -$literal_expr = ".quad" if $arch eq "aarch64"; - -my $thumb = 0; - -my %thumb_labels; -my %call_targets; -my %mov32_targets; - -my %neon_alias_reg; -my %neon_alias_type; - -my $temp_label_next = 0; -my %last_temp_labels; -my %next_temp_labels; - -my %labels_seen; - -my %aarch64_req_alias; - -if ($force_thumb) { - parse_line(".thumb\n"); -} - -# pass 1: parse .macro -# note that the handling of arguments is probably overly permissive vs. gas -# but it should be the same for valid cases -while () { - # remove all comments (to avoid interfering with evaluating directives) - s/(? 0) { - $ifstack[-1] = -$ifstack[-1]; - } - return 1; - } elsif ($line =~ /\.else/) { - $ifstack[-1] = !$ifstack[-1]; - return 1; - } elsif (handle_if($line)) { - return 1; - } - } - - # discard lines in false .if blocks - foreach my $i (0 .. $#ifstack) { - if ($ifstack[$i] <= 0) { - return 1; - } - } - } - return 0; -} - -sub parse_line { - my $line = $_[0]; - - return if (parse_if_line($line)); - - if (scalar(@rept_lines) == 0) { - if (/\.macro/) { - $macro_level++; - if ($macro_level > 1 && !$current_macro) { - die "nested macros but we don't have master macro"; - } - } elsif (/\.endm/) { - $macro_level--; - if ($macro_level < 0) { - die "unmatched .endm"; - } elsif ($macro_level == 0) { - $current_macro = ''; - return; - } - } - } - - if ($macro_level == 0) { - if ($line =~ /\.(rept|irp)/) { - $rept_level++; - } elsif ($line =~ /.endr/) { - $rept_level--; - } - } - - if ($macro_level > 1) { - push(@{$macro_lines{$current_macro}}, $line); - } elsif (scalar(@rept_lines) and $rept_level >= 1) { - push(@rept_lines, $line); - } elsif ($macro_level == 0) { - expand_macros($line); - } else { - if ($line =~ /\.macro\s+([\d\w\.]+)\s*(.*)/) { - $current_macro = $1; - - # commas in the argument list are optional, so only use whitespace as the separator - my $arglist = $2; - $arglist =~ s/,/ /g; - - my @args = split(/\s+/, $arglist); - foreach my $i (0 .. $#args) { - my @argpair = split(/=/, $args[$i]); - $macro_args{$current_macro}[$i] = $argpair[0]; - $argpair[0] =~ s/:vararg$//; - $macro_args_default{$current_macro}{$argpair[0]} = $argpair[1]; - } - # ensure %macro_lines has the macro name added as a key - $macro_lines{$current_macro} = []; - - } elsif ($current_macro) { - push(@{$macro_lines{$current_macro}}, $line); - } else { - die "macro level without a macro name"; - } - } -} - -sub handle_set { - my $line = $_[0]; - if ($line =~ /\.set\s+(.*),\s*(.*)/) { - $symbols{$1} = eval_expr($2); - return 1; - } - return 0; -} - -sub expand_macros { - my $line = $_[0]; - - # handle .if directives; apple's assembler doesn't support important non-basic ones - # evaluating them is also needed to handle recursive macros - if (handle_if($line)) { - return; - } - - if (/\.purgem\s+([\d\w\.]+)/) { - delete $macro_lines{$1}; - delete $macro_args{$1}; - delete $macro_args_default{$1}; - return; - } - - if ($line =~ /\.altmacro/) { - $altmacro = 1; - return; - } - - if ($line =~ /\.noaltmacro/) { - $altmacro = 0; - return; - } - - $line =~ s/\%([^,]*)/eval_expr($1)/eg if $altmacro; - - # Strip out the .set lines from the armasm output - return if (handle_set($line) and $as_type eq "armasm"); - - if ($line =~ /\.rept\s+(.*)/) { - $num_repts = $1; - @rept_lines = ("\n"); - - # handle the possibility of repeating another directive on the same line - # .endr on the same line is not valid, I don't know if a non-directive is - if ($num_repts =~ s/(\.\w+.*)//) { - push(@rept_lines, "$1\n"); - } - $num_repts = eval_expr($num_repts); - } elsif ($line =~ /\.irp\s+([\d\w\.]+)\s*(.*)/) { - $in_irp = 1; - $num_repts = 1; - @rept_lines = ("\n"); - $irp_param = $1; - - # only use whitespace as the separator - my $irp_arglist = $2; - $irp_arglist =~ s/,/ /g; - $irp_arglist =~ s/^\s+//; - @irp_args = split(/\s+/, $irp_arglist); - } elsif ($line =~ /\.irpc\s+([\d\w\.]+)\s*(.*)/) { - $in_irp = 1; - $num_repts = 1; - @rept_lines = ("\n"); - $irp_param = $1; - - my $irp_arglist = $2; - $irp_arglist =~ s/,/ /g; - $irp_arglist =~ s/^\s+//; - @irp_args = split(//, $irp_arglist); - } elsif ($line =~ /\.endr/) { - my @prev_rept_lines = @rept_lines; - my $prev_in_irp = $in_irp; - my @prev_irp_args = @irp_args; - my $prev_irp_param = $irp_param; - my $prev_num_repts = $num_repts; - @rept_lines = (); - $in_irp = 0; - @irp_args = ''; - - if ($prev_in_irp != 0) { - foreach my $i (@prev_irp_args) { - foreach my $origline (@prev_rept_lines) { - my $line = $origline; - $line =~ s/\\$prev_irp_param/$i/g; - $line =~ s/\\\(\)//g; # remove \() - parse_line($line); - } - } - } else { - for (1 .. $prev_num_repts) { - foreach my $origline (@prev_rept_lines) { - my $line = $origline; - parse_line($line); - } - } - } - } elsif ($line =~ /(\S+:|)\s*([\w\d\.]+)\s*(.*)/ && exists $macro_lines{$2}) { - handle_serialized_line($1); - my $macro = $2; - - # commas are optional here too, but are syntactically important because - # parameters can be blank - my @arglist = split(/,/, $3); - my @args; - my @args_seperator; - - my $comma_sep_required = 0; - foreach (@arglist) { - # allow arithmetic/shift operators in macro arguments - $_ =~ s/\s*(\+|-|\*|\/|<<|>>|<|>)\s*/$1/g; - - my @whitespace_split = split(/\s+/, $_); - if (!@whitespace_split) { - push(@args, ''); - push(@args_seperator, ''); - } else { - foreach (@whitespace_split) { - #print ("arglist = \"$_\"\n"); - if (length($_)) { - push(@args, $_); - my $sep = $comma_sep_required ? "," : " "; - push(@args_seperator, $sep); - #print ("sep = \"$sep\", arg = \"$_\"\n"); - $comma_sep_required = 0; - } - } - } - - $comma_sep_required = 1; - } - - my %replacements; - if ($macro_args_default{$macro}){ - %replacements = %{$macro_args_default{$macro}}; - } - - # construct hashtable of text to replace - foreach my $i (0 .. $#args) { - my $argname = $macro_args{$macro}[$i]; - my @macro_args = @{ $macro_args{$macro} }; - if ($args[$i] =~ m/=/) { - # arg=val references the argument name - # XXX: I'm not sure what the expected behaviour if a lot of - # these are mixed with unnamed args - my @named_arg = split(/=/, $args[$i]); - $replacements{$named_arg[0]} = $named_arg[1]; - } elsif ($i > $#{$macro_args{$macro}}) { - # more args given than the macro has named args - # XXX: is vararg allowed on arguments before the last? - $argname = $macro_args{$macro}[-1]; - if ($argname =~ s/:vararg$//) { - #print "macro = $macro, args[$i] = $args[$i], args_seperator=@args_seperator, argname = $argname, arglist[$i] = $arglist[$i], arglist = @arglist, args=@args, macro_args=@macro_args\n"; - #$replacements{$argname} .= ", $args[$i]"; - $replacements{$argname} .= "$args_seperator[$i] $args[$i]"; - } else { - die "Too many arguments to macro $macro"; - } - } else { - $argname =~ s/:vararg$//; - $replacements{$argname} = $args[$i]; - } - } - - my $count = $macro_count++; - - # apply replacements as regex - foreach (@{$macro_lines{$macro}}) { - my $macro_line = $_; - # do replacements by longest first, this avoids wrong replacement - # when argument names are subsets of each other - foreach (reverse sort {length $a <=> length $b} keys %replacements) { - $macro_line =~ s/\\$_/$replacements{$_}/g; - } - if ($altmacro) { - foreach (reverse sort {length $a <=> length $b} keys %replacements) { - $macro_line =~ s/\b$_\b/$replacements{$_}/g; - } - } - $macro_line =~ s/\\\@/$count/g; - $macro_line =~ s/\\\(\)//g; # remove \() - parse_line($macro_line); - } - } else { - handle_serialized_line($line); - } -} - -sub is_arm_register { - my $name = $_[0]; - if ($name eq "lr" or - $name eq "ip" or - $name =~ /^[rav]\d+$/) { - return 1; - } - return 0; -} - -sub handle_local_label { - my $line = $_[0]; - my $num = $_[1]; - my $dir = $_[2]; - my $target = "$num$dir"; - if ($dir eq "b") { - $line =~ s/$target/$last_temp_labels{$num}/g; - } else { - my $name = "temp_label_$temp_label_next"; - $temp_label_next++; - push(@{$next_temp_labels{$num}}, $name); - $line =~ s/$target/$name/g; - } - return $line; -} - -sub handle_serialized_line { - my $line = $_[0]; - - # handle .previous (only with regard to .section not .subsection) - if ($line =~ /\.(section|text|const_data)/) { - push(@sections, $line); - } elsif ($line =~ /\.previous/) { - if (!$sections[-2]) { - die ".previous without a previous section"; - } - $line = $sections[-2]; - push(@sections, $line); - } - - $thumb = 1 if $line =~ /\.code\s+16|\.thumb/; - $thumb = 0 if $line =~ /\.code\s+32|\.arm/; - - # handle ldr , = - if ($line =~ /(.*)\s*ldr([\w\s\d]+)\s*,\s*=(.*)/ and $as_type ne "armasm") { - my $label = $literal_labels{$3}; - if (!$label) { - $label = "Literal_$literal_num"; - $literal_num++; - $literal_labels{$3} = $label; - } - $line = "$1 ldr$2, $label\n"; - } elsif ($line =~ /\.ltorg/ and $as_type ne "armasm") { - $line .= ".align 2\n"; - foreach my $literal (keys %literal_labels) { - $line .= "$literal_labels{$literal}:\n $literal_expr $literal\n"; - } - %literal_labels = (); - } - - # handle GNU as pc-relative relocations for adrp/add - if ($line =~ /(.*)\s*adrp([\w\s\d]+)\s*,\s*#?:pg_hi21:([^\s]+)/) { - $line = "$1 adrp$2, ${3}\@PAGE\n"; - } elsif ($line =~ /(.*)\s*add([\w\s\d]+)\s*,([\w\s\d]+)\s*,\s*#?:lo12:([^\s]+)/) { - $line = "$1 add$2, $3, ${4}\@PAGEOFF\n"; - } - - # thumb add with large immediate needs explicit add.w - if ($thumb and $line =~ /add\s+.*#([^@]+)/) { - $line =~ s/add/add.w/ if eval_expr($1) > 255; - } - - # mach-o local symbol names start with L (no dot) - $line =~ s/(? with ic as conditional code - if ($cond =~ /|$arm_cond_codes/) { - if (exists $thumb_labels{$label}) { - print ASMFILE ".thumb_func $label\n"; - } else { - $call_targets{$label}++; - } - } - } - - # @l -> lo16() @ha -> ha16() - $line =~ s/,\s+([^,]+)\@l\b/, lo16($1)/g; - $line =~ s/,\s+([^,]+)\@ha\b/, ha16($1)/g; - - # move to/from SPR - if ($line =~ /(\s+)(m[ft])([a-z]+)\s+(\w+)/ and exists $ppc_spr{$3}) { - if ($2 eq 'mt') { - $line = "$1${2}spr $ppc_spr{$3}, $4\n"; - } else { - $line = "$1${2}spr $4, $ppc_spr{$3}\n"; - } - } - - if ($line =~ /\.unreq\s+(.*)/) { - if (defined $neon_alias_reg{$1}) { - delete $neon_alias_reg{$1}; - delete $neon_alias_type{$1}; - return; - } elsif (defined $aarch64_req_alias{$1}) { - delete $aarch64_req_alias{$1}; - return; - } - } - # old gas versions store upper and lower case names on .req, - # but they remove only one on .unreq - if ($fix_unreq) { - if ($line =~ /\.unreq\s+(.*)/) { - $line = ".unreq " . lc($1) . "\n"; - $line .= ".unreq " . uc($1) . "\n"; - } - } - - if ($line =~ /(\w+)\s+\.(dn|qn)\s+(\w+)(?:\.(\w+))?(\[\d+\])?/) { - $neon_alias_reg{$1} = "$3$5"; - $neon_alias_type{$1} = $4; - return; - } - if (scalar keys %neon_alias_reg > 0 && $line =~ /^\s+v\w+/) { - # This line seems to possibly have a neon instruction - foreach (keys %neon_alias_reg) { - my $alias = $_; - # Require the register alias to match as an invididual word, not as a substring - # of a larger word-token. - if ($line =~ /\b$alias\b/) { - $line =~ s/\b$alias\b/$neon_alias_reg{$alias}/g; - # Add the type suffix. If multiple aliases match on the same line, - # only do this replacement the first time (a vfoo.bar string won't match v\w+). - $line =~ s/^(\s+)(v\w+)(\s+)/$1$2.$neon_alias_type{$alias}$3/; - } - } - } - - if ($arch eq "aarch64" or $as_type eq "armasm") { - # clang's integrated aarch64 assembler in Xcode 5 does not support .req/.unreq - if ($line =~ /\b(\w+)\s+\.req\s+(\w+)\b/) { - $aarch64_req_alias{$1} = $2; - return; - } - foreach (keys %aarch64_req_alias) { - my $alias = $_; - # recursively resolve aliases - my $resolved = $aarch64_req_alias{$alias}; - while (defined $aarch64_req_alias{$resolved}) { - $resolved = $aarch64_req_alias{$resolved}; - } - $line =~ s/\b$alias\b/$resolved/g; - } - } - if ($arch eq "aarch64") { - # fix missing aarch64 instructions in Xcode 5.1 (beta3) - # mov with vector arguments is not supported, use alias orr instead - if ($line =~ /^\s*mov\s+(v\d[\.{}\[\]\w]+),\s*(v\d[\.{}\[\]\w]+)\b\s*$/) { - $line = " orr $1, $2, $2\n"; - } - # movi 16, 32 bit shifted variant, shift is optional - if ($line =~ /^\s*movi\s+(v[0-3]?\d\.(?:2|4|8)[hsHS])\s*,\s*(#\w+)\b\s*$/) { - $line = " movi $1, $2, lsl #0\n"; - } - # Xcode 5 misses the alias uxtl. Replace it with the more general ushll. - # Clang 3.4 misses the alias sxtl too. Replace it with the more general sshll. - if ($line =~ /^\s*(s|u)xtl(2)?\s+(v[0-3]?\d\.[248][hsdHSD])\s*,\s*(v[0-3]?\d\.(?:2|4|8|16)[bhsBHS])\b\s*$/) { - $line = " $1shll$2 $3, $4, #0\n"; - } - # clang 3.4 does not automatically use shifted immediates in add/sub - if ($as_type eq "clang" and - $line =~ /^(\s*(?:add|sub)s?) ([^#l]+)#([\d\+\-\*\/ <>]+)\s*$/) { - my $imm = eval $3; - if ($imm > 4095 and not ($imm & 4095)) { - $line = "$1 $2#" . ($imm >> 12) . ", lsl #12\n"; - } - } - if ($ENV{GASPP_FIX_XCODE5}) { - if ($line =~ /^\s*bsl\b/) { - $line =~ s/\b(bsl)(\s+v[0-3]?\d\.(\w+))\b/$1.$3$2/; - $line =~ s/\b(v[0-3]?\d)\.$3\b/$1/g; - } - if ($line =~ /^\s*saddl2?\b/) { - $line =~ s/\b(saddl2?)(\s+v[0-3]?\d\.(\w+))\b/$1.$3$2/; - $line =~ s/\b(v[0-3]?\d)\.\w+\b/$1/g; - } - if ($line =~ /^\s*dup\b.*\]$/) { - $line =~ s/\bdup(\s+v[0-3]?\d)\.(\w+)\b/dup.$2$1/g; - $line =~ s/\b(v[0-3]?\d)\.[bhsdBHSD](\[\d\])$/$1$2/g; - } - } - } - - if ($as_type eq "armasm") { - # Also replace variables set by .set - foreach (keys %symbols) { - my $sym = $_; - $line =~ s/\b$sym\b/$symbols{$sym}/g; - } - - # Handle function declarations and keep track of the declared labels - if ($line =~ s/^\s*\.func\s+(\w+)/$1 PROC/) { - $labels_seen{$1} = 1; - } - - if ($line =~ s/^(\d+)://) { - # Convert local labels into unique labels. armasm (at least in - # RVCT) has something similar, but still different enough. - # By converting to unique labels we avoid any possible - # incompatibilities. - - my $num = $1; - foreach (@{$next_temp_labels{$num}}) { - $line = "$_\n" . $line; - } - @next_temp_labels{$num} = (); - my $name = "temp_label_$temp_label_next"; - $temp_label_next++; - # The matching regexp above removes the label from the start of - # the line (which might contain an instruction as well), readd - # it on a separate line above it. - $line = "$name:\n" . $line; - $last_temp_labels{$num} = $name; - } - - if ($line =~ s/^(\w+):/$1/) { - # Skip labels that have already been declared with a PROC, - # labels must not be declared multiple times. - return if (defined $labels_seen{$1}); - $labels_seen{$1} = 1; - } elsif ($line !~ /(\w+) PROC/) { - # If not a label, make sure the line starts with whitespace, - # otherwise ms armasm interprets it incorrectly. - $line =~ s/^[\.\w]/\t$&/; - } - - - # Check branch instructions - if ($line =~ /(?:^|\n)\s*(\w+\s*:\s*)?(bl?x?(..)?(\.w)?)\s+(\w+)/) { - my $instr = $2; - my $cond = $3; - my $width = $4; - my $target = $5; - # Don't interpret e.g. bic as b with ic as conditional code - if ($cond !~ /|$arm_cond_codes/) { - # Not actually a branch - } elsif ($target =~ /(\d+)([bf])/) { - # The target is a local label - $line = handle_local_label($line, $1, $2); - $line =~ s/\b$instr\b/$&.w/ if $width eq ""; - } elsif (!is_arm_register($target)) { - $call_targets{$target}++; - } - } elsif ($line =~ /^\s*.h?word.*\b\d+[bf]\b/) { - while ($line =~ /\b(\d+)([bf])\b/g) { - $line = handle_local_label($line, $1, $2); - } - } - - # ALIGN in armasm syntax is the actual number of bytes - if ($line =~ /\.align\s+(\d+)/) { - my $align = 1 << $1; - $line =~ s/\.align\s(\d+)/ALIGN $align/; - } - # Convert gas style [r0, :128] into armasm [r0@128] alignment specification - $line =~ s/\[([^\[]+),\s*:(\d+)\]/[$1\@$2]/g; - - # armasm treats logical values {TRUE} and {FALSE} separately from - # numeric values - logical operators and values can't be intermixed - # with numerical values. Evaluate ! and (a <> b) into numbers, - # let the assembler evaluate the rest of the expressions. This current - # only works for cases when ! and <> are used with actual constant numbers, - # we don't evaluate subexpressions here. - - # Evaluate ! - while ($line =~ /!\s*(\d+)/g) { - my $val = ($1 != 0) ? 0 : 1; - $line =~ s/!(\d+)/$val/; - } - # Evaluate (a > b) - while ($line =~ /\(\s*(\d+)\s*([<>])\s*(\d+)\s*\)/) { - my $val; - if ($2 eq "<") { - $val = ($1 < $3) ? 1 : 0; - } else { - $val = ($1 > $3) ? 1 : 0; - } - $line =~ s/\(\s*(\d+)\s*([<>])\s*(\d+)\s*\)/$val/; - } - - # Change a movw... #:lower16: into a mov32 pseudoinstruction - $line =~ s/^(\s*)movw(\s+\w+\s*,\s*)\#:lower16:(.*)$/$1mov32$2$3/; - # and remove the following, matching movt completely - $line =~ s/^\s*movt\s+\w+\s*,\s*\#:upper16:.*$//; - - if ($line =~ /^\s*mov32\s+\w+,\s*([a-zA-Z]\w*)/) { - $mov32_targets{$1}++; - } - - # Misc bugs/deficiencies: - # armasm seems unable to parse e.g. "vmov s0, s1" without a type - # qualifier, thus add .f32. - $line =~ s/^(\s+(?:vmov|vadd))(\s+s)/$1.f32$2/; - # armasm is unable to parse &0x - add spacing - $line =~ s/&0x/& 0x/g; - } - - if ($force_thumb) { - # Convert register post indexing to a separate add instruction. - # This converts e.g. "ldr r0, [r1], r2" into "ldr r0, [r1]", - # "add r1, r1, r2". - $line =~ s/(ldr|str)\s+(\w+),\s*\[(\w+)\],\s*(\w+)/$1 $2, [$3]\n\tadd $3, $3, $4/g; - - # Convert "mov pc, lr" into "bx lr", since the former only works - # for switching from arm to thumb (and only in armv7), but not - # from thumb to arm. - s/mov\s*pc\s*,\s*lr/bx lr/g; - - # Convert stmdb/ldmia with only one register into a plain str/ldr with post-increment/decrement - $line =~ s/stmdb\s+sp!\s*,\s*\{([^,-]+)\}/str $1, [sp, #-4]!/g; - $line =~ s/ldmia\s+sp!\s*,\s*\{([^,-]+)\}/ldr $1, [sp], #4/g; - - $line =~ s/\.arm/.thumb/x; - } - - # comment out unsupported directives - $line =~ s/\.type/$comm$&/x if $as_type =~ /^(apple-|armasm)/; - $line =~ s/\.func/$comm$&/x if $as_type =~ /^(apple-|clang)/; - $line =~ s/\.endfunc/$comm$&/x if $as_type =~ /^(apple-|clang)/; - $line =~ s/\.endfunc/ENDP/x if $as_type =~ /armasm/; - $line =~ s/\.ltorg/$comm$&/x if $as_type =~ /^(apple-|clang)/; - $line =~ s/\.ltorg/LTORG/x if $as_type eq "armasm"; - $line =~ s/\.size/$comm$&/x if $as_type =~ /^(apple-|armasm)/; - $line =~ s/\.fpu/$comm$&/x if $as_type =~ /^(apple-|armasm)/; - $line =~ s/\.arch/$comm$&/x if $as_type =~ /^(apple-|clang|armasm)/; - $line =~ s/\.object_arch/$comm$&/x if $as_type =~ /^(apple-|armasm)/; - $line =~ s/.section\s+.note.GNU-stack.*/$comm$&/x if $as_type =~ /^(apple-|armasm)/; - $line =~ s/\.hidden/$comm$&/x if $as_type =~ /^(apple-|clang|armasm)/; - - $line =~ s/\.syntax/$comm$&/x if $as_type =~ /armasm/; - - $line =~ s/\.hword/.short/x; - - if ($as_type =~ /^apple-/) { - # the syntax for these is a little different - $line =~ s/\.global/.globl/x; - # also catch .section .rodata since the equivalent to .const_data is .section __DATA,__const - $line =~ s/(.*)\.rodata/.const_data/x; - $line =~ s/\.int/.long/x; - $line =~ s/\.float/.single/x; - } - if ($as_type eq "armasm") { - $line =~ s/\.global/EXPORT/x; - $line =~ s/\.int/dcd/x; - $line =~ s/\.long/dcd/x; - $line =~ s/\.float/dcfs/x; - $line =~ s/\.word/dcd/x; - $line =~ s/\.short/dcw/x; - $line =~ s/\.byte/dcb/x; - $line =~ s/\.thumb/THUMB/x; - $line =~ s/\.arm/ARM/x; - # The alignment in AREA is the power of two, just as .align in gas - $line =~ s/\.text/AREA |.text|, CODE, READONLY, ALIGN=2, CODEALIGN/; - $line =~ s/(\s*)(.*)\.rodata/$1AREA |.rodata|, DATA, READONLY, ALIGN=5/; - - $line =~ s/fmxr/vmsr/; - $line =~ s/fmrx/vmrs/; - $line =~ s/fadds/vadd/; - } - - # catch unknown section names that aren't mach-o style (with a comma) - if ($as_type =~ /apple-/ and $line =~ /.section ([^,]*)$/) { - die ".section $1 unsupported; figure out the mach-o section name and add it"; - } - - print ASMFILE $line; -} - -if ($as_type ne "armasm") { - print ASMFILE ".text\n"; - print ASMFILE ".align 2\n"; - foreach my $literal (keys %literal_labels) { - print ASMFILE "$literal_labels{$literal}:\n $literal_expr $literal\n"; - } - - map print(ASMFILE ".thumb_func $_\n"), - grep exists $thumb_labels{$_}, keys %call_targets; -} else { - map print(ASMFILE "\tIMPORT $_\n"), - grep ! exists $labels_seen{$_}, (keys %call_targets, keys %mov32_targets); - - print ASMFILE "\tEND\n"; -} - -close(INPUT) or exit 1; -close(ASMFILE) or exit 1; -if ($as_type eq "armasm" and ! defined $ENV{GASPP_DEBUG}) { - system(@gcc_cmd) == 0 or die "Error running assembler"; -} - -END { - unlink($tempfile) if defined $tempfile; -} -#exit 1 diff --git a/xmake/scripts/tools/gcc.lua b/xmake/scripts/tools/gcc.lua deleted file mode 100644 index ab5e94ccb..000000000 --- a/xmake/scripts/tools/gcc.lua +++ /dev/null @@ -1,192 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file gcc.lua --- - --- load modules -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local config = require("base/config") -local platform = require("platform/platform") - --- define module: gcc -local gcc = gcc or {} - --- check the given flag -function gcc._check(self, flag) - - -- this flag has been checked? - self._CHECK = self._CHECK or {} - if self._CHECK[flag] then - return self._CHECK[flag] - end - - -- check it - local result = flag - if 0 ~= os.execute(string.format("%s %s -S -o %s -xc %s > %s 2>&1", self.name, flag, xmake._NULDEV, xmake._NULDEV, xmake._NULDEV)) then - result = "" - end - - -- trace - utils.verbose("checking for the compiler flags %s ... %s", flag, utils.ifelse(#result ~= 0, "ok", "no")) - - -- save it - self._CHECK[flag] = result - - -- ok? - return result -end - --- the init function -function gcc.init(self, name) - - -- save name - self.name = name or "gcc" - - -- init mxflags - self.mxflags = { "-fmessage-length=0" - , "-pipe" - , "-fpascal-strings" - , "\"-DIBOutlet=__attribute__((iboutlet))\"" - , "\"-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))\"" - , "\"-DIBAction=void)__attribute__((ibaction)\""} - - -- init shflags - if name:find("clang") then - self.shflags = { "-dynamiclib", "-fPIC" } - else - self.shflags = { "-shared", "-fPIC" } - end - - -- init cxflags for the kind: shared - self.shared = {} - self.shared.cxflags = {"-fPIC"} - - -- suppress warning for the clang - local isclang = false - if name:find("clang") then - isclang = true - self.cxflags = self.cxflags or {} - self.mxflags = self.mxflags or {} - self.asflags = self.asflags or {} - table.join2(self.cxflags, "-Qunused-arguments") - table.join2(self.mxflags, "-Qunused-arguments") - table.join2(self.asflags, "-Qunused-arguments") - end - - -- init flags map - self.mapflags = - { - -- vectorexts - ["-mmmx"] = self._check - , ["-msse$"] = self._check - , ["-msse2"] = self._check - , ["-msse3"] = self._check - , ["-mssse3"] = self._check - , ["-mavx$"] = self._check - , ["-mavx2"] = self._check - , ["-mfpu=.*"] = self._check - - -- warnings - , ["-W1"] = "-Wall" - , ["-W2"] = "-Wall" - , ["-W3"] = "-Wall" - - -- strip - , ["-s"] = utils.ifelse(isclang, "-Wl,-S", "-s") - , ["-S"] = utils.ifelse(isclang, "-Wl,-S", "-S") - - -- others - , ["-ftrapv"] = self._check - , ["-fsanitize=address"] = self._check - } - -end - --- make the compile command -function gcc.command_compile(self, srcfile, objfile, flags, logfile) - - -- redirect - local redirect = "" - if logfile then redirect = string.format(" > %s 2>&1", logfile) end - - -- make it - return string.format("%s -c %s -o %s %s%s", self.name, flags, objfile, srcfile, redirect) -end - --- make the link command -function gcc.command_link(self, objfiles, targetfile, flags, logfile) - - -- redirect - local redirect = "" - if logfile then redirect = string.format(" > %s 2>&1", logfile) end - - -- make it - return string.format("%s -o %s %s %s%s", self.name, targetfile, objfiles, flags, redirect) -end - --- make the define flag -function gcc.flag_define(self, define) - - -- make it - return "-D" .. define:gsub("\"", "\\\"") -end - --- make the undefine flag -function gcc.flag_undefine(self, undefine) - - -- make it - return "-U" .. undefine -end - --- make the includedir flag -function gcc.flag_includedir(self, includedir) - - -- make it - return "-I" .. includedir -end - --- make the link flag -function gcc.flag_link(self, link) - - -- make it - return "-l" .. link -end - --- make the linkdir flag -function gcc.flag_linkdir(self, linkdir) - - -- make it - return "-L" .. linkdir -end - --- the main function -function gcc.main(self, cmd) - - -- execute it - local ok = os.execute(cmd) - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: gcc -return gcc diff --git a/xmake/scripts/tools/make.lua b/xmake/scripts/tools/make.lua deleted file mode 100644 index 5d2d1f42b..000000000 --- a/xmake/scripts/tools/make.lua +++ /dev/null @@ -1,82 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file make.lua --- - --- load modules -local os = require("base/os") -local utils = require("base/utils") - --- define module: make -local make = make or {} - --- the init function -function make.init(self, name) - - -- save name - self.name = name or "make" - - -- is verbose? - self._VERBOSE = utils.ifelse(xmake._OPTIONS.verbose, "-v", "") - -end - --- the main function -function make.main(self, mkfile, target) - - -- enable jobs? - local jobs = "" - if xmake._OPTIONS.jobs ~= nil then - if tonumber(xmake._OPTIONS.jobs) ~= 0 then - jobs = "-j" .. xmake._OPTIONS.jobs - else - jobs = "-j" - end - end - - -- make command - local cmd = nil - if mkfile and os.isfile(mkfile) then - cmd = string.format("%s -r %s -f %s %s VERBOSE=%s", self.name, jobs, mkfile, target or "", self._VERBOSE) - else - cmd = string.format("%s -r %s %s VERBOSE=%s", self.name, jobs, target or "", self._VERBOSE) - end - - -- done - local ok = os.execute(cmd) - if ok ~= 0 then - - -- attempt to execute it again for getting the error logs without jobs - if mkfile and os.isfile(mkfile) then - cmd = string.format("%s -r -f %s %s VERBOSE=%s", self.name, mkfile, target or "", self._VERBOSE) - else - cmd = string.format("%s -r %s VERBOSE=%s", self.name, target or "", self._VERBOSE) - end - - -- done - return os.execute(cmd) == 0 - end - - -- ok - return true -end - --- return module: make -return make diff --git a/xmake/scripts/tools/mkdir.lua b/xmake/scripts/tools/mkdir.lua deleted file mode 100644 index 9fadb875d..000000000 --- a/xmake/scripts/tools/mkdir.lua +++ /dev/null @@ -1,46 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file mkdir.lua --- - --- define module: mkdir -local mkdir = mkdir or {} - --- load modules -local os = require("base/os") - --- the main function -function mkdir.main(self, ...) - - -- mkdir all - for _, dir in ipairs(...) do - if not os.exists(dir) then - if not os.mkdir(dir) then - return false - end - end - end - - -- ok - return true -end - --- return module: mkdir -return mkdir diff --git a/xmake/scripts/tools/mv.lua b/xmake/scripts/tools/mv.lua deleted file mode 100644 index 7af2db9ed..000000000 --- a/xmake/scripts/tools/mv.lua +++ /dev/null @@ -1,43 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file mv.lua --- - --- define module: mv -local mv = mv or {} - --- load modules -local os = require("base/os") - --- the main function -function mv.main(self, ...) - - -- mv it - local pathes = ... - if pathes and table.getn(pathes) == 2 then - return os.mv(pathes[1], pathes[2]) - end - - -- failed - return false -end - --- return module: mv -return mv diff --git a/xmake/scripts/tools/rm.lua b/xmake/scripts/tools/rm.lua deleted file mode 100644 index 47f57e68b..000000000 --- a/xmake/scripts/tools/rm.lua +++ /dev/null @@ -1,46 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file rm.lua --- - --- define module: rm -local rm = rm or {} - --- load modules -local os = require("base/os") - --- the main function -function rm.main(self, ...) - - -- rm all - for _, file_or_dir in ipairs(...) do - if os.exists(file_or_dir) then - if not os.rm(file_or_dir) then - return false - end - end - end - - -- ok - return true -end - --- return module: rm -return rm diff --git a/xmake/scripts/tools/rmdir.lua b/xmake/scripts/tools/rmdir.lua deleted file mode 100644 index cea1e28fa..000000000 --- a/xmake/scripts/tools/rmdir.lua +++ /dev/null @@ -1,46 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file rmdir.lua --- - --- define module: rmdir -local rmdir = rmdir or {} - --- load modules -local os = require("base/os") - --- the main function -function rmdir.main(self, ...) - - -- rmdir all - for _, dir in ipairs(...) do - if os.isdir(dir) then - if not os.rmdir(dir) then - return false - end - end - end - - -- ok - return true -end - --- return module: rmdir -return rmdir diff --git a/xmake/scripts/tools/swiftc.lua b/xmake/scripts/tools/swiftc.lua deleted file mode 100644 index 39142705f..000000000 --- a/xmake/scripts/tools/swiftc.lua +++ /dev/null @@ -1,117 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file swiftc.lua --- - --- load modules -local utils = require("base/utils") -local table = require("base/table") -local string = require("base/string") -local config = require("base/config") -local platform = require("platform/platform") - --- define module: swiftc -local swiftc = swiftc or {} - --- the init function -function swiftc.init(self, name) - - -- save name - self.name = name or "swiftc" - - -- init flags map - self.mapflags = - { - -- symbols - ["-fvisibility=hidden"] = "" - - -- warnings - , ["-w"] = "" - , ["-W.*"] = "" - - -- optimize - , ["-O0"] = "-Onone" - , ["-Ofast"] = "-Ounchecked" - , ["-O.*"] = "-O" - - -- vectorexts - , ["-m.*"] = "" - - -- strip - , ["-s"] = "" - , ["-S"] = "" - - -- others - , ["-ftrapv"] = "" - , ["-fsanitize=address"] = "" - } - - -- init ldflags - local swift_linkdirs = config.get("__swift_linkdirs") - if swift_linkdirs then - self.ldflags = { "-L" .. swift_linkdirs } - end - -end - --- make the compile command -function swiftc.command_compile(self, srcfile, objfile, flags, logfile) - - -- redirect - local redirect = "" - if logfile then redirect = string.format(" > %s 2>&1", logfile) end - - -- make it - return string.format("%s -c %s -o %s %s%s", self.name, flags, objfile, srcfile, redirect) -end - --- make the includedir flag -function swiftc.flag_includedir(self, includedir) - - -- make it - return "-Xcc -I" .. includedir -end - --- make the define flag -function swiftc.flag_define(self, define) - - -- make it - return "-Xcc -D" .. define:gsub("\"", "\\\"") -end - --- make the undefine flag -function swiftc.flag_undefine(self, undefine) - - -- make it - return "-Xcc -U" .. undefine -end - --- the main function -function swiftc.main(self, cmd) - - -- execute it - local ok = os.execute(cmd) - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: swiftc -return swiftc diff --git a/xmake/scripts/tools/tools.lua b/xmake/scripts/tools/tools.lua deleted file mode 100644 index 31a68734b..000000000 --- a/xmake/scripts/tools/tools.lua +++ /dev/null @@ -1,222 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file tools.lua --- - --- define module: tools -local tools = tools or {} - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local platform = require("platform/platform") - --- match the tool name -function tools._match(name, toolname) - - -- match full? ok - if name == toolname then return 100 end - - -- match the name for windows? ok - if name:find("^" .. toolname .. "%.exe") then return 90 end - if name:find(toolname .. "%.exe") then return 85 end - - -- match the last word? ok - if name:find(toolname .. "$") then return 80 end - - -- match the partial word? ok - if name:find("%-" .. toolname) then return 60 end - - -- contains it? ok - if name:find(toolname, 1, true) then return 30 end - - -- not matched - return 0 -end - --- find tool from the given root directory and name -function tools._find_from(root, name) - - -- attempt to get it directly first - local filepath = string.format("%s/%s.lua", root, name) - if os.isfile(filepath) then - return filepath - end - - -- make the lower name - name = name:lower() - - -- get all tool files - local file_ok = nil - local score_maxn = 0 - local files = os.match(string.format("%s/*.lua", root)) - for _, file in ipairs(files) do - - -- the tool name - local toolname = path.basename(file) - - -- found it? - if toolname and toolname ~= "tools" then - - -- match score - local score = tools._match(name, toolname:lower()) - - -- ok? - if score >= 100 then return file end - - -- select the file with the max score - if score > score_maxn then - file_ok = file - score_maxn = score - end - end - end - - -- ok? - return file_ok -end - --- probe it's absolute path if exists from the given tool name and root directory -function tools._probe(root, name) - - -- check - assert(root and name) - - -- make the tool path - local toolpath = string.format("%s/%s", root, name) - toolpath = path.translate(toolpath) - - -- the tool exists? ok - if toolpath and os.isfile(toolpath) then - return toolpath - end -end - --- find tool from the given name and directory (optional) -function tools.find(name, root) - - -- check - assert(name) - - -- init filename - local filepath = nil - - -- only find it from this directory if the given directory exists - if root then return tools._find_from(root, name) end - - -- attempt to find it from the current platform directory first - if not filepath then filepath = tools._find_from(platform.directory() .. "/tools", name) end - - -- attempt to find it from the script directory - if not filepath then filepath = tools._find_from(xmake._SCRIPTS_DIR .. "/tools", name) end - - -- ok? - return filepath -end - --- load tool from the given name and directory (optional) -function tools.load(name, root) - - -- check - assert(name) - - -- get it directly from cache dirst - tools._TOOLS = tools._TOOLS or {} - if tools._TOOLS[name] then - return tools._TOOLS[name] - end - - -- find the tool file path - local toolpath = tools.find(name, root) - - -- not exists? - if not toolpath or not os.isfile(toolpath) then - return - end - - -- load script - local script, errors = loadfile(toolpath) - if script then - - -- load tool - local tool = script() - - -- init tool - if tool and tool.init then - tool:init(name) - end - - -- save tool to the cache - tools._TOOLS[name] = tool - - -- ok? - return tool - else - utils.error(errors) - utils.error("load %s failed!", toolpath) - assert(false) - end -end - --- get the given tool script from the given kind -function tools.get(kind) - - -- get the tool name - local toolname = platform.tool(kind) - if not toolname then - utils.error("cannot get tool name for %s", kind) - return - end - - -- load it - return tools.load(toolname) -end - --- probe it's absolute path if exists from the given tool name -function tools.probe(name, dirs) - - -- check - assert(name) - - -- attempt to run it directly first - if os.execute(string.format("%s > %s 2>&1", name, xmake._NULDEV)) ~= 0x7f00 then - return name - end - - -- attempt to get it from the given directories - if dirs then - for _, dir in ipairs(utils.wrap(dirs)) do - - -- probe it - local toolpath = tools._probe(dir, name) - - -- ok? - if toolpath and os.execute(string.format("%s > %s 2>&1", toolpath, xmake._NULDEV)) ~= 0x7f00 then - return toolpath - end - end - end -end - - --- return module: tools -return tools diff --git a/xmake/scripts/tools/verbose.lua b/xmake/scripts/tools/verbose.lua deleted file mode 100644 index b1168f29d..000000000 --- a/xmake/scripts/tools/verbose.lua +++ /dev/null @@ -1,47 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file verbose.lua --- - - --- define module: verbose -local verbose = verbose or {} - --- load modules -local io = require("base/io") -local string = require("base/string") - --- the main function -function verbose.main(self, ...) - - -- verbose all - if xmake._OPTIONS.verbose then - for _, v in ipairs(...) do - io.write(string.format("%s ", v:decode())) - end - io.write("\n") - end - - -- ok - return true -end - --- return module: verbose -return verbose -- cgit v1.3.1