--!A cross-platform build utility based on Lua -- -- Licensed under the Apache License, Version 2.0 (the "License"); -- you may not use this file except in compliance with the License. -- You may obtain a copy of the License at -- -- http://www.apache.org/licenses/LICENSE-2.0 -- -- Unless required by applicable law or agreed to in writing, software -- distributed under the License is distributed on an "AS IS" BASIS, -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. -- -- Copyright (C) 2015-present, Xmake Open Source Community. -- -- @author ruki -- @file macosx.lua -- -- imports import("core.theme.theme") import("core.base.option") import("core.project.config") import("core.project.depend") import("core.tool.toolchain") import("lib.detect.find_file") import("lib.detect.find_path") import("detect.sdks.find_qt") import("utils.progress") import("private.tools.codesign") -- save Info.plist function _save_info_plist(target, info_plist_file) -- get target minver local target_minver = nil local toolchain_xcode = toolchain.load("xcode", {plat = target:plat(), arch = target:arch()}) if toolchain_xcode then target_minver = toolchain_xcode:config("target_minver") end -- generate info.plist local name = target:basename() io.writefile(info_plist_file, string.format([[ BuildMachineOSBuild 18G95 CFBundleDevelopmentRegion en CFBundleDisplayName %s CFBundleExecutable %s CFBundleIdentifier org.example.%s CFBundleInfoDictionaryVersion 6.0 CFBundleName %s CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleVersion 1.0.0 LSMinimumSystemVersion %s NSPrincipalClass NSApplication ]], name, name, name, name, target_minver or (macos.version():major() .. "." .. macos.version():minor()))) end -- deploy application package for macosx function main(target, opt) -- need re-generate this app? local target_app = path.join(target:targetdir(), target:basename() .. ".app") local targetfile = target:targetfile() local dependfile = target:dependfile(target_app) local dependinfo = target:is_rebuilt() and {} or (depend.load(dependfile) or {}) if not depend.is_changed(dependinfo, {lastmtime = os.mtime(dependfile)}) then return end -- trace progress info progress.show(opt.progress, "${color.build.target}generating.qt.app %s.app", target:basename()) -- get qt sdk local qt = assert(find_qt(), "Qt SDK not found!") -- get macdeployqt local search_dirs = {} if qt.bindir_host then table.insert(search_dirs, qt.bindir_host) end if qt.bindir then table.insert(search_dirs, qt.bindir) end local macdeployqt = find_file("macdeployqt" .. (is_host("windows") and ".exe" or ""), search_dirs) assert(os.isexec(macdeployqt), "macdeployqt not found!") -- generate target app local target_contents = path.join(target_app, "Contents") os.tryrm(target_app) os.cp(target:targetfile(), path.join(target_contents, "MacOS", target:basename())) os.cp(path.join(os.programdir(), "scripts", "PkgInfo"), target_contents) -- generate Info.plist _save_info_plist(target, path.join(target_contents, "Info.plist")) -- find qml directory local qmldir = target:values("qt.deploy.qmldir") if not qmldir then for _, sourcebatch in pairs(target:sourcebatches()) do if sourcebatch.rulename == "qt.qrc" then for _, sourcefile in ipairs(sourcebatch.sourcefiles) do qmldir = find_path("*.qml", path.directory(sourcefile)) if qmldir then break end end end end else qmldir = path.join(target:scriptdir(), qmldir) end -- do deploy local argv = {target_app, "-always-overwrite"} if option.get("diagnosis") then table.insert(argv, "-verbose=3") elseif option.get("verbose") then table.insert(argv, "-verbose=1") else table.insert(argv, "-verbose=0") end if qmldir then table.insert(argv, "-qmldir=" .. qmldir) end local codesign_identity = target:values("xcode.codesign_identity") or codesign.xcode_codesign_identity() if codesign_identity then -- e.g. "Apple Development: waruqi@gmail.com (T3NA4MRVPU)" table.insert(argv, "-codesign=" .. codesign_identity) end -- add user flags local user_flags = target:values("qt.deploy.flags") or {} if user_flags then argv = table.join(argv, user_flags) end os.vrunv(macdeployqt, argv) -- update files and values to the dependent file dependinfo.files = {targetfile} depend.save(dependinfo, dependfile) end