summaryrefslogtreecommitdiff
path: root/xmake/modules/package/tools/cmake.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2022-10-12 23:21:11 +0800
committerruki <[email protected]>2022-10-12 23:21:11 +0800
commit343db2cf17ec4449d886ebf588215e853f1beb7b (patch)
treee1e3588d18e1def8fc5fdde23f35265cacccacca /xmake/modules/package/tools/cmake.lua
parentf931f32b33228f0efadbb7942507047b570a7cda (diff)
improve tools/cmake for toolchains
Diffstat (limited to 'xmake/modules/package/tools/cmake.lua')
-rw-r--r--xmake/modules/package/tools/cmake.lua90
1 files changed, 88 insertions, 2 deletions
diff --git a/xmake/modules/package/tools/cmake.lua b/xmake/modules/package/tools/cmake.lua
index 062123ff0..cda883daf 100644
--- a/xmake/modules/package/tools/cmake.lua
+++ b/xmake/modules/package/tools/cmake.lua
@@ -72,6 +72,34 @@ function _map_linkflags(package, targetkind, sourcekinds, name, values)
return linker.map_flags(targetkind, sourcekinds, name, values, {target = package})
end
+-- is cross compilation?
+function _is_cross_compilation(package)
+ if not package:is_plat(os.subhost()) then
+ return true
+ end
+ if package:is_plat("macosx") and not package:is_arch(os.subarch()) then
+ return true
+ end
+ return false
+end
+
+-- is the toolchain compatible with the host?
+function _is_toolchain_compatible_with_host(package)
+ local toolchains = package:config("toolchains")
+ if toolchains then
+ toolchains = table.wrap(toolchains)
+ if is_host("linux", "macosx", "bsd") then
+ for _, name in ipairs(toolchains) do
+ if name:startswith("clang") or name:startswith("gcc") then
+ return true
+ end
+ end
+ elseif is_host("windows") and table.contains(toolchains, "msvc") then
+ return true
+ end
+ end
+end
+
-- get msvc
function _get_msvc(package)
local msvc = toolchain.load("msvc", {plat = package:plat(), arch = package:arch()})
@@ -509,6 +537,57 @@ function _get_configs_for_cross(package, configs, opt)
end
end
+-- get configs for host toolchain
+function _get_configs_for_host_toolchain(package, configs, opt)
+ opt = opt or {}
+ opt.cross = true
+ local envs = {}
+ local sdkdir = _translate_paths(package:build_getenv("sdk"))
+ envs.CMAKE_C_COMPILER = _translate_bin_path(package:build_getenv("cc"))
+ envs.CMAKE_CXX_COMPILER = _translate_bin_path(package:build_getenv("cxx"))
+ envs.CMAKE_ASM_COMPILER = _translate_bin_path(package:build_getenv("as"))
+ envs.CMAKE_AR = _translate_bin_path(package:build_getenv("ar"))
+ -- https://github.com/xmake-io/xmake-repo/pull/1096
+ local cxx = envs.CMAKE_CXX_COMPILER
+ if cxx and package:has_tool("cxx", "clang", "gcc") then
+ local dir = path.directory(cxx)
+ local name = path.filename(cxx)
+ name = name:gsub("clang$", "clang++")
+ name = name:gsub("clang%-", "clang++-")
+ name = name:gsub("gcc$", "g++")
+ name = name:gsub("gcc%-", "g++-")
+ envs.CMAKE_CXX_COMPILER = _translate_bin_path(dir and path.join(dir, name) or name)
+ end
+ -- @note The link command line is set in Modules/CMake{C,CXX,Fortran}Information.cmake and defaults to using the compiler, not CMAKE_LINKER,
+ -- so we need set CMAKE_CXX_LINK_EXECUTABLE to use CMAKE_LINKER as linker.
+ --
+ -- https://github.com/xmake-io/xmake-repo/pull/1039
+ -- https://stackoverflow.com/questions/1867745/cmake-use-a-custom-linker/25274328#25274328
+ envs.CMAKE_LINKER = _translate_bin_path(package:build_getenv("ld"))
+ if package:has_tool("ld", "gxx", "clangxx") then
+ envs.CMAKE_CXX_LINK_EXECUTABLE = "<CMAKE_LINKER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>"
+ end
+ envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib"))
+ envs.CMAKE_C_FLAGS = _get_cflags(package, opt)
+ envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, opt)
+ envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt)
+ envs.CMAKE_STATIC_LINKER_FLAGS = table.concat(table.wrap(package:build_getenv("arflags")), ' ')
+ envs.CMAKE_EXE_LINKER_FLAGS = _get_ldflags(package, opt)
+ envs.CMAKE_SHARED_LINKER_FLAGS = _get_shflags(package, opt)
+ -- we need not set it as cross compilation if we just pass toolchain
+ -- https://github.com/xmake-io/xmake/issues/2170
+ if not package:is_plat(os.subhost()) then
+ envs.CMAKE_SYSTEM_NAME = "Linux"
+ else
+ if package:config("pic") ~= false then
+ table.insert(configs, "-DCMAKE_POSITION_INDEPENDENT_CODE=ON")
+ end
+ end
+ for k, v in pairs(envs) do
+ table.insert(configs, "-D" .. k .. "=" .. v)
+ end
+end
+
-- get cmake generator for msvc
function _get_cmake_generator_for_msvc(package)
local vsvers =
@@ -591,9 +670,16 @@ function _get_configs(package, configs, opt)
_get_configs_for_mingw(package, configs, opt)
elseif package:is_plat("wasm") then
_get_configs_for_wasm(package, configs, opt)
- elseif not package:is_plat(os.subhost()) or
- package:config("toolchains") then -- we need pass toolchains
+ elseif _is_cross_compilation(package) then
_get_configs_for_cross(package, configs, opt)
+ elseif package:config("toolchains") then
+ -- we still need find system libraries,
+ -- it just pass toolchain environments if the toolchain is compatible with host
+ if _is_toolchain_compatible_with_host(package) then
+ _get_configs_for_host_toolchain(package, configs, opt)
+ else
+ _get_configs_for_cross(package, configs, opt)
+ end
else
_get_configs_for_generic(package, configs, opt)
end