Skip to content

Commit a4b5e56

Browse files
authored
Merge pull request #6810 from xmake-io/cmake
improve the default flags for cmake #6781
2 parents ee75f6d + 7cd5466 commit a4b5e56

File tree

1 file changed

+80
-91
lines changed

1 file changed

+80
-91
lines changed

xmake/modules/package/tools/cmake.lua

Lines changed: 80 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,13 @@ function _get_shflags(package, opt)
315315
end
316316
end
317317

318+
-- get arflags
319+
function _get_arflags(package, opt)
320+
local result = table.wrap(package:build_getenv("arflags"))
321+
if #result > 0 then
322+
return os.args(_translate_paths(result))
323+
end
324+
end
318325
-- get cmake version
319326
function _get_cmake_version()
320327
local cmake_version = _g.cmake_version
@@ -401,27 +408,6 @@ end
401408
-- get configs for generic
402409
function _get_configs_for_generic(package, configs, opt)
403410
local envs = {}
404-
local cflags = _get_cflags(package, opt)
405-
if cflags then
406-
envs.CMAKE_C_FLAGS = cflags
407-
end
408-
local cxxflags = _get_cxxflags(package, opt)
409-
if cxxflags then
410-
envs.CMAKE_CXX_FLAGS = cxxflags
411-
end
412-
local asflags = _get_asflags(package, opt)
413-
if asflags then
414-
envs.CMAKE_ASM_FLAGS = asflags
415-
end
416-
local ldflags = _get_ldflags(package, opt)
417-
if ldflags then
418-
envs.CMAKE_EXE_LINKER_FLAGS = ldflags
419-
end
420-
local shflags = _get_shflags(package, opt)
421-
if shflags then
422-
envs.CMAKE_SHARED_LINKER_FLAGS = shflags
423-
envs.CMAKE_MODULE_LINKER_FLAGS = shflags
424-
end
425411
if not package:is_plat("windows", "mingw") and package:config("pic") ~= false then
426412
envs.CMAKE_POSITION_INDEPENDENT_CODE = "ON"
427413
end
@@ -461,12 +447,9 @@ function _get_configs_for_windows(package, configs, opt)
461447
-- use clang-cl or clang, and we need pass --target=xxx flags
462448
if package:has_tool("cc", "clang", "clang_cl") then
463449
envs.CMAKE_C_COMPILER = _translate_bin_path(package:build_getenv("cc"))
464-
-- @see https://github.com/xmake-io/xmake-repo/issues/7662
465-
envs.CMAKE_C_FLAGS = _get_cflags(package, {cross = true})
466450
end
467451
if package:has_tool("cxx", "clang", "clang_cl") then
468452
envs.CMAKE_CXX_COMPILER = _translate_bin_path(package:build_getenv("cxx"))
469-
envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, {cross = true})
470453
end
471454

472455
-- we maybe need patch `cmake_policy(SET CMP0091 NEW)` to enable this argument for some packages
@@ -535,13 +518,6 @@ function _get_configs_for_appleos(package, configs, opt)
535518
opt = opt or {}
536519
local envs = {}
537520
opt.cross = true
538-
envs.CMAKE_C_FLAGS = _get_cflags(package, opt)
539-
envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, opt)
540-
envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt)
541-
envs.CMAKE_STATIC_LINKER_FLAGS = table.concat(table.wrap(package:build_getenv("arflags")), ' ')
542-
envs.CMAKE_EXE_LINKER_FLAGS = _get_ldflags(package, opt)
543-
envs.CMAKE_SHARED_LINKER_FLAGS = _get_shflags(package, opt)
544-
envs.CMAKE_MODULE_LINKER_FLAGS = _get_shflags(package, opt)
545521
-- https://cmake.org/cmake/help/v3.17/manual/cmake-toolchains.7.html#id25
546522
if package:is_plat("watchos") then
547523
envs.CMAKE_SYSTEM_NAME = "watchOS"
@@ -580,13 +556,6 @@ function _get_configs_for_mingw(package, configs, opt)
580556
envs.CMAKE_AR = _translate_bin_path(package:build_getenv("ar"))
581557
envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib"))
582558
envs.CMAKE_RC_COMPILER = _translate_bin_path(package:build_getenv("mrc"))
583-
envs.CMAKE_C_FLAGS = _get_cflags(package, opt)
584-
envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, opt)
585-
envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt)
586-
envs.CMAKE_STATIC_LINKER_FLAGS = table.concat(table.wrap(package:build_getenv("arflags")), ' ')
587-
envs.CMAKE_EXE_LINKER_FLAGS = _get_ldflags(package, opt)
588-
envs.CMAKE_SHARED_LINKER_FLAGS = _get_shflags(package, opt)
589-
envs.CMAKE_MODULE_LINKER_FLAGS = _get_shflags(package, opt)
590559
-- @see https://cmake.org/cmake/help/latest/variable/CMAKE_CROSSCOMPILING.html
591560
-- https://github.com/xmake-io/xmake/pull/5888
592561
if not is_host("windows") then
@@ -633,15 +602,6 @@ function _get_configs_for_wasm(package, configs, opt)
633602
end
634603
end
635604

636-
-- pass toolchain flags cross-compilation
637-
-- @see https://github.com/xmake-io/xmake/issues/6690
638-
envs.CMAKE_C_FLAGS = _get_cflags(package, {cross = true})
639-
envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, {cross = true})
640-
envs.CMAKE_ASM_FLAGS = _get_asflags(package, {cross = true})
641-
envs.CMAKE_EXE_LINKER_FLAGS = _get_ldflags(package, {cross = true})
642-
envs.CMAKE_SHARED_LINKER_FLAGS = _get_shflags(package, {cross = true})
643-
envs.CMAKE_MODULE_LINKER_FLAGS = _get_shflags(package, {cross = true})
644-
645605
-- avoid find and add system include/library path
646606
-- @see https://github.com/xmake-io/xmake/issues/5577
647607
-- https://github.com/emscripten-core/emscripten/issues/13310
@@ -679,14 +639,7 @@ function _get_configs_for_cross(package, configs, opt)
679639
if package:has_tool("ld", "gxx", "clangxx") then
680640
envs.CMAKE_CXX_LINK_EXECUTABLE = ld .. " <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>"
681641
end
682-
envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib"))
683-
envs.CMAKE_C_FLAGS = _get_cflags(package, opt)
684-
envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, opt)
685-
envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt)
686-
envs.CMAKE_STATIC_LINKER_FLAGS = table.concat(table.wrap(package:build_getenv("arflags")), ' ')
687-
envs.CMAKE_EXE_LINKER_FLAGS = _get_ldflags(package, opt)
688-
envs.CMAKE_SHARED_LINKER_FLAGS = _get_shflags(package, opt)
689-
envs.CMAKE_MODULE_LINKER_FLAGS = _get_shflags(package, opt)
642+
envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib"))
690643
-- we don't need to set it as cross compilation if we just pass toolchain
691644
-- https://github.com/xmake-io/xmake/issues/2170
692645
if package:is_cross() then
@@ -743,14 +696,7 @@ function _get_configs_for_host_toolchain(package, configs, opt)
743696
if package:has_tool("ld", "gxx", "clangxx") then
744697
envs.CMAKE_CXX_LINK_EXECUTABLE = ld .. " <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>"
745698
end
746-
envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib"))
747-
envs.CMAKE_C_FLAGS = _get_cflags(package, opt)
748-
envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, opt)
749-
envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt)
750-
envs.CMAKE_STATIC_LINKER_FLAGS = table.concat(table.wrap(package:build_getenv("arflags")), ' ')
751-
envs.CMAKE_EXE_LINKER_FLAGS = _get_ldflags(package, opt)
752-
envs.CMAKE_SHARED_LINKER_FLAGS = _get_shflags(package, opt)
753-
envs.CMAKE_MODULE_LINKER_FLAGS = _get_shflags(package, opt)
699+
envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib"))
754700
-- we don't need to set it as cross compilation if we just pass toolchain
755701
-- https://github.com/xmake-io/xmake/issues/2170
756702
if package:is_cross() then
@@ -866,21 +812,23 @@ function _get_default_flags(package, configs, buildtype, opt)
866812

867813
local runenvs = opt.envs or buildenvs(package)
868814
local cmake = find_tool("cmake")
869-
local _configs = table.join(configs, "-S " .. path.directory(dummy_cmakelist), "-B " .. tmpdir, cflags or {}, cxxflags)
815+
local _configs = table.join(configs, "-S", path.directory(dummy_cmakelist), "-B", tmpdir, cflags or {}, cxxflags)
870816
local outdata = try{ function() return os.iorunv(cmake.program, _configs, {envs = runenvs}) end}
871817
if outdata and outdata ~= "" then
872818
cmake_default_flags = {}
873-
cmake_default_flags.cflags = outdata:match("CMAKE_C_FLAGS is (.-)\n") or " "
874-
cmake_default_flags.cflags = cmake_default_flags.cflags .. " " .. outdata:match(format("CMAKE_C_FLAGS_%s is (.-)\n", buildtype)):replace("/MDd", ""):replace("/MD", "")
875-
cmake_default_flags.cxxflags = outdata:match("CMAKE_CXX_FLAGS is (.-)\n") or " "
876-
cmake_default_flags.cxxflags = cmake_default_flags.cxxflags .. " " .. outdata:match(format("CMAKE_CXX_FLAGS_%s is (.-)\n", buildtype)):replace("/MDd", ""):replace("/MD", "")
877-
cmake_default_flags.ldflags = outdata:match("CMAKE_EXE_LINKER_FLAGS is (.-)\n") or " "
878-
cmake_default_flags.ldflags = cmake_default_flags.ldflags .. " " .. outdata:match(format("CMAKE_EXE_LINKER_FLAGS_%s is (.-)\n", buildtype))
879-
cmake_default_flags.shflags = outdata:match("CMAKE_SHARED_LINKER_FLAGS is (.-)\n") or " "
880-
cmake_default_flags.shflags = cmake_default_flags.shflags .. " " .. outdata:match(format("CMAKE_SHARED_LINKER_FLAGS_%s is (.-)\n", buildtype))
881-
cmake_default_flags.arflags = outdata:match("CMAKE_STATIC_LINKER_FLAGS is (.-)\n") or " "
882-
cmake_default_flags.arflags = cmake_default_flags.arflags .. " " ..outdata:match(format("CMAKE_STATIC_LINKER_FLAGS_%s is (.-)\n", buildtype))
883-
819+
cmake_default_flags.CMAKE_C_FLAGS = outdata:match("CMAKE_C_FLAGS is (.-)\n")
820+
cmake_default_flags["CMAKE_C_FLAGS_" .. buildtype] = outdata:match(format("CMAKE_C_FLAGS_%s is (.-)\n", buildtype))
821+
cmake_default_flags.CMAKE_CXX_FLAGS = outdata:match("CMAKE_CXX_FLAGS is (.-)\n")
822+
cmake_default_flags["CMAKE_CXX_FLAGS_" .. buildtype] = outdata:match(format("CMAKE_CXX_FLAGS_%s is (.-)\n", buildtype))
823+
cmake_default_flags.CMAKE_CXX_FLAGS = outdata:match("CMAKE_CXX_FLAGS is (.-)\n")
824+
cmake_default_flags["CMAKE_EXE_LINKER_FLAGS_" .. buildtype] = outdata:match(format("CMAKE_EXE_LINKER_FLAGS_%s is (.-)\n", buildtype))
825+
cmake_default_flags.CMAKE_SHARED_LINKER_FLAGS = outdata:match("CMAKE_SHARED_LINKER_FLAGS is (.-)\n")
826+
cmake_default_flags["CMAKE_SHARED_LINKER_FLAGS_" .. buildtype] = outdata:match(format("CMAKE_SHARED_LINKER_FLAGS_%s is (.-)\n", buildtype))
827+
cmake_default_flags.CMAKE_STATIC_LINKER_FLAGS = outdata:match("CMAKE_STATIC_LINKER_FLAGS is (.-)\n")
828+
cmake_default_flags["CMAKE_STATIC_LINKER_FLAGS_" .. buildtype] = outdata:match(format("CMAKE_STATIC_LINKER_FLAGS_%s is (.-)\n", buildtype))
829+
for k, v in ipairs(cmake_default_flags) do
830+
cmake_default_flags[k] = v:replace("/M[DT]d", ""):replace("/M[DT]", "")
831+
end
884832
_g.cmake_default_flags = _g.cmake_default_flags or {}
885833
_g.cmake_default_flags[cachekey] = cmake_default_flags
886834
end
@@ -905,25 +853,30 @@ function _get_envs_for_default_flags(package, configs, opt)
905853
local default_flags = _get_default_flags(package, configs, buildtype, opt)
906854
if default_flags then
907855
if not opt.cxxflags and not opt.cxflags then
908-
envs[format("CMAKE_CXX_FLAGS_%s", buildtype)] = default_flags.cxxflags
856+
envs.CMAKE_CXX_FLAGS = default_flags.CMAKE_CXX_FLAGS
857+
envs["CMAKE_CXX_FLAGS_" .. buildtype] = default_flags["CMAKE_CXX_FLAGS_" .. buildtype]
909858
end
910859
if not opt.cflags and not opt.cxflags then
911-
envs[format("CMAKE_C_FLAGS_%s", buildtype)] = default_flags.cflags
860+
envs.CMAKE_C_FLAGS = default_flags.CMAKE_C_FLAGS
861+
envs["CMAKE_C_FLAGS_" .. buildtype] = default_flags["CMAKE_C_FLAGS_" .. buildtype]
912862
end
913863
if not opt.ldflags then
914-
envs[format("CMAKE_EXE_LINKER_FLAGS_%s", buildtype)] = default_flags.ldflags
864+
envs.CMAKE_EXE_LINKER_FLAGS = default_flags.CMAKE_EXE_LINKER_FLAGS
865+
envs["CMAKE_EXE_LINKER_FLAGS_" .. buildtype] = default_flags["CMAKE_EXE_LINKER_FLAGS_" .. buildtype]
915866
end
916867
if not opt.arflags then
917-
envs[format("CMAKE_STATIC_LINKER_FLAGS_%s", buildtype)] = default_flags.arflags
868+
envs.CMAKE_STATIC_LINKER_FLAGS = default_flags.CMAKE_STATIC_LINKER_FLAGS
869+
envs["CMAKE_STATIC_LINKER_FLAGS_" .. buildtype] = default_flags["CMAKE_STATIC_LINKER_FLAGS_" .. buildtype]
918870
end
919871
if not opt.shflags then
920-
envs[format("CMAKE_SHARED_LINKER_FLAGS_%s", buildtype)] = default_flags.shflags
872+
envs.CMAKE_SHARED_LINKER_FLAGS = default_flags.CMAKE_SHARED_LINKER_FLAGS
873+
envs["CMAKE_SHARED_LINKER_FLAGS_" .. buildtype] = default_flags["CMAKE_SHARED_LINKER_FLAGS_" .. buildtype]
921874
end
922875
end
923876
return envs
924877
end
925878

926-
function _get_envs_for_runtime_flags(package, configs, opt)
879+
function _get_envs_for_runtime_flags(package, opt)
927880
local buildtype = _get_cmake_buildtype(package)
928881
local envs = {}
929882
local runtimes = package:runtimes()
@@ -938,6 +891,45 @@ function _get_envs_for_runtime_flags(package, configs, opt)
938891
return envs
939892
end
940893

894+
function _get_envs_for_flags(package, configs, opt)
895+
-- get the default envs
896+
local envs = _get_envs_for_default_flags(package, configs, opt) or {}
897+
local runtime_envs = _get_envs_for_runtime_flags(package, opt)
898+
if runtime_envs then
899+
for name, value in pairs(runtime_envs) do
900+
envs[name] = (envs[name] or " ") .. " " .. table.concat(value, " ")
901+
end
902+
end
903+
904+
-- get the platform/toolchain envs
905+
local platform_envs = {}
906+
if package:is_plat("windows") then
907+
-- use clang-cl or clang, and we need pass --target=xxx flags
908+
if package:has_tool("cc", "clang", "clang_cl") then
909+
-- @see https://github.com/xmake-io/xmake-repo/issues/7662
910+
platform_envs.CMAKE_C_FLAGS = _get_cflags(package, {cross = true})
911+
end
912+
if package:has_tool("cxx", "clang", "clang_cl") then
913+
platform_envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, {cross = true})
914+
end
915+
elseif package:is_plat("wasm") then
916+
-- pass toolchain flags cross-compilation
917+
-- @see https://github.com/xmake-io/xmake/issues/6690
918+
opt.cross = true
919+
end
920+
platform_envs.CMAKE_C_FLAGS = platform_envs.CMAKE_C_FLAGS or _get_cflags(package, opt)
921+
platform_envs.CMAKE_CXX_FLAGS = platform_envs.CMAKE_CXX_FLAGS or _get_cxxflags(package, opt)
922+
platform_envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt)
923+
platform_envs.CMAKE_EXE_LINKER_FLAGS = _get_ldflags(package, opt)
924+
platform_envs.CMAKE_SHARED_LINKER_FLAGS = _get_shflags(package, opt)
925+
platform_envs.CMAKE_MODULE_LINKER_FLAGS = _get_shflags(package, opt)
926+
platform_envs.CMAKE_STATIC_LINKER_FLAGS = _get_arflags(package, opt)
927+
for name, value in pairs(platform_envs) do
928+
envs[name] = (envs[name] or " ") .. " " .. value
929+
end
930+
return envs
931+
end
932+
941933
function _get_configs(package, configs, opt)
942934
configs = configs or {}
943935
opt._configs_str = string.serialize(configs, {indent = false, strip = true})
@@ -975,22 +967,19 @@ function _get_configs(package, configs, opt)
975967
table.insert(configs, "-DCMAKE_POLICY_VERSION_MINIMUM=3.5")
976968
end
977969

978-
local envs = _get_envs_for_default_flags(package, configs, opt)
979-
local runtime_envs = _get_envs_for_runtime_flags(package, configs, opt)
980-
if runtime_envs then
981-
envs = envs or {}
982-
for name, value in pairs(runtime_envs) do
983-
envs[name] = (envs[name] or " ") .. " " .. table.concat(value, " ")
984-
end
985-
end
986-
_insert_configs_from_envs(configs, envs or {}, opt)
970+
-- insert flags to configs
971+
--
972+
-- @note We need to rely on configs to get the exact default flags
973+
-- @see https://github.com/xmake-io/xmake/issues/6781
974+
local envs = _get_envs_for_flags(package, configs, opt)
975+
_insert_configs_from_envs(configs, envs, opt)
987976

977+
-- enable ccache?
988978
local ccache = package:data("ccache")
989979
if ccache then
990980
table.insert(configs, "-DCMAKE_C_COMPILER_LAUNCHER=" .. ccache)
991981
table.insert(configs, "-DCMAKE_CXX_COMPILER_LAUNCHER=" .. ccache)
992982
end
993-
994983
return configs
995984
end
996985

0 commit comments

Comments
 (0)