From a69cac4ac8a3d5176970fbc45578aea7208c6cec Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 2 May 2023 00:45:44 +0800 Subject: add conan v1/v2 --- .../package/manager/conan/configurations.lua | 2 +- .../package/manager/conan/install_package.lua | 267 +------------------ .../package/manager/conan/v1/install_package.lua | 282 +++++++++++++++++++++ .../package/manager/conan/v2/install_package.lua | 282 +++++++++++++++++++++ 4 files changed, 572 insertions(+), 261 deletions(-) create mode 100644 xmake/modules/package/manager/conan/v1/install_package.lua create mode 100644 xmake/modules/package/manager/conan/v2/install_package.lua diff --git a/xmake/modules/package/manager/conan/configurations.lua b/xmake/modules/package/manager/conan/configurations.lua index b4ed38fc3..6f99742f1 100644 --- a/xmake/modules/package/manager/conan/configurations.lua +++ b/xmake/modules/package/manager/conan/configurations.lua @@ -27,7 +27,7 @@ function main() options = {description = "Set the options values, e.g. OpenSSL:shared=True"}, imports = {description = "Set the imports for conan."}, settings = {description = "Set the build settings for conan."}, - build_requires = {description = "Set the build requires for conan.", default = "xmake_generator/0.1.0@bincrafters/testing"} + build_requires = {description = "Set the build requires for conan."} } end diff --git a/xmake/modules/package/manager/conan/install_package.lua b/xmake/modules/package/manager/conan/install_package.lua index 2a3f8b38f..2d234b241 100644 --- a/xmake/modules/package/manager/conan/install_package.lua +++ b/xmake/modules/package/manager/conan/install_package.lua @@ -21,280 +21,27 @@ -- imports import("core.base.option") import("core.base.semver") -import("core.project.config") -import("core.tool.toolchain") -import("core.platform.platform") import("lib.detect.find_tool") -import("devel.git") -import("net.fasturl") - --- get build env -function _conan_get_build_env(name, plat) - local value = config.get(name) - if value == nil then - value = platform.toolconfig(name, plat) - end - if value == nil then - value = platform.tool(name, plat) - end - value = table.unique(table.wrap(value)) - if #value > 0 then - value = table.unwrap(value) - return value - end -end - --- get build directory -function _conan_get_build_directory(name) - return path.absolute(path.join(config.buildir() or os.tmpdir(), ".conan", name)) -end - --- generate conanfile.txt -function _conan_generate_conanfile(name, configs, opt) - - -- trace - dprint("generate %s ..", path.join(_conan_get_build_directory(name), "conanfile.txt")) - - -- get conan options, imports and build_requires - local options = table.wrap(configs.options) - local imports = table.wrap(configs.imports) - local build_requires = table.wrap(configs.build_requires) - - -- @see https://docs.conan.io/en/latest/systems_cross_building/cross_building.html - -- generate it - local conanfile = io.open("conanfile.txt", "w") - if conanfile then - conanfile:print("[generators]") - conanfile:print("xmake") - conanfile:print("[requires]") - local require_version = opt.require_version - if require_version ~= nil and require_version ~= "latest" then - conanfile:print("%s/%s", name, require_version) - else - conanfile:print("%s", name) - end - if #options > 0 then - conanfile:print("[options]") - conanfile:print("%s", table.concat(options, "\n")) - end - if #imports > 0 then - conanfile:print("[imports]") - conanfile:print("%s", table.concat(imports, "\n")) - end - if #build_requires > 0 then - conanfile:print("[build_requires]") - conanfile:print("%s", table.concat(build_requires, "\n")) - end - conanfile:close() - end -end - --- install xmake generator -function _conan_install_xmake_generator(conan) - local xmake_generator_localdir = path.join(config.directory(), "conan", "xmake_generator") - if not os.isdir(xmake_generator_localdir) then - - -- sort main urls - local mainurls = {"https://github.com/xmake-io/conan-xmake_generator.git", - "https://gitlab.com/xmake-io/conan-xmake_generator.git", - "https://gitee.com/xmake-io/conan-xmake_generator.git"} - fasturl.add(mainurls) - mainurls = fasturl.sort(mainurls) - - -- clone xmake generator repository - local ok = false - for _, url in ipairs(mainurls) do - ok = try { function () git.clone(url, {depth = 1, branch = "0.1.0/testing", outputdir = xmake_generator_localdir}); return true end } - if ok then - break - end - end - if ok then - os.vrunv(conan.program, {"export", xmake_generator_localdir, "bincrafters/testing"}) - end - end -end -- install package -- --- @param name the package name, e.g. conan::OpenSSL/1.0.2n@conan/stable +-- @param name the package name, e.g. conan::OpenSSL 1.0.2n -- @param opt the options, e.g. { verbose = true, mode = "release", plat = , arch = , -- configs = { -- remote = "", build = "all", options = {}, imports = {}, build_requires = {}, -- settings = {"compiler=msvc", "compiler.version=10", "compiler.runtime=MD"}}} -- --- @return true or false --- function main(name, opt) - - -- get configs - opt = opt or {} - local configs = opt.configs or {} - - -- find conan local conan = find_tool("conan", {version = true}) if not conan then raise("conan not found!") end - if conan.version then - assert(semver.compare(conan.version, "2.0") < 0, "conan %s is not supported, please use conan 1.x", conan.version) - end - - -- get build directory - local buildir = _conan_get_build_directory(name) - - -- clean the build directory - os.tryrm(buildir) - if not os.isdir(buildir) then - os.mkdir(buildir) - end - - -- enter build directory - local oldir = os.cd(buildir) - - -- install xmake generator - _conan_install_xmake_generator(conan) - - -- generate conanfile.txt - _conan_generate_conanfile(name, configs, opt) - - -- install package - local argv = {"install", "."} - if configs.build then - if configs.build == "all" then - table.insert(argv, "--build") - else - table.insert(argv, "--build=" .. configs.build) - end - end - - -- set platform - local plats = {macosx = "Macos", windows = "Windows", mingw = "Windows", linux = "Linux", cross = "Linux", iphoneos = "iOS", android = "Android"} - table.insert(argv, "-s") - local plat = plats[opt.plat] - if plat then - table.insert(argv, "os=" .. plat) - else - raise("cannot install package(%s) on platform(%s)!", name, opt.plat) - end - - -- set architecture - local archs = {x86_64 = "x86_64", - x64 = "x86_64", - i386 = "x86", - x86 = "x86", - armv7 = "armv7", - ["armv7-a"] = "armv7", -- for android, deprecated - ["armeabi"] = "armv7", -- for android, removed in ndk r17 - ["armeabi-v7a"] = "armv7", -- for android - armv7s = "armv7s", -- for iphoneos - arm64 = "armv8", -- for iphoneos - ["arm64-v8a"] = "armv8", -- for android - mips = "mips", - mips64 = "mips64"} - table.insert(argv, "-s") - local arch = archs[opt.arch] - if arch then - table.insert(argv, "arch=" .. arch) + if conan.version and semver.compare(conan.version, "2.0.4") >= 0 then -- TODO 2.0.5 + import("package.manager.conan.v2.install_package")(conan, name, opt) + elseif conan.version and semver.compare(conan.version, "2.0.0") < 0 then + import("package.manager.conan.v1.install_package")(conan, name, opt) else - raise("cannot install package(%s) for arch(%s)!", name, opt.arch) + -- conan 2.0.0-2.0.4 does not supported + raise("conan %s is not supported, please use conan 1.x", conan.version) end - - -- set build mode - table.insert(argv, "-s") - if opt.mode == "debug" then - table.insert(argv, "build_type=Debug") - else - table.insert(argv, "build_type=Release") - end - - -- set compiler settings - if opt.plat == "windows" then - local vsvers = {["2022"] = "17", - ["2019"] = "16", - ["2017"] = "15", - ["2015"] = "14", - ["2013"] = "12", - ["2012"] = "11", - ["2010"] = "10", - ["2008"] = "9", - ["2005"] = "8"} - local vs = assert(config.get("vs"), "vs not found!") - table.insert(argv, "-s") - table.insert(argv, "compiler=Visual Studio") - table.insert(argv, "-s") - table.insert(argv, "compiler.version=" .. assert(vsvers[vs], "unknown msvc version!")) - if configs.vs_runtime then - table.insert(argv, "-s") - table.insert(argv, "compiler.runtime=" .. configs.vs_runtime) - end - elseif opt.plat == "iphoneos" then - local target_minver = nil - local toolchain_xcode = toolchain.load("xcode", {plat = opt.plat, arch = opt.arch}) - if toolchain_xcode then - target_minver = toolchain_xcode:config("target_minver") - end - if target_minver and tonumber(target_minver) > 10 and (arch == "armv7" or arch == "armv7s" or arch == "x86") then - target_minver = "10" -- iOS 10 is the maximum deployment target for 32-bit targets - end - if target_minver then - table.insert(argv, "-s") - table.insert(argv, "os.version=" .. target_minver) - end - elseif opt.plat == "android" then - local ndk_sdkver = config.get("ndk_sdkver") - if ndk_sdkver then - table.insert(argv, "-s") - table.insert(argv, "os.api_level=" .. ndk_sdkver) - end - end - - -- set custom settings - for _, setting in ipairs(configs.settings) do - table.insert(argv, "-s") - table.insert(argv, setting) - end - - -- set remote - if configs.remote then - table.insert(argv, "-r") - table.insert(argv, configs.remote) - end - - -- TODO set environments - if opt.plat == "android" then - local envs = {} - local cflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cflags", opt.plat)) - local cxxflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cxxflags", opt.plat)) - envs.CC = _conan_get_build_env("cc", opt.plat) - envs.CXX = _conan_get_build_env("cxx", opt.plat) - envs.AS = _conan_get_build_env("as", opt.plat) - envs.AR = _conan_get_build_env("ar", opt.plat) - envs.LD = _conan_get_build_env("ld", opt.plat) - envs.LDSHARED = _conan_get_build_env("sh", opt.plat) - envs.CPP = _conan_get_build_env("cpp", opt.plat) - envs.RANLIB = _conan_get_build_env("ranlib", opt.plat) - envs.CFLAGS = table.concat(cflags, ' ') - envs.CXXFLAGS = table.concat(cxxflags, ' ') - envs.ASFLAGS = table.concat(table.wrap(_conan_get_build_env("asflags", opt.plat)), ' ') - envs.ARFLAGS = table.concat(table.wrap(_conan_get_build_env("arflags", opt.plat)), ' ') - envs.LDFLAGS = table.concat(table.wrap(_conan_get_build_env("ldflags", opt.plat)), ' ') - envs.SHFLAGS = table.concat(table.wrap(_conan_get_build_env("shflags", opt.plat)), ' ') - local toolchain_ndk = toolchain.load("ndk", {plat = opt.plat, arch = opt.arch}) - local ndk_sysroot = toolchain_ndk:config("ndk_sysroot") - if ndk_sysroot then - table.insert(argv, "-e") - table.insert(argv, "CONAN_CMAKE_FIND_ROOT_PATH=" .. ndk_sysroot) - end - for k, v in pairs(envs) do - table.insert(argv, "-e") - table.insert(argv, k .. "=" .. v) - end - end - - -- do install - os.vrunv(conan.program, argv) - - -- leave build directory - os.cd(oldir) end diff --git a/xmake/modules/package/manager/conan/v1/install_package.lua b/xmake/modules/package/manager/conan/v1/install_package.lua new file mode 100644 index 000000000..f8c60ad72 --- /dev/null +++ b/xmake/modules/package/manager/conan/v1/install_package.lua @@ -0,0 +1,282 @@ +--!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, TBOOX Open Source Group. +-- +-- @author ruki +-- @file install_package.lua +-- + +-- imports +import("core.base.option") +import("core.base.semver") +import("core.project.config") +import("core.tool.toolchain") +import("core.platform.platform") +import("lib.detect.find_tool") +import("devel.git") +import("net.fasturl") + +-- get build env +function _conan_get_build_env(name, plat) + local value = config.get(name) + if value == nil then + value = platform.toolconfig(name, plat) + end + if value == nil then + value = platform.tool(name, plat) + end + value = table.unique(table.wrap(value)) + if #value > 0 then + value = table.unwrap(value) + return value + end +end + +-- get build directory +function _conan_get_build_directory(name) + return path.absolute(path.join(config.buildir() or os.tmpdir(), ".conan", name)) +end + +-- generate conanfile.txt +function _conan_generate_conanfile(name, configs, opt) + + -- trace + dprint("generate %s ..", path.join(_conan_get_build_directory(name), "conanfile.txt")) + + -- get conan options, imports and build_requires + local options = table.wrap(configs.options) + local imports = table.wrap(configs.imports) + local build_requires = table.wrap(configs.build_requires or "xmake_generator/0.1.0@bincrafters/testing") + + -- @see https://docs.conan.io/en/latest/systems_cross_building/cross_building.html + -- generate it + local conanfile = io.open("conanfile.txt", "w") + if conanfile then + conanfile:print("[generators]") + conanfile:print("xmake") + conanfile:print("[requires]") + local require_version = opt.require_version + if require_version ~= nil and require_version ~= "latest" then + conanfile:print("%s/%s", name, require_version) + else + conanfile:print("%s", name) + end + if #options > 0 then + conanfile:print("[options]") + conanfile:print("%s", table.concat(options, "\n")) + end + if #imports > 0 then + conanfile:print("[imports]") + conanfile:print("%s", table.concat(imports, "\n")) + end + if #build_requires > 0 then + conanfile:print("[build_requires]") + conanfile:print("%s", table.concat(build_requires, "\n")) + end + conanfile:close() + end +end + +-- install xmake generator +function _conan_install_xmake_generator(conan) + local xmake_generator_localdir = path.join(config.directory(), "conan", "xmake_generator") + if not os.isdir(xmake_generator_localdir) then + + -- sort main urls + local mainurls = {"https://github.com/xmake-io/conan-xmake_generator.git", + "https://gitlab.com/xmake-io/conan-xmake_generator.git", + "https://gitee.com/xmake-io/conan-xmake_generator.git"} + fasturl.add(mainurls) + mainurls = fasturl.sort(mainurls) + + -- clone xmake generator repository + local ok = false + for _, url in ipairs(mainurls) do + ok = try { function () git.clone(url, {depth = 1, branch = "0.1.0/testing", outputdir = xmake_generator_localdir}); return true end } + if ok then + break + end + end + if ok then + os.vrunv(conan.program, {"export", xmake_generator_localdir, "bincrafters/testing"}) + end + end +end + +-- install package +function main(conan, name, opt) + + -- get configs + opt = opt or {} + local configs = opt.configs or {} + + -- get build directory + local buildir = _conan_get_build_directory(name) + + -- clean the build directory + os.tryrm(buildir) + if not os.isdir(buildir) then + os.mkdir(buildir) + end + + -- enter build directory + local oldir = os.cd(buildir) + + -- install xmake generator + _conan_install_xmake_generator(conan) + + -- generate conanfile.txt + _conan_generate_conanfile(name, configs, opt) + + -- install package + local argv = {"install", "."} + if configs.build then + if configs.build == "all" then + table.insert(argv, "--build") + else + table.insert(argv, "--build=" .. configs.build) + end + end + + -- set platform + local plats = {macosx = "Macos", windows = "Windows", mingw = "Windows", linux = "Linux", cross = "Linux", iphoneos = "iOS", android = "Android"} + table.insert(argv, "-s") + local plat = plats[opt.plat] + if plat then + table.insert(argv, "os=" .. plat) + else + raise("cannot install package(%s) on platform(%s)!", name, opt.plat) + end + + -- set architecture + local archs = {x86_64 = "x86_64", + x64 = "x86_64", + i386 = "x86", + x86 = "x86", + armv7 = "armv7", + ["armv7-a"] = "armv7", -- for android, deprecated + ["armeabi"] = "armv7", -- for android, removed in ndk r17 + ["armeabi-v7a"] = "armv7", -- for android + armv7s = "armv7s", -- for iphoneos + arm64 = "armv8", -- for iphoneos + ["arm64-v8a"] = "armv8", -- for android + mips = "mips", + mips64 = "mips64"} + table.insert(argv, "-s") + local arch = archs[opt.arch] + if arch then + table.insert(argv, "arch=" .. arch) + else + raise("cannot install package(%s) for arch(%s)!", name, opt.arch) + end + + -- set build mode + table.insert(argv, "-s") + if opt.mode == "debug" then + table.insert(argv, "build_type=Debug") + else + table.insert(argv, "build_type=Release") + end + + -- set compiler settings + if opt.plat == "windows" then + local vsvers = {["2022"] = "17", + ["2019"] = "16", + ["2017"] = "15", + ["2015"] = "14", + ["2013"] = "12", + ["2012"] = "11", + ["2010"] = "10", + ["2008"] = "9", + ["2005"] = "8"} + local vs = assert(config.get("vs"), "vs not found!") + table.insert(argv, "-s") + table.insert(argv, "compiler=Visual Studio") + table.insert(argv, "-s") + table.insert(argv, "compiler.version=" .. assert(vsvers[vs], "unknown msvc version!")) + if configs.vs_runtime then + table.insert(argv, "-s") + table.insert(argv, "compiler.runtime=" .. configs.vs_runtime) + end + elseif opt.plat == "iphoneos" then + local target_minver = nil + local toolchain_xcode = toolchain.load("xcode", {plat = opt.plat, arch = opt.arch}) + if toolchain_xcode then + target_minver = toolchain_xcode:config("target_minver") + end + if target_minver and tonumber(target_minver) > 10 and (arch == "armv7" or arch == "armv7s" or arch == "x86") then + target_minver = "10" -- iOS 10 is the maximum deployment target for 32-bit targets + end + if target_minver then + table.insert(argv, "-s") + table.insert(argv, "os.version=" .. target_minver) + end + elseif opt.plat == "android" then + local ndk_sdkver = config.get("ndk_sdkver") + if ndk_sdkver then + table.insert(argv, "-s") + table.insert(argv, "os.api_level=" .. ndk_sdkver) + end + end + + -- set custom settings + for _, setting in ipairs(configs.settings) do + table.insert(argv, "-s") + table.insert(argv, setting) + end + + -- set remote + if configs.remote then + table.insert(argv, "-r") + table.insert(argv, configs.remote) + end + + -- TODO set environments + if opt.plat == "android" then + local envs = {} + local cflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cflags", opt.plat)) + local cxxflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cxxflags", opt.plat)) + envs.CC = _conan_get_build_env("cc", opt.plat) + envs.CXX = _conan_get_build_env("cxx", opt.plat) + envs.AS = _conan_get_build_env("as", opt.plat) + envs.AR = _conan_get_build_env("ar", opt.plat) + envs.LD = _conan_get_build_env("ld", opt.plat) + envs.LDSHARED = _conan_get_build_env("sh", opt.plat) + envs.CPP = _conan_get_build_env("cpp", opt.plat) + envs.RANLIB = _conan_get_build_env("ranlib", opt.plat) + envs.CFLAGS = table.concat(cflags, ' ') + envs.CXXFLAGS = table.concat(cxxflags, ' ') + envs.ASFLAGS = table.concat(table.wrap(_conan_get_build_env("asflags", opt.plat)), ' ') + envs.ARFLAGS = table.concat(table.wrap(_conan_get_build_env("arflags", opt.plat)), ' ') + envs.LDFLAGS = table.concat(table.wrap(_conan_get_build_env("ldflags", opt.plat)), ' ') + envs.SHFLAGS = table.concat(table.wrap(_conan_get_build_env("shflags", opt.plat)), ' ') + local toolchain_ndk = toolchain.load("ndk", {plat = opt.plat, arch = opt.arch}) + local ndk_sysroot = toolchain_ndk:config("ndk_sysroot") + if ndk_sysroot then + table.insert(argv, "-e") + table.insert(argv, "CONAN_CMAKE_FIND_ROOT_PATH=" .. ndk_sysroot) + end + for k, v in pairs(envs) do + table.insert(argv, "-e") + table.insert(argv, k .. "=" .. v) + end + end + + -- do install + os.vrunv(conan.program, argv) + + -- leave build directory + os.cd(oldir) +end diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua new file mode 100644 index 000000000..4c9186d8f --- /dev/null +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -0,0 +1,282 @@ +--!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, TBOOX Open Source Group. +-- +-- @author ruki +-- @file install_package.lua +-- + +-- imports +import("core.base.option") +import("core.base.semver") +import("core.project.config") +import("core.tool.toolchain") +import("core.platform.platform") +import("lib.detect.find_tool") +import("devel.git") +import("net.fasturl") + +-- get build env +function _conan_get_build_env(name, plat) + local value = config.get(name) + if value == nil then + value = platform.toolconfig(name, plat) + end + if value == nil then + value = platform.tool(name, plat) + end + value = table.unique(table.wrap(value)) + if #value > 0 then + value = table.unwrap(value) + return value + end +end + +-- get build directory +function _conan_get_build_directory(name) + return path.absolute(path.join(config.buildir() or os.tmpdir(), ".conan", name)) +end + +-- generate conanfile.txt +function _conan_generate_conanfile(name, configs, opt) + + -- trace + dprint("generate %s ..", path.join(_conan_get_build_directory(name), "conanfile.txt")) + + -- get conan options, imports and build_requires + local options = table.wrap(configs.options) + local imports = table.wrap(configs.imports) + local build_requires = table.wrap(configs.build_requires) + + -- @see https://docs.conan.io/en/latest/systems_cross_building/cross_building.html + -- generate it + local conanfile = io.open("conanfile.txt", "w") + if conanfile then + conanfile:print("[generators]") + conanfile:print("xmake") + conanfile:print("[requires]") + local require_version = opt.require_version + if require_version ~= nil and require_version ~= "latest" then + conanfile:print("%s/%s", name, require_version) + else + conanfile:print("%s", name) + end + if #options > 0 then + conanfile:print("[options]") + conanfile:print("%s", table.concat(options, "\n")) + end + if #imports > 0 then + conanfile:print("[imports]") + conanfile:print("%s", table.concat(imports, "\n")) + end + if #build_requires > 0 then + conanfile:print("[build_requires]") + conanfile:print("%s", table.concat(build_requires, "\n")) + end + conanfile:close() + end +end + +-- install xmake generator +function _conan_install_xmake_generator(conan) + local xmake_generator_localdir = path.join(config.directory(), "conan", "xmake_generator") + if not os.isdir(xmake_generator_localdir) then + + -- sort main urls + local mainurls = {"https://github.com/xmake-io/conan-xmake_generator.git", + "https://gitlab.com/xmake-io/conan-xmake_generator.git", + "https://gitee.com/xmake-io/conan-xmake_generator.git"} + fasturl.add(mainurls) + mainurls = fasturl.sort(mainurls) + + -- clone xmake generator repository + local ok = false + for _, url in ipairs(mainurls) do + ok = try { function () git.clone(url, {depth = 1, branch = "0.1.0/testing", outputdir = xmake_generator_localdir}); return true end } + if ok then + break + end + end + if ok then + os.vrunv(conan.program, {"export", xmake_generator_localdir, "bincrafters/testing"}) + end + end +end + +-- install package +function main(conan, name, opt) + + -- get configs + opt = opt or {} + local configs = opt.configs or {} + + -- get build directory + local buildir = _conan_get_build_directory(name) + + -- clean the build directory + os.tryrm(buildir) + if not os.isdir(buildir) then + os.mkdir(buildir) + end + + -- enter build directory + local oldir = os.cd(buildir) + + -- install xmake generator + _conan_install_xmake_generator(conan) + + -- generate conanfile.txt + _conan_generate_conanfile(name, configs, opt) + + -- install package + local argv = {"install", "."} + if configs.build then + if configs.build == "all" then + table.insert(argv, "--build") + else + table.insert(argv, "--build=" .. configs.build) + end + end + + -- set platform + local plats = {macosx = "Macos", windows = "Windows", mingw = "Windows", linux = "Linux", cross = "Linux", iphoneos = "iOS", android = "Android"} + table.insert(argv, "-s") + local plat = plats[opt.plat] + if plat then + table.insert(argv, "os=" .. plat) + else + raise("cannot install package(%s) on platform(%s)!", name, opt.plat) + end + + -- set architecture + local archs = {x86_64 = "x86_64", + x64 = "x86_64", + i386 = "x86", + x86 = "x86", + armv7 = "armv7", + ["armv7-a"] = "armv7", -- for android, deprecated + ["armeabi"] = "armv7", -- for android, removed in ndk r17 + ["armeabi-v7a"] = "armv7", -- for android + armv7s = "armv7s", -- for iphoneos + arm64 = "armv8", -- for iphoneos + ["arm64-v8a"] = "armv8", -- for android + mips = "mips", + mips64 = "mips64"} + table.insert(argv, "-s") + local arch = archs[opt.arch] + if arch then + table.insert(argv, "arch=" .. arch) + else + raise("cannot install package(%s) for arch(%s)!", name, opt.arch) + end + + -- set build mode + table.insert(argv, "-s") + if opt.mode == "debug" then + table.insert(argv, "build_type=Debug") + else + table.insert(argv, "build_type=Release") + end + + -- set compiler settings + if opt.plat == "windows" then + local vsvers = {["2022"] = "17", + ["2019"] = "16", + ["2017"] = "15", + ["2015"] = "14", + ["2013"] = "12", + ["2012"] = "11", + ["2010"] = "10", + ["2008"] = "9", + ["2005"] = "8"} + local vs = assert(config.get("vs"), "vs not found!") + table.insert(argv, "-s") + table.insert(argv, "compiler=Visual Studio") + table.insert(argv, "-s") + table.insert(argv, "compiler.version=" .. assert(vsvers[vs], "unknown msvc version!")) + if configs.vs_runtime then + table.insert(argv, "-s") + table.insert(argv, "compiler.runtime=" .. configs.vs_runtime) + end + elseif opt.plat == "iphoneos" then + local target_minver = nil + local toolchain_xcode = toolchain.load("xcode", {plat = opt.plat, arch = opt.arch}) + if toolchain_xcode then + target_minver = toolchain_xcode:config("target_minver") + end + if target_minver and tonumber(target_minver) > 10 and (arch == "armv7" or arch == "armv7s" or arch == "x86") then + target_minver = "10" -- iOS 10 is the maximum deployment target for 32-bit targets + end + if target_minver then + table.insert(argv, "-s") + table.insert(argv, "os.version=" .. target_minver) + end + elseif opt.plat == "android" then + local ndk_sdkver = config.get("ndk_sdkver") + if ndk_sdkver then + table.insert(argv, "-s") + table.insert(argv, "os.api_level=" .. ndk_sdkver) + end + end + + -- set custom settings + for _, setting in ipairs(configs.settings) do + table.insert(argv, "-s") + table.insert(argv, setting) + end + + -- set remote + if configs.remote then + table.insert(argv, "-r") + table.insert(argv, configs.remote) + end + + -- TODO set environments + if opt.plat == "android" then + local envs = {} + local cflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cflags", opt.plat)) + local cxxflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cxxflags", opt.plat)) + envs.CC = _conan_get_build_env("cc", opt.plat) + envs.CXX = _conan_get_build_env("cxx", opt.plat) + envs.AS = _conan_get_build_env("as", opt.plat) + envs.AR = _conan_get_build_env("ar", opt.plat) + envs.LD = _conan_get_build_env("ld", opt.plat) + envs.LDSHARED = _conan_get_build_env("sh", opt.plat) + envs.CPP = _conan_get_build_env("cpp", opt.plat) + envs.RANLIB = _conan_get_build_env("ranlib", opt.plat) + envs.CFLAGS = table.concat(cflags, ' ') + envs.CXXFLAGS = table.concat(cxxflags, ' ') + envs.ASFLAGS = table.concat(table.wrap(_conan_get_build_env("asflags", opt.plat)), ' ') + envs.ARFLAGS = table.concat(table.wrap(_conan_get_build_env("arflags", opt.plat)), ' ') + envs.LDFLAGS = table.concat(table.wrap(_conan_get_build_env("ldflags", opt.plat)), ' ') + envs.SHFLAGS = table.concat(table.wrap(_conan_get_build_env("shflags", opt.plat)), ' ') + local toolchain_ndk = toolchain.load("ndk", {plat = opt.plat, arch = opt.arch}) + local ndk_sysroot = toolchain_ndk:config("ndk_sysroot") + if ndk_sysroot then + table.insert(argv, "-e") + table.insert(argv, "CONAN_CMAKE_FIND_ROOT_PATH=" .. ndk_sysroot) + end + for k, v in pairs(envs) do + table.insert(argv, "-e") + table.insert(argv, k .. "=" .. v) + end + end + + -- do install + os.vrunv(conan.program, argv) + + -- leave build directory + os.cd(oldir) +end -- cgit v1.3.1 From 427517545da92e25270c290887602c77e1cbc077 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 2 May 2023 00:54:00 +0800 Subject: add xmake_generator stub for conan --- .../package/manager/conan/install_package.lua | 1 + .../package/manager/conan/v2/install_package.lua | 62 +++++++++++++--------- .../conan/extensions/generators/xmake_generator.py | 17 ++++++ 3 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 xmake/scripts/conan/extensions/generators/xmake_generator.py diff --git a/xmake/modules/package/manager/conan/install_package.lua b/xmake/modules/package/manager/conan/install_package.lua index 2d234b241..48e9f132f 100644 --- a/xmake/modules/package/manager/conan/install_package.lua +++ b/xmake/modules/package/manager/conan/install_package.lua @@ -37,6 +37,7 @@ function main(name, opt) raise("conan not found!") end if conan.version and semver.compare(conan.version, "2.0.4") >= 0 then -- TODO 2.0.5 + -- https://github.com/conan-io/conan/issues/13709 import("package.manager.conan.v2.install_package")(conan, name, opt) elseif conan.version and semver.compare(conan.version, "2.0.0") < 0 then import("package.manager.conan.v1.install_package")(conan, name, opt) diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua index 4c9186d8f..3565e6455 100644 --- a/xmake/modules/package/manager/conan/v2/install_package.lua +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -64,8 +64,6 @@ function _conan_generate_conanfile(name, configs, opt) -- generate it local conanfile = io.open("conanfile.txt", "w") if conanfile then - conanfile:print("[generators]") - conanfile:print("xmake") conanfile:print("[requires]") local require_version = opt.require_version if require_version ~= nil and require_version ~= "latest" then @@ -89,29 +87,25 @@ function _conan_generate_conanfile(name, configs, opt) end end +-- get conan home directory +function _conan_get_homedir(conan) + local homedir = _g.homedir + if homedir == nil then + homedir = try {function () return os.iorunv(conan.program, {"config", "home"}) end} + _g.homedir = homedir + end + return homedir +end + -- install xmake generator +-- @see https://github.com/conan-io/conan/pull/13718 +-- function _conan_install_xmake_generator(conan) - local xmake_generator_localdir = path.join(config.directory(), "conan", "xmake_generator") - if not os.isdir(xmake_generator_localdir) then - - -- sort main urls - local mainurls = {"https://github.com/xmake-io/conan-xmake_generator.git", - "https://gitlab.com/xmake-io/conan-xmake_generator.git", - "https://gitee.com/xmake-io/conan-xmake_generator.git"} - fasturl.add(mainurls) - mainurls = fasturl.sort(mainurls) - - -- clone xmake generator repository - local ok = false - for _, url in ipairs(mainurls) do - ok = try { function () git.clone(url, {depth = 1, branch = "0.1.0/testing", outputdir = xmake_generator_localdir}); return true end } - if ok then - break - end - end - if ok then - os.vrunv(conan.program, {"export", xmake_generator_localdir, "bincrafters/testing"}) - end + local homedir = assert(_conan_get_homedir(conan), "cannot get conan home") + local scriptfile_now = path.join(os.programdir(), "scripts", "conan", "extensions", "generators", "xmake_generator.py") + local scriptfile_installed = path.join(homedir, "extensions", "generators", "xmake_generator.py") + if not os.isfile(scriptfile_installed) or os.mtime(scriptfile_now) > os.mtime(scriptfile_installed) then + os.vrunv(conan.program, {"config", "install", path.join(os.programdir(), "scripts", "conan")}) end end @@ -140,8 +134,28 @@ function main(conan, name, opt) -- generate conanfile.txt _conan_generate_conanfile(name, configs, opt) + io.writefile("profile_build.txt", [[ + [settings] +arch=x86_64 +build_type=Release +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=11 +os=Linux]]) + + io.writefile("profile_host.txt", [[ + [settings] +arch=x86_64 +build_type=Release +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=11 +os=Linux]]) + -- install package - local argv = {"install", "."} + local argv = {"install", ".", "-g", "XmakeGenerator", "--profile:build=profile_build.txt", "--profile:host=profile_host.txt"} if configs.build then if configs.build == "all" then table.insert(argv, "--build") diff --git a/xmake/scripts/conan/extensions/generators/xmake_generator.py b/xmake/scripts/conan/extensions/generators/xmake_generator.py new file mode 100644 index 000000000..8a28e9dfd --- /dev/null +++ b/xmake/scripts/conan/extensions/generators/xmake_generator.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from conan import ConanFile +from conan.tools.files import save, load +from conan.tools.microsoft import unix_path, VCVars, is_msvc +from conan.errors import ConanInvalidConfiguration +from conan.errors import ConanException +from conans.model.build_info import CppInfo + +class XmakeGenerator: + def __init__(self, conanfile): + self._conanfile = conanfile + def generate(self): + print("XmakeGenerator generate") + + -- cgit v1.3.1 From 3df1ad8688967a638f3ef5825a0011505c02dc55 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 2 May 2023 00:56:39 +0800 Subject: improve xmake generator --- .../conan/extensions/generators/xmake_generator.py | 26 +++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/xmake/scripts/conan/extensions/generators/xmake_generator.py b/xmake/scripts/conan/extensions/generators/xmake_generator.py index 8a28e9dfd..f95164acc 100644 --- a/xmake/scripts/conan/extensions/generators/xmake_generator.py +++ b/xmake/scripts/conan/extensions/generators/xmake_generator.py @@ -12,6 +12,30 @@ class XmakeGenerator: def __init__(self, conanfile): self._conanfile = conanfile def generate(self): - print("XmakeGenerator generate") + print("XmakeGenerator: generating build info ..") + + # Extract all dependencies + host_req = self._conanfile.dependencies.host + test_req = self._conanfile.dependencies.test + build_req = self._conanfile.dependencies.build + + # Merge into one list + full_req = list(host_req.items()) \ + + list(test_req.items()) \ + + list(build_req.items()) + + # Process dependencies and accumulate globally required data + pkg_files = [] + dep_names = [] + for require, dep in full_req: + dep_name = require.ref.name + dep_names.append(dep_name) + print("dep_name", dep_name) + + # Convert and aggregate dependency's + dep_cppinfo = dep.cpp_info.copy() + dep_cppinfo.set_relative_base_folder(dep.package_folder) + dep_aggregate = dep_cppinfo.aggregated_components() + print("dep_aggregate", dep_aggregate) -- cgit v1.3.1 From 13d11b2929915f3118cd91845b31d2a6e0d55015 Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 2 May 2023 21:05:45 +0800 Subject: generate conan build info --- .../conan/extensions/generators/xmake_generator.py | 92 +++++++++++++++++++--- 1 file changed, 83 insertions(+), 9 deletions(-) diff --git a/xmake/scripts/conan/extensions/generators/xmake_generator.py b/xmake/scripts/conan/extensions/generators/xmake_generator.py index f95164acc..c7c4b2a0d 100644 --- a/xmake/scripts/conan/extensions/generators/xmake_generator.py +++ b/xmake/scripts/conan/extensions/generators/xmake_generator.py @@ -11,31 +11,105 @@ from conans.model.build_info import CppInfo class XmakeGenerator: def __init__(self, conanfile): self._conanfile = conanfile + + def filename(self): + return "conanbuildinfo.xmake.lua" + def generate(self): print("XmakeGenerator: generating build info ..") - # Extract all dependencies + # extract all dependencies host_req = self._conanfile.dependencies.host test_req = self._conanfile.dependencies.test build_req = self._conanfile.dependencies.build - # Merge into one list full_req = list(host_req.items()) \ + list(test_req.items()) \ + list(build_req.items()) - # Process dependencies and accumulate globally required data - pkg_files = [] - dep_names = [] for require, dep in full_req: - dep_name = require.ref.name - dep_names.append(dep_name) - print("dep_name", dep_name) + #dep_name = require.ref.name - # Convert and aggregate dependency's + # get aggregate dependency's cppinfo dep_cppinfo = dep.cpp_info.copy() dep_cppinfo.set_relative_base_folder(dep.package_folder) dep_aggregate = dep_cppinfo.aggregated_components() print("dep_aggregate", dep_aggregate) + # format deps + deps = XmakeDepsFormatter(dep_aggregate) + + # make template + plat = "Linux" + arch = "x86_64" + mode = "Release" + template = (' {plat}_{arch}_{mode} = \n' + ' {{\n' + ' includedirs = {{{deps.include_paths}}},\n' + ' linkdirs = {{{deps.lib_paths}}},\n' + ' links = {{{deps.libs}}},\n' + ' frameworkdirs = {{{deps.framework_paths}}},\n' + ' frameworks = {{{deps.frameworks}}},\n' + ' syslinks = {{{deps.system_libs}}},\n' + ' defines = {{{deps.defines}}},\n' + ' cxxflags = {{{deps.cppflags}}},\n' + ' cflags = {{{deps.cflags}}},\n' + ' shflags = {{{deps.sharedlinkflags}}},\n' + ' ldflags = {{{deps.exelinkflags}}},\n' + ' __bindirs = {{{deps.bin_paths}}},\n' + ' __resdirs = {{{deps.res_paths}}},\n' + ' __srcdirs = {{{deps.src_paths}}}\n' + ' }}') + + # make sections + sections = [] + sections.append(template.format(plat = plat, arch = arch, mode = mode, deps = deps)) + + # make content + content = "{\n" + ",\n".join(sections) + "\n}" + print(content) + + # save content to file + with open(self.filename(), 'w') as file: + file.write(content) + +class XmakeDepsFormatter(object): + def __prepare_process_escape_character(self, raw_string): + if raw_string.find('\"') != -1: + raw_string = raw_string.replace("\"","\\\"") + return raw_string + + def __filter_char(self, raw_string): + return self.__prepare_process_escape_character(raw_string) + + def __init__(self, deps_cpp_info): + includedirs = deps_cpp_info._includedirs if deps_cpp_info._includedirs else [] + libdirs = deps_cpp_info._libdirs if deps_cpp_info._libdirs else [] + bindirs = deps_cpp_info._bindirs if deps_cpp_info._bindirs else [] + resdirs = deps_cpp_info._resdirs if deps_cpp_info._resdirs else [] + srcdirs = deps_cpp_info._srcdirs if deps_cpp_info._srcdirs else [] + frameworkdirs = deps_cpp_info._frameworkdirs if deps_cpp_info._frameworkdirs else [] + libs = deps_cpp_info._libs if deps_cpp_info._libs else [] + frameworks = deps_cpp_info._frameworks if deps_cpp_info._frameworks else [] + system_libs = deps_cpp_info._system_libs if deps_cpp_info._system_libs else [] + defines = deps_cpp_info._defines if deps_cpp_info._defines else [] + cxxflags = deps_cpp_info._cxxflags if deps_cpp_info._cxxflags else [] + cflags = deps_cpp_info._cflags if deps_cpp_info._cflags else [] + sharedlinkflags = deps_cpp_info._sharedlinkflags if deps_cpp_info._sharedlinkflags else [] + exelinkflags = deps_cpp_info._exelinkflags if deps_cpp_info._exelinkflags else [] + + self.include_paths = ",\n".join('"%s"' % self.__filter_char(p.replace("\\", "/")) for p in includedirs) + self.lib_paths = ",\n".join('"%s"' % self.__filter_char(p.replace("\\", "/")) for p in libdirs) + self.bin_paths = ",\n".join('"%s"' % self.__filter_char(p.replace("\\", "/")) for p in bindirs) + self.res_paths = ",\n".join('"%s"' % self.__filter_char(p.replace("\\", "/")) for p in resdirs) + self.src_paths = ",\n".join('"%s"' % self.__filter_char(p.replace("\\", "/")) for p in srcdirs) + self.framework_paths = ",\n".join('"%s"' % self.__filter_char(p.replace("\\", "/")) for p in frameworkdirs) + self.libs = ", ".join('"%s"' % p for p in libs) + self.frameworks = ", ".join('"%s"' % p for p in frameworks) + self.system_libs = ", ".join('"%s"' % p for p in system_libs) + self.defines = ", ".join('"%s"' % self.__filter_char(p) for p in defines) + self.cppflags = ", ".join('"%s"' % p for p in cxxflags) + self.cflags = ", ".join('"%s"' % p for p in cflags) + self.sharedlinkflags = ", ".join('"%s"' % p for p in sharedlinkflags) + self.exelinkflags = ", ".join('"%s"' % p for p in exelinkflags) -- cgit v1.3.1 From 54705be6387cddcf0a8689a5f62114463e26189b Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 2 May 2023 21:06:37 +0800 Subject: fix plat/arch/mode for conan generator --- xmake/scripts/conan/extensions/generators/xmake_generator.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xmake/scripts/conan/extensions/generators/xmake_generator.py b/xmake/scripts/conan/extensions/generators/xmake_generator.py index c7c4b2a0d..a7298615f 100644 --- a/xmake/scripts/conan/extensions/generators/xmake_generator.py +++ b/xmake/scripts/conan/extensions/generators/xmake_generator.py @@ -34,15 +34,14 @@ class XmakeGenerator: dep_cppinfo = dep.cpp_info.copy() dep_cppinfo.set_relative_base_folder(dep.package_folder) dep_aggregate = dep_cppinfo.aggregated_components() - print("dep_aggregate", dep_aggregate) # format deps deps = XmakeDepsFormatter(dep_aggregate) # make template - plat = "Linux" - arch = "x86_64" - mode = "Release" + plat = self._conanfile.settings.os + arch = self._conanfile.settings.arch + mode = self._conanfile.settings.build_type template = (' {plat}_{arch}_{mode} = \n' ' {{\n' ' includedirs = {{{deps.include_paths}}},\n' -- cgit v1.3.1 From 4f89cfadfd187382802dbc3ef2332eadc6f548af Mon Sep 17 00:00:00 2001 From: ruki Date: Tue, 2 May 2023 22:53:15 +0800 Subject: remove imports --- tests/projects/package/conan/xmake.lua | 4 ++-- xmake/modules/package/manager/conan/configurations.lua | 4 ++-- xmake/modules/package/manager/conan/v2/install_package.lua | 5 ----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/projects/package/conan/xmake.lua b/tests/projects/package/conan/xmake.lua index 3021fab7c..fcd36e3a8 100644 --- a/tests/projects/package/conan/xmake.lua +++ b/tests/projects/package/conan/xmake.lua @@ -1,6 +1,6 @@ add_requires("conan::zlib 1.2.11", {alias = "zlib", debug = true}) -add_requires("conan::openssl 1.1.1g", {alias = "openssl", - configs = {options = "OpenSSL:shared=True"}}) +add_requires("conan::openssl 1.1.1t", {alias = "openssl", + configs = {options = "openssl/*:shared=True"}}) target("test") set_kind("binary") diff --git a/xmake/modules/package/manager/conan/configurations.lua b/xmake/modules/package/manager/conan/configurations.lua index 6f99742f1..8667ab112 100644 --- a/xmake/modules/package/manager/conan/configurations.lua +++ b/xmake/modules/package/manager/conan/configurations.lua @@ -24,9 +24,9 @@ function main() { build = {description = "Use it to choose if you want to build from sources.", default = "missing", values = {"all", "never", "missing", "outdated"}}, remote = {description = "Set the conan remote server."}, - options = {description = "Set the options values, e.g. OpenSSL:shared=True"}, - imports = {description = "Set the imports for conan."}, + options = {description = "Set the options values, e.g. shared=True"}, -- TODO settings = {description = "Set the build settings for conan."}, + imports = {description = "Set the imports for conan 1.x, it has been deprecated in conan 2.x."}, build_requires = {description = "Set the build requires for conan."} } end diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua index 3565e6455..694fd5ff1 100644 --- a/xmake/modules/package/manager/conan/v2/install_package.lua +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -57,7 +57,6 @@ function _conan_generate_conanfile(name, configs, opt) -- get conan options, imports and build_requires local options = table.wrap(configs.options) - local imports = table.wrap(configs.imports) local build_requires = table.wrap(configs.build_requires) -- @see https://docs.conan.io/en/latest/systems_cross_building/cross_building.html @@ -75,10 +74,6 @@ function _conan_generate_conanfile(name, configs, opt) conanfile:print("[options]") conanfile:print("%s", table.concat(options, "\n")) end - if #imports > 0 then - conanfile:print("[imports]") - conanfile:print("%s", table.concat(imports, "\n")) - end if #build_requires > 0 then conanfile:print("[build_requires]") conanfile:print("%s", table.concat(build_requires, "\n")) -- cgit v1.3.1 From a39ce82c6a22f890e55187a95a7d105d2558ac04 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 3 May 2023 00:26:24 +0800 Subject: improve conan options --- tests/projects/package/conan/xmake.lua | 2 +- .../package/manager/conan/configurations.lua | 2 +- .../package/manager/conan/v1/install_package.lua | 7 ++- .../package/manager/conan/v2/install_package.lua | 64 +++++++++++++++------- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/tests/projects/package/conan/xmake.lua b/tests/projects/package/conan/xmake.lua index fcd36e3a8..ecf8c6b60 100644 --- a/tests/projects/package/conan/xmake.lua +++ b/tests/projects/package/conan/xmake.lua @@ -1,6 +1,6 @@ add_requires("conan::zlib 1.2.11", {alias = "zlib", debug = true}) add_requires("conan::openssl 1.1.1t", {alias = "openssl", - configs = {options = "openssl/*:shared=True"}}) + configs = {options = "shared=True"}}) target("test") set_kind("binary") diff --git a/xmake/modules/package/manager/conan/configurations.lua b/xmake/modules/package/manager/conan/configurations.lua index 8667ab112..8e03cf9a3 100644 --- a/xmake/modules/package/manager/conan/configurations.lua +++ b/xmake/modules/package/manager/conan/configurations.lua @@ -24,7 +24,7 @@ function main() { build = {description = "Use it to choose if you want to build from sources.", default = "missing", values = {"all", "never", "missing", "outdated"}}, remote = {description = "Set the conan remote server."}, - options = {description = "Set the options values, e.g. shared=True"}, -- TODO + options = {description = "Set the options values, e.g. shared=True"}, settings = {description = "Set the build settings for conan."}, imports = {description = "Set the imports for conan 1.x, it has been deprecated in conan 2.x."}, build_requires = {description = "Set the build requires for conan."} diff --git a/xmake/modules/package/manager/conan/v1/install_package.lua b/xmake/modules/package/manager/conan/v1/install_package.lua index f8c60ad72..e443e585b 100644 --- a/xmake/modules/package/manager/conan/v1/install_package.lua +++ b/xmake/modules/package/manager/conan/v1/install_package.lua @@ -75,7 +75,12 @@ function _conan_generate_conanfile(name, configs, opt) end if #options > 0 then conanfile:print("[options]") - conanfile:print("%s", table.concat(options, "\n")) + for _, item in ipairs(options) do + if not item:find(":", 1, true) then + item = name .. ":" .. item + end + conanfile:print("%s", item) + end end if #imports > 0 then conanfile:print("[imports]") diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua index 694fd5ff1..f5181022d 100644 --- a/xmake/modules/package/manager/conan/v2/install_package.lua +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -59,7 +59,8 @@ function _conan_generate_conanfile(name, configs, opt) local options = table.wrap(configs.options) local build_requires = table.wrap(configs.build_requires) - -- @see https://docs.conan.io/en/latest/systems_cross_building/cross_building.html + -- @see https://docs.conan.io/1/migrating_to_2.0/recipes.html + -- https://docs.conan.io/en/latest/systems_cross_building/cross_building.html -- generate it local conanfile = io.open("conanfile.txt", "w") if conanfile then @@ -72,10 +73,15 @@ function _conan_generate_conanfile(name, configs, opt) end if #options > 0 then conanfile:print("[options]") - conanfile:print("%s", table.concat(options, "\n")) + for _, item in ipairs(options) do + if not item:find(":", 1, true) then + item = name .. "/*:" .. item + end + conanfile:print("%s", item) + end end if #build_requires > 0 then - conanfile:print("[build_requires]") + conanfile:print("[tool_requires]") conanfile:print("%s", table.concat(build_requires, "\n")) end conanfile:close() @@ -104,6 +110,36 @@ function _conan_install_xmake_generator(conan) end end +-- generate host profile +function _conan_generate_host_profile(configs, opt) + + io.writefile("profile_host.txt", [[ + [settings] +arch=x86_64 +build_type=Release +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=11 +os=Linux]]) + +end + +-- generate build profile +function _conan_generate_build_profile(configs, opt) + + io.writefile("profile_build.txt", [[ + [settings] +arch=x86_64 +build_type=Release +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=11 +os=Linux]]) + +end + -- install package function main(conan, name, opt) @@ -129,25 +165,11 @@ function main(conan, name, opt) -- generate conanfile.txt _conan_generate_conanfile(name, configs, opt) - io.writefile("profile_build.txt", [[ - [settings] -arch=x86_64 -build_type=Release -compiler=gcc -compiler.cppstd=gnu17 -compiler.libcxx=libstdc++11 -compiler.version=11 -os=Linux]]) + -- generate host profile + _conan_generate_host_profile(configs, opt) - io.writefile("profile_host.txt", [[ - [settings] -arch=x86_64 -build_type=Release -compiler=gcc -compiler.cppstd=gnu17 -compiler.libcxx=libstdc++11 -compiler.version=11 -os=Linux]]) + -- generate build profile + _conan_generate_build_profile(configs, opt) -- install package local argv = {"install", ".", "-g", "XmakeGenerator", "--profile:build=profile_build.txt", "--profile:host=profile_host.txt"} -- cgit v1.3.1 From 006ba41d2e4d78ef59bcf109c71320682e743832 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 3 May 2023 00:33:19 +0800 Subject: generate profile --- .../package/manager/conan/v2/install_package.lua | 204 ++++++++++----------- 1 file changed, 100 insertions(+), 104 deletions(-) diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua index f5181022d..82e53aad3 100644 --- a/xmake/modules/package/manager/conan/v2/install_package.lua +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -110,34 +110,110 @@ function _conan_install_xmake_generator(conan) end end --- generate host profile -function _conan_generate_host_profile(configs, opt) +-- get arch +function _conan_get_arch(arch) + local map = {x86_64 = "x86_64", + x64 = "x86_64", + i386 = "x86", + x86 = "x86", + armv7 = "armv7", + ["armv7-a"] = "armv7", -- for android, deprecated + ["armeabi"] = "armv7", -- for android, removed in ndk r17 + ["armeabi-v7a"] = "armv7", -- for android + armv7s = "armv7s", -- for iphoneos + arm64 = "armv8", -- for iphoneos + ["arm64-v8a"] = "armv8", -- for android + mips = "mips", + mips64 = "mips64"} + return assert(map[arch], "unknown arch(%s)!", arch) +end - io.writefile("profile_host.txt", [[ - [settings] -arch=x86_64 -build_type=Release -compiler=gcc -compiler.cppstd=gnu17 -compiler.libcxx=libstdc++11 -compiler.version=11 -os=Linux]]) +-- get os +function _conan_get_os(plat) + local map = {macosx = "Macos", + windows = "Windows", + mingw = "Windows", + linux = "Linux", + cross = "Linux", + iphoneos = "iOS", + android = "Android"} + return assert(map[plat], "unknown os(%s)!", plat) +end +-- get build type +function _conan_get_build_type(mode) + if mode == "debug" then + return "Debug" + else + return "Release" + end end --- generate build profile -function _conan_generate_build_profile(configs, opt) +-- generate compiler profile +function _conan_generate_compiler_profile(profile, configs, opt) + local plat = opt.plat + local arch = opt.arch + if plat == "windows" then + local vsvers = {["2022"] = "17", + ["2019"] = "16", + ["2017"] = "15", + ["2015"] = "14", + ["2013"] = "12", + ["2012"] = "11", + ["2010"] = "10", + ["2008"] = "9", + ["2005"] = "8"} + local vs = assert(config.get("vs"), "vs not found!") + profile:print("compiler=Visual Studio") + profile:print("compiler.version=" .. assert(vsvers[vs], "unknown msvc version!")) + if configs.vs_runtime then + profile:print("compiler.runtime=" .. configs.vs_runtime) + end + elseif plat == "iphoneos" then + local target_minver = nil + local toolchain_xcode = toolchain.load("xcode", {plat = plat, arch = arch}) + if toolchain_xcode then + target_minver = toolchain_xcode:config("target_minver") + end + if target_minver and tonumber(target_minver) > 10 and (arch == "armv7" or arch == "armv7s" or arch == "x86") then + target_minver = "10" -- iOS 10 is the maximum deployment target for 32-bit targets + end + if target_minver then + profile:print("os.version=" .. target_minver) + end + elseif plat == "android" then + local ndk_sdkver = config.get("ndk_sdkver") + if ndk_sdkver then + profile:print("os.api_level=" .. ndk_sdkver) + end + else + profile:print("compiler=gcc") + profile:print("compiler.cppstd=gnu17") + profile:print("compiler.libcxx=libstdc++11") + profile:print("compiler.version=11") + end +end - io.writefile("profile_build.txt", [[ - [settings] -arch=x86_64 -build_type=Release -compiler=gcc -compiler.cppstd=gnu17 -compiler.libcxx=libstdc++11 -compiler.version=11 -os=Linux]]) +-- generate host profile +function _conan_generate_host_profile(configs, opt) + local profile = io.open("profile_host.txt", "w") + profile:print("[settings]") + profile:print("arch=%s", _conan_get_arch(os.arch())) + profile:print("build_type=%s", _conan_get_build_type(opt.mode)) + profile:print("os=%s", _conan_get_os(os.host())) + _conan_generate_compiler_profile(profile, configs, {plat = os.host(), arch = os.arch()}) + profile:close() +end +-- generate build profile +function _conan_generate_build_profile(configs, opt) + local profile = io.open("profile_build.txt", "w") + profile:print("[settings]") + profile:print("arch=%s", _conan_get_arch(opt.arch)) + profile:print("build_type=%s", _conan_get_build_type(opt.mode)) + profile:print("os=%s", _conan_get_os(opt.plat)) + _conan_generate_compiler_profile(profile, configs, opt) + profile:close() end -- install package @@ -172,7 +248,8 @@ function main(conan, name, opt) _conan_generate_build_profile(configs, opt) -- install package - local argv = {"install", ".", "-g", "XmakeGenerator", "--profile:build=profile_build.txt", "--profile:host=profile_host.txt"} + local argv = {"install", ".", "-g", "XmakeGenerator", + "--profile:build=profile_build.txt", "--profile:host=profile_host.txt"} if configs.build then if configs.build == "all" then table.insert(argv, "--build") @@ -181,87 +258,6 @@ function main(conan, name, opt) end end - -- set platform - local plats = {macosx = "Macos", windows = "Windows", mingw = "Windows", linux = "Linux", cross = "Linux", iphoneos = "iOS", android = "Android"} - table.insert(argv, "-s") - local plat = plats[opt.plat] - if plat then - table.insert(argv, "os=" .. plat) - else - raise("cannot install package(%s) on platform(%s)!", name, opt.plat) - end - - -- set architecture - local archs = {x86_64 = "x86_64", - x64 = "x86_64", - i386 = "x86", - x86 = "x86", - armv7 = "armv7", - ["armv7-a"] = "armv7", -- for android, deprecated - ["armeabi"] = "armv7", -- for android, removed in ndk r17 - ["armeabi-v7a"] = "armv7", -- for android - armv7s = "armv7s", -- for iphoneos - arm64 = "armv8", -- for iphoneos - ["arm64-v8a"] = "armv8", -- for android - mips = "mips", - mips64 = "mips64"} - table.insert(argv, "-s") - local arch = archs[opt.arch] - if arch then - table.insert(argv, "arch=" .. arch) - else - raise("cannot install package(%s) for arch(%s)!", name, opt.arch) - end - - -- set build mode - table.insert(argv, "-s") - if opt.mode == "debug" then - table.insert(argv, "build_type=Debug") - else - table.insert(argv, "build_type=Release") - end - - -- set compiler settings - if opt.plat == "windows" then - local vsvers = {["2022"] = "17", - ["2019"] = "16", - ["2017"] = "15", - ["2015"] = "14", - ["2013"] = "12", - ["2012"] = "11", - ["2010"] = "10", - ["2008"] = "9", - ["2005"] = "8"} - local vs = assert(config.get("vs"), "vs not found!") - table.insert(argv, "-s") - table.insert(argv, "compiler=Visual Studio") - table.insert(argv, "-s") - table.insert(argv, "compiler.version=" .. assert(vsvers[vs], "unknown msvc version!")) - if configs.vs_runtime then - table.insert(argv, "-s") - table.insert(argv, "compiler.runtime=" .. configs.vs_runtime) - end - elseif opt.plat == "iphoneos" then - local target_minver = nil - local toolchain_xcode = toolchain.load("xcode", {plat = opt.plat, arch = opt.arch}) - if toolchain_xcode then - target_minver = toolchain_xcode:config("target_minver") - end - if target_minver and tonumber(target_minver) > 10 and (arch == "armv7" or arch == "armv7s" or arch == "x86") then - target_minver = "10" -- iOS 10 is the maximum deployment target for 32-bit targets - end - if target_minver then - table.insert(argv, "-s") - table.insert(argv, "os.version=" .. target_minver) - end - elseif opt.plat == "android" then - local ndk_sdkver = config.get("ndk_sdkver") - if ndk_sdkver then - table.insert(argv, "-s") - table.insert(argv, "os.api_level=" .. ndk_sdkver) - end - end - -- set custom settings for _, setting in ipairs(configs.settings) do table.insert(argv, "-s") -- cgit v1.3.1 From a3b4b157db9eab2a98929429952e9ec4b05a9ebf Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 3 May 2023 00:39:38 +0800 Subject: improve conan2 for macos/clang --- .../package/manager/conan/v2/install_package.lua | 25 ++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua index 82e53aad3..399665136 100644 --- a/xmake/modules/package/manager/conan/v2/install_package.lua +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -187,10 +187,27 @@ function _conan_generate_compiler_profile(profile, configs, opt) profile:print("os.api_level=" .. ndk_sdkver) end else - profile:print("compiler=gcc") - profile:print("compiler.cppstd=gnu17") - profile:print("compiler.libcxx=libstdc++11") - profile:print("compiler.version=11") + local program, toolname = platform.tool("cc", plat, arch) + if toolname == "gcc" or toolname == "clang" then + local version + local gcc = find_tool(toolname, {program = program, version = true}) + if gcc and gcc.version then + local v = semver.try_parse(gcc.version) + if v then + version = v:major() + end + end + profile:print("compiler=" .. toolname) + profile:print("compiler.cppstd=gnu17") + if toolname == "clang" then + profile:print("compiler.libcxx=libc++") + else + profile:print("compiler.libcxx=libstdc++11") + end + if version then + profile:print("compiler.version=" .. version) + end + end end end -- cgit v1.3.1 From 9dee54ceb13907227b61ee434dd761dfba996fa4 Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 3 May 2023 00:48:15 +0800 Subject: improve msvc for conan2 --- .../package/manager/conan/v2/install_package.lua | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua index 399665136..cd8b7c7a0 100644 --- a/xmake/modules/package/manager/conan/v2/install_package.lua +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -154,17 +154,15 @@ function _conan_generate_compiler_profile(profile, configs, opt) local plat = opt.plat local arch = opt.arch if plat == "windows" then - local vsvers = {["2022"] = "17", - ["2019"] = "16", - ["2017"] = "15", - ["2015"] = "14", - ["2013"] = "12", - ["2012"] = "11", - ["2010"] = "10", - ["2008"] = "9", - ["2005"] = "8"} + -- https://github.com/conan-io/conan/blob/353c63b16c31c90d370305b5cbb5dc175cf8a443/conan/tools/microsoft/visual.py#L13 + local vsvers = {["2022"] = "193", + ["2019"] = "192", + ["2017"] = "191", + ["2015"] = "190", + ["2013"] = "180", + ["2012"] = "170"} local vs = assert(config.get("vs"), "vs not found!") - profile:print("compiler=Visual Studio") + profile:print("compiler=msvc") profile:print("compiler.version=" .. assert(vsvers[vs], "unknown msvc version!")) if configs.vs_runtime then profile:print("compiler.runtime=" .. configs.vs_runtime) -- cgit v1.3.1 From a0f212e57a8b5ad1c550ef61f418884989c7c17f Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 3 May 2023 00:56:02 +0800 Subject: improve ios/android build for conan2 --- .../package/manager/conan/v2/install_package.lua | 100 ++++++++++++--------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/xmake/modules/package/manager/conan/v2/install_package.lua b/xmake/modules/package/manager/conan/v2/install_package.lua index cd8b7c7a0..af2ec771c 100644 --- a/xmake/modules/package/manager/conan/v2/install_package.lua +++ b/xmake/modules/package/manager/conan/v2/install_package.lua @@ -151,6 +151,7 @@ end -- generate compiler profile function _conan_generate_compiler_profile(profile, configs, opt) + local conf local plat = opt.plat local arch = opt.arch if plat == "windows" then @@ -169,9 +170,9 @@ function _conan_generate_compiler_profile(profile, configs, opt) end elseif plat == "iphoneos" then local target_minver = nil - local toolchain_xcode = toolchain.load("xcode", {plat = plat, arch = arch}) - if toolchain_xcode then - target_minver = toolchain_xcode:config("target_minver") + local xcode = toolchain.load("xcode", {plat = plat, arch = arch}) + if xcode then + target_minver = xcode:config("target_minver") end if target_minver and tonumber(target_minver) > 10 and (arch == "armv7" or arch == "armv7s" or arch == "x86") then target_minver = "10" -- iOS 10 is the maximum deployment target for 32-bit targets @@ -179,18 +180,52 @@ function _conan_generate_compiler_profile(profile, configs, opt) if target_minver then profile:print("os.version=" .. target_minver) end + local simulator = xcode:config("appledev") == "simulator" + profile:print("os.sdk=" .. (simulator and "iphonesimulator" or "iphoneos")) + profile:print("compiler=clang") + local version + local result = find_tool("clang", {version = true}) + if result and result.version then + local v = semver.try_parse(result.version) + if v then + version = v:major() + end + end + if version then + profile:print("compiler.version=" .. version) + end elseif plat == "android" then - local ndk_sdkver = config.get("ndk_sdkver") + local ndk = toolchain.load("ndk", {plat = plat, arch = arch}) + local ndk_sdkver = ndk:config("ndk_sdkver") if ndk_sdkver then profile:print("os.api_level=" .. ndk_sdkver) end + local ndk_cxxstl = config.get("ndk_cxxstl") + if ndk_cxxstl then + profile:print("compiler.libcxx=" .. ndk_cxxstl) + end + local version + local program, toolname = ndk:tool("cc") + local result = find_tool(toolname, {program = program, version = true}) + if result and result.version then + local v = semver.try_parse(result.version) + if v then + version = v:major() + end + end + profile:print("compiler=" .. toolname) + if version then + profile:print("compiler.version=" .. version) + end + conf = {} + conf["tools.android:ndk_path"] = ndk:config("ndk") else local program, toolname = platform.tool("cc", plat, arch) if toolname == "gcc" or toolname == "clang" then local version - local gcc = find_tool(toolname, {program = program, version = true}) - if gcc and gcc.version then - local v = semver.try_parse(gcc.version) + local result = find_tool(toolname, {program = program, version = true}) + if result and result.version then + local v = semver.try_parse(result.version) if v then version = v:major() end @@ -207,11 +242,19 @@ function _conan_generate_compiler_profile(profile, configs, opt) end end end + + if conf then + profile:print("") + profile:print("[conf]") + for k, v in pairs(conf) do + profile:print("%s=%s", k, v) + end + end end --- generate host profile -function _conan_generate_host_profile(configs, opt) - local profile = io.open("profile_host.txt", "w") +-- generate build profile +function _conan_generate_build_profile(configs, opt) + local profile = io.open("profile_build.txt", "w") profile:print("[settings]") profile:print("arch=%s", _conan_get_arch(os.arch())) profile:print("build_type=%s", _conan_get_build_type(opt.mode)) @@ -220,9 +263,9 @@ function _conan_generate_host_profile(configs, opt) profile:close() end --- generate build profile -function _conan_generate_build_profile(configs, opt) - local profile = io.open("profile_build.txt", "w") +-- generate host profile +function _conan_generate_host_profile(configs, opt) + local profile = io.open("profile_host.txt", "w") profile:print("[settings]") profile:print("arch=%s", _conan_get_arch(opt.arch)) profile:print("build_type=%s", _conan_get_build_type(opt.mode)) @@ -285,37 +328,6 @@ function main(conan, name, opt) table.insert(argv, configs.remote) end - -- TODO set environments - if opt.plat == "android" then - local envs = {} - local cflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cflags", opt.plat)) - local cxxflags = table.join(table.wrap(_conan_get_build_env("cxflags", opt.plat)), _conan_get_build_env("cxxflags", opt.plat)) - envs.CC = _conan_get_build_env("cc", opt.plat) - envs.CXX = _conan_get_build_env("cxx", opt.plat) - envs.AS = _conan_get_build_env("as", opt.plat) - envs.AR = _conan_get_build_env("ar", opt.plat) - envs.LD = _conan_get_build_env("ld", opt.plat) - envs.LDSHARED = _conan_get_build_env("sh", opt.plat) - envs.CPP = _conan_get_build_env("cpp", opt.plat) - envs.RANLIB = _conan_get_build_env("ranlib", opt.plat) - envs.CFLAGS = table.concat(cflags, ' ') - envs.CXXFLAGS = table.concat(cxxflags, ' ') - envs.ASFLAGS = table.concat(table.wrap(_conan_get_build_env("asflags", opt.plat)), ' ') - envs.ARFLAGS = table.concat(table.wrap(_conan_get_build_env("arflags", opt.plat)), ' ') - envs.LDFLAGS = table.concat(table.wrap(_conan_get_build_env("ldflags", opt.plat)), ' ') - envs.SHFLAGS = table.concat(table.wrap(_conan_get_build_env("shflags", opt.plat)), ' ') - local toolchain_ndk = toolchain.load("ndk", {plat = opt.plat, arch = opt.arch}) - local ndk_sysroot = toolchain_ndk:config("ndk_sysroot") - if ndk_sysroot then - table.insert(argv, "-e") - table.insert(argv, "CONAN_CMAKE_FIND_ROOT_PATH=" .. ndk_sysroot) - end - for k, v in pairs(envs) do - table.insert(argv, "-e") - table.insert(argv, k .. "=" .. v) - end - end - -- do install os.vrunv(conan.program, argv) -- cgit v1.3.1 From 34e986ea513cfc509dd860b2edab6f867d13a1dd Mon Sep 17 00:00:00 2001 From: ruki Date: Wed, 3 May 2023 00:56:26 +0800 Subject: update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4a0300fb..deb5068d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### New features * [#3613](https://github.com/xmake-io/xmake/issues/3613): Add `wasm.preloadfiles` configuration for wasm +* [#3703](https://github.com/xmake-io/xmake/pull/3703): Support for conan 2.0 ### Changes @@ -1578,6 +1579,7 @@ ### 新特性 * [#3613](https://github.com/xmake-io/xmake/issues/3613): 添加 `wasm.preloadfiles` 扩展配置 +* [#3703](https://github.com/xmake-io/xmake/pull/3703): 支持 conan 2.0 ### 改进 -- cgit v1.3.1