Skip to content

Commit 1d3ff91

Browse files
authored
Merge pull request #5025 from Arthapz/fix-cmake-packages
fix CMake package defaultflags and runtimes support
2 parents 8b8831f + 0713cf3 commit 1d3ff91

File tree

1 file changed

+98
-32
lines changed

1 file changed

+98
-32
lines changed

xmake/modules/package/tools/cmake.lua

+98-32
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,6 @@ function _get_cxxflags(package, opt)
184184
table.join2(result, _map_compflags(package, "cxx", "includedir", package:build_getenv("includedirs")))
185185
table.join2(result, _map_compflags(package, "cxx", "sysincludedir", package:build_getenv("sysincludedirs")))
186186
end
187-
local runtimes = package:runtimes()
188-
if runtimes then
189-
local fake_target = {is_shared = function(_) return false end,
190-
sourcekinds = function(_) return "cxx" end}
191-
table.join2(result, _map_compflags(fake_target, "cxx", "runtime", runtimes))
192-
end
193187
table.join2(result, package:config("cxxflags"))
194188
table.join2(result, package:config("cxflags"))
195189
if opt.cxxflags then
@@ -239,12 +233,6 @@ function _get_ldflags(package, opt)
239233
table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "syslink", package:build_getenv("syslinks")))
240234
table.join2(result, _map_linkflags(package, "binary", {"cxx"}, "linkdir", package:build_getenv("linkdirs")))
241235
end
242-
local runtimes = package:runtimes()
243-
if runtimes then
244-
local fake_target = {is_shared = function(_) return false end,
245-
sourcekinds = function(_) return "cxx" end}
246-
table.join2(result, _map_linkflags(fake_target, "binary", {"cxx"}, "runtime", runtimes))
247-
end
248236
table.join2(result, package:config("ldflags"))
249237
if package:config("lto") then
250238
table.join2(result, package:_generate_lto_configs().ldflags)
@@ -271,12 +259,6 @@ function _get_shflags(package, opt)
271259
table.join2(result, _map_linkflags(package, "shared", {"cxx"}, "syslink", package:build_getenv("syslinks")))
272260
table.join2(result, _map_linkflags(package, "shared", {"cxx"}, "linkdir", package:build_getenv("linkdirs")))
273261
end
274-
local runtimes = package:runtimes()
275-
if runtimes then
276-
local fake_target = {is_shared = function(_) return true end,
277-
sourcekinds = function(_) return "cxx" end}
278-
table.join2(result, _map_linkflags(fake_target, "shared", {"cxx"}, "runtime", runtimes))
279-
end
280262
table.join2(result, package:config("shflags"))
281263
if package:config("lto") then
282264
table.join2(result, package:_generate_lto_configs().shflags)
@@ -401,28 +383,14 @@ function _get_configs_for_windows(package, configs, opt)
401383
-- we maybe need patch `cmake_policy(SET CMP0091 NEW)` to enable this argument for some packages
402384
-- @see https://cmake.org/cmake/help/latest/policy/CMP0091.html#policy:CMP0091
403385
-- https://github.com/xmake-io/xmake-repo/pull/303
404-
local runtime
405386
if package:has_runtime("MT") then
406387
table.insert(configs, "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded")
407-
runtime = "MT"
408388
elseif package:has_runtime("MTd") then
409389
table.insert(configs, "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebug")
410-
runtime = "MTd"
411390
elseif package:has_runtime("MD") then
412391
table.insert(configs, "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL")
413-
runtime = "MD"
414392
elseif package:has_runtime("MDd") then
415393
table.insert(configs, "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDebugDLL")
416-
runtime = "MDd"
417-
end
418-
if runtime then
419-
-- CMake default MSVC flags as of 3.21.2
420-
local default_debug_flags = "/Zi /Ob0 /Od /RTC1"
421-
local default_release_flags = "/O2 /Ob2 /DNDEBUG"
422-
table.insert(configs, '-DCMAKE_CXX_FLAGS_DEBUG=/' .. runtime .. ' ' .. default_debug_flags)
423-
table.insert(configs, '-DCMAKE_CXX_FLAGS_RELEASE=/' .. runtime .. ' ' .. default_release_flags)
424-
table.insert(configs, '-DCMAKE_C_FLAGS_DEBUG=/' .. runtime .. ' ' .. default_debug_flags)
425-
table.insert(configs, '-DCMAKE_C_FLAGS_RELEASE=/' .. runtime .. ' ' .. default_release_flags)
426394
end
427395
if not opt._configs_str:find("CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY") then
428396
table.insert(configs, "-DCMAKE_COMPILE_PDB_OUTPUT_DIRECTORY=pdb")
@@ -755,6 +723,95 @@ function _get_configs_for_install(package, configs, opt)
755723
end
756724
end
757725

726+
function _get_default_flags(package, configs, buildtype, opt)
727+
local cmake_default_flags = _g.cmake_default_flags and _g.cmake_default_flags[buildtype]
728+
if not cmake_default_flags then
729+
local tmpdir = path.join(os.tmpdir() .. ".dir", package:name(), package:mode())
730+
local dummy_cmakelist = path.join(tmpdir, "CMakeLists.txt")
731+
732+
io.writefile(dummy_cmakelist, format([[
733+
message(STATUS "CMAKE_C_FLAGS is ${CMAKE_C_FLAGS}")
734+
message(STATUS "CMAKE_C_FLAGS_%s is ${CMAKE_C_FLAGS_%s}")
735+
736+
message(STATUS "CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
737+
message(STATUS "CMAKE_CXX_FLAGS_%s is ${CMAKE_CXX_FLAGS_%s}")
738+
739+
message(STATUS "CMAKE_EXE_LINKER_FLAGS is ${CMAKE_EXE_LINKER_FLAGS}")
740+
message(STATUS "CMAKE_EXE_LINKER_FLAGS_%s is ${CMAKE_EXE_LINKER_FLAGS_%s}")
741+
742+
message(STATUS "CMAKE_SHARED_LINKER_FLAGS is ${CMAKE_SHARED_LINKER_FLAGS}")
743+
message(STATUS "CMAKE_SHARED_LINKER_FLAGS_%s is ${CMAKE_SHARED_LINKER_FLAGS_%s}")
744+
745+
message(STATUS "CMAKE_STATIC_LINKER_FLAGS is ${CMAKE_STATIC_LINKER_FLAGS}")
746+
message(STATUS "CMAKE_STATIC_LINKER_FLAGS_%s is ${CMAKE_STATIC_LINKER_FLAGS_%s}")
747+
]], buildtype, buildtype, buildtype, buildtype, buildtype, buildtype, buildtype, buildtype, buildtype, buildtype))
748+
749+
local runenvs = opt.envs or buildenvs(package)
750+
local cmake = find_tool("cmake")
751+
local _configs = table.join(configs, "-S " .. path.directory(dummy_cmakelist), "-B " .. tmpdir)
752+
local outdata = try{ function() return os.iorunv(cmake.program, _configs, {envs = runenvs}) end}
753+
if outdata then
754+
cmake_default_flags = {}
755+
cmake_default_flags.cflags = outdata:match("CMAKE_C_FLAGS is (.-)\n") or " "
756+
cmake_default_flags.cflags = cmake_default_flags.cflags .. " " .. outdata:match(format("CMAKE_C_FLAGS_%s is (.-)\n", buildtype)):replace("/MDd", ""):replace("/MD", "")
757+
cmake_default_flags.cxxflags = outdata:match("CMAKE_CXX_FLAGS is (.-)\n") or " "
758+
cmake_default_flags.cxxflags = cmake_default_flags.cxxflags .. " " .. outdata:match(format("CMAKE_CXX_FLAGS_%s is (.-)\n", buildtype)):replace("/MDd", ""):replace("/MD", "")
759+
cmake_default_flags.ldflags = outdata:match("CMAKE_EXE_LINKER_FLAGS is (.-)\n") or " "
760+
cmake_default_flags.ldflags = cmake_default_flags.ldflags .. " " .. outdata:match(format("CMAKE_EXE_LINKER_FLAGS_%s is (.-)\n", buildtype))
761+
cmake_default_flags.shflags = outdata:match("CMAKE_SHARED_LINKER_FLAGS is (.-)\n") or " "
762+
cmake_default_flags.shflags = cmake_default_flags.shflags .. " " .. outdata:match(format("CMAKE_SHARED_LINKER_FLAGS_%s is (.-)\n", buildtype))
763+
cmake_default_flags.arflags = outdata:match("CMAKE_STATIC_LINKER_FLAGS is (.-)\n") or " "
764+
cmake_default_flags.arflags = cmake_default_flags.arflags .. " " ..outdata:match(format("CMAKE_STATIC_LINKER_FLAGS_%s is (.-)\n", buildtype))
765+
766+
_g.cmake_default_flags = _g.cmake_default_flags or {}
767+
_g.cmake_default_flags[buildtype] = cmake_default_flags
768+
end
769+
os.rm(tmpdir)
770+
end
771+
return cmake_default_flags
772+
end
773+
774+
function _get_cmake_buildtype(package)
775+
local cmake_buildtype_map = {
776+
debug = "DEBUG",
777+
release = "RELEASE",
778+
releasedbg = "RELWITHDEBINFO"
779+
}
780+
local buildtype = package:mode()
781+
return cmake_buildtype_map[buildtype] or "RELEASE"
782+
end
783+
784+
function _get_envs_for_default_flags(package, configs, opt)
785+
local buildtype = _get_cmake_buildtype(package)
786+
local envs = {}
787+
local default_flags = _get_default_flags(package, configs, buildtype, opt)
788+
if default_flags then
789+
envs[format("CMAKE_CXX_FLAGS_%s", buildtype)] = (not opt.cxxflags and not opt.cxflags) and default_flags.cxxflags
790+
envs[format("CMAKE_C_FLAGS_%s", buildtype)] = (not opt.cflags and not opt.cxflags) and default_flags.cflags
791+
envs[format("CMAKE_EXE_LINKER_FLAGS_%s", buildtype)] = not opt.ldflags and default_flags.ldflags
792+
envs[format("CMAKE_STATIC_LINKER_FLAGS_%s", buildtype)] = not opt.arflags and default_flags.arflags
793+
envs[format("CMAKE_SHARED_LINKER_FLAGS_%s", buildtype)] = not opt.shflags and default_flags.shflags
794+
end
795+
return envs
796+
end
797+
798+
function _get_envs_for_runtime_flags(package, configs, opt)
799+
local buildtype = _get_cmake_buildtype(package)
800+
local envs = {}
801+
local runtimes = package:runtimes()
802+
if runtimes then
803+
local fake_target = {is_shared = function(_) return false end,
804+
sourcekinds = function(_) return "c" end}
805+
envs[format("CMAKE_C_FLAGS_%s", buildtype)] = _map_compflags(fake_target, "c", "runtime", runtimes)
806+
fake_target.sourcekinds = function(_) return "cxx" end
807+
envs[format("CMAKE_CXX_FLAGS_%s", buildtype)] = _map_compflags(fake_target, "cxx", "runtime", runtimes)
808+
envs[format("CMAKE_EXE_LINKER_FLAGS_%s", buildtype)] = _map_linkflags(fake_target, "binary", {"cxx"}, "runtime", runtimes)
809+
envs[format("CMAKE_STATIC_LINKER_FLAGS_%s", buildtype)] = _map_linkflags(fake_target, "static", {"cxx"}, "runtime", runtimes)
810+
fake_target.is_shared = function(_) return true end
811+
envs[format("CMAKE_SHARED_LINKER_FLAGS_%s", buildtype)] = _map_linkflags(fake_target, "shared", {"cxx"}, "runtime", runtimes)
812+
end
813+
return envs
814+
end
758815
-- get configs
759816
function _get_configs(package, configs, opt)
760817
configs = configs or {}
@@ -786,6 +843,15 @@ function _get_configs(package, configs, opt)
786843
else
787844
_get_configs_for_generic(package, configs, opt)
788845
end
846+
local envs = _get_envs_for_default_flags(package, configs, opt)
847+
local runtime_envs = _get_envs_for_runtime_flags(package, configs, opt)
848+
if runtime_envs then
849+
envs = envs or {}
850+
for name, value in pairs(runtime_envs) do
851+
envs[name] = (envs[name] or " ") .. " " .. table.concat(value, " ")
852+
end
853+
end
854+
_insert_configs_from_envs(configs, envs or {}, opt)
789855
return configs
790856
end
791857

0 commit comments

Comments
 (0)