summaryrefslogtreecommitdiff
path: root/xmake/plugins
diff options
context:
space:
mode:
authorNorthn <[email protected]>2026-05-04 13:57:14 +0400
committerNorthn <[email protected]>2026-05-10 00:46:20 +0400
commitbccbb1effb606109a8d608527cedc29c610e7f9b (patch)
tree277633a7301f8767f91a24d887ee7706d2b1ddb1 /xmake/plugins
parent8bbbb2860fdd1910db466fe318ee8d465728ca32 (diff)
handle compiler/linkers arguments based on their frontend variant
fixes: https://github.com/xmake-io/xmake/issues/7526
Diffstat (limited to 'xmake/plugins')
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua119
1 files changed, 75 insertions, 44 deletions
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index 964508a5e..88ec94533 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -147,6 +147,37 @@ function _get_project_languages()
return languages
end
+-- get cmake compiler condition for tool-specific flags
+function _get_cmake_compiler_condition(toolname)
+ local conditions =
+ {
+ clang = [[CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID MATCHES "Clang$|^IntelLLVM$"]]
+ , clangxx = [[CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID MATCHES "Clang$|^IntelLLVM$"]]
+ , clang_cl = [[CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC" AND CURRENT_COMPILER_ID MATCHES "Clang$|^IntelLLVM$"]]
+ , gcc = [[CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID STREQUAL "GNU"]]
+ , gxx = [[CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID STREQUAL "GNU"]]
+ , cl = [[CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"]]
+ }
+ return conditions[toolname]
+end
+
+-- get cmake linker condition for tool-specific flags
+function _get_cmake_linker_condition(toolname)
+ local conditions =
+ {
+ clang = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID MATCHES "Clang$|^IntelLLVM$"]]
+ , clangxx = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID MATCHES "Clang$|^IntelLLVM$"]]
+ , clang_cl = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "MSVC" AND CURRENT_COMPILER_ID MATCHES "Clang$|^IntelLLVM$"]]
+ , gcc = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID STREQUAL "GNU"]]
+ , gxx = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "GNU" AND CURRENT_COMPILER_ID STREQUAL "GNU"]]
+ , cl = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "MSVC"]]
+ , ld = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "GNU"]]
+ , link = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "MSVC"]]
+ , lld_link = [[CURRENT_LINKER_FRONTEND_VARIANT STREQUAL "MSVC"]]
+ }
+ return conditions[toolname]
+end
+
-- get configs from target
function _get_configs_from_target(target, name)
local values = {}
@@ -370,11 +401,34 @@ function _add_project(cmakelists, outputdir)
cmakelists:print("project(%s%s)", project_name, project_info)
end
end
- -- Define a language-independant global compiler_id variable
+ -- Define language-independant global compiler/linker variables
if (languages and #languages > 0) then
- cmakelists:print("set(CURRENT_COMPILER_ID ${CMAKE_%s_COMPILER_ID})", _get_project_languages()[1])
+ local language = _get_project_languages()[1]
+ cmakelists:print("set(CURRENT_COMPILER_ID ${CMAKE_%s_COMPILER_ID})", language)
+ cmakelists:print("set(CURRENT_COMPILER_FRONTEND_VARIANT ${CMAKE_%s_COMPILER_FRONTEND_VARIANT})", language)
+ cmakelists:print("if(NOT CURRENT_COMPILER_FRONTEND_VARIANT)")
+ cmakelists:print(" set(CURRENT_COMPILER_FRONTEND_VARIANT ${CURRENT_COMPILER_ID})")
+ cmakelists:print("endif()")
+ cmakelists:print("set(CURRENT_LINKER_ID ${CMAKE_%s_COMPILER_LINKER_ID})", language)
+ cmakelists:print("if(DEFINED CMAKE_%s_COMPILER_LINKER_FRONTEND_VARIANT)", language)
+ cmakelists:print(" set(CURRENT_LINKER_FRONTEND_VARIANT ${CMAKE_%s_COMPILER_LINKER_FRONTEND_VARIANT})", language)
+ cmakelists:print("endif()")
+ cmakelists:print("if(NOT CURRENT_LINKER_FRONTEND_VARIANT)")
+ cmakelists:print(" set(CURRENT_LINKER_FRONTEND_VARIANT ${CURRENT_COMPILER_FRONTEND_VARIANT})")
+ cmakelists:print("endif()")
else
cmakelists:print("set(CURRENT_COMPILER_ID ${CMAKE_C_COMPILER_ID})") -- C should be defined by default if not specified
+ cmakelists:print("set(CURRENT_COMPILER_FRONTEND_VARIANT ${CMAKE_C_COMPILER_FRONTEND_VARIANT})")
+ cmakelists:print("if(NOT CURRENT_COMPILER_FRONTEND_VARIANT)")
+ cmakelists:print(" set(CURRENT_COMPILER_FRONTEND_VARIANT ${CURRENT_COMPILER_ID})")
+ cmakelists:print("endif()")
+ cmakelists:print("set(CURRENT_LINKER_ID ${CMAKE_C_COMPILER_LINKER_ID})")
+ cmakelists:print("if(DEFINED CMAKE_C_COMPILER_LINKER_FRONTEND_VARIANT)")
+ cmakelists:print(" set(CURRENT_LINKER_FRONTEND_VARIANT ${CMAKE_C_COMPILER_LINKER_FRONTEND_VARIANT})")
+ cmakelists:print("endif()")
+ cmakelists:print("if(NOT CURRENT_LINKER_FRONTEND_VARIANT)")
+ cmakelists:print(" set(CURRENT_LINKER_FRONTEND_VARIANT ${CURRENT_COMPILER_FRONTEND_VARIANT})")
+ cmakelists:print("endif()")
end
cmakelists:print("")
end
@@ -787,18 +841,10 @@ function _add_target_compile_options(cmakelists, target, outputdir)
end
end
_add_target_compile_options_for_compiler()
- local compilernames = {
- clang = "Clang",
- clangxx = "Clang",
- gcc = "GNU",
- gxx = "GNU",
- cl = "MSVC",
- link = "MSVC"
- }
for _, toolname in toolnames:keys() do
- local name = compilernames[toolname]
- if name then
- cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"%s\")", name)
+ local condition = _get_cmake_compiler_condition(toolname)
+ if condition then
+ cmakelists:print("if(%s)", condition)
_add_target_compile_options_for_compiler(toolname)
cmakelists:print("endif()")
end
@@ -825,20 +871,13 @@ function _add_target_values(cmakelists, target, name)
if name:endswith("s") then
name = name:sub(1, #name - 1)
end
- cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")")
- local flags_cl = _map_compflags("cl", "c", name, values)
- for _, flag in ipairs(flags_cl) do
- cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flag)
- end
- cmakelists:print("elseif(CURRENT_COMPILER_ID STREQUAL \"Clang\")")
- local flags_clang = _map_compflags("clang", "c", name, values)
- for _, flag in ipairs(flags_clang) do
- cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flag)
- end
- cmakelists:print("elseif(CURRENT_COMPILER_ID STREQUAL \"GNU\")")
- local flags_gcc = _map_compflags("gcc", "c", name, values)
- for _, flag in ipairs(flags_gcc) do
- cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flag)
+ for index, toolname in ipairs({"cl", "clang", "gcc"}) do
+ local condition = _get_cmake_compiler_condition(toolname)
+ cmakelists:print("%s(%s)", index == 1 and "if" or "elseif", condition)
+ local flags = _map_compflags(toolname, "c", name, values)
+ for _, flag in ipairs(flags) do
+ cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flag)
+ end
end
cmakelists:print("endif()")
end
@@ -903,7 +942,7 @@ function _add_target_languages(cmakelists, target)
if flag:endswith('++') then
cmakelists:print('foreach(standard 26 23 20 17 14 11 98)')
cmakelists:print(' include(CheckCXXCompilerFlag)')
- cmakelists:print(' if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")')
+ cmakelists:print(' if(CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")')
cmakelists:print(' check_cxx_compiler_flag("/std:%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag)
cmakelists:print(' else()')
cmakelists:print(' check_cxx_compiler_flag("-std=%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag)
@@ -916,7 +955,7 @@ function _add_target_languages(cmakelists, target)
else
cmakelists:print('foreach(standard 23 17 11 99 90)')
cmakelists:print(' include(CheckCCompilerFlag)')
- cmakelists:print(' if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")')
+ cmakelists:print(' if(CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")')
cmakelists:print(' check_c_compiler_flag("/std:%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag)
cmakelists:print(' else()')
cmakelists:print(' check_c_compiler_flag("-std=%s${standard}" %s_support_%s_standard_${standard})', flag, target:name(), flag)
@@ -956,7 +995,7 @@ function _add_target_optimization(cmakelists, target)
}
local optimization = target:get("optimize")
if optimization then
- cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")")
+ cmakelists:print("if(CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL \"MSVC\")")
cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flags_msvc[optimization])
cmakelists:print("else()")
cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), flags_gcc[optimization])
@@ -984,7 +1023,7 @@ function _add_target_symbols(cmakelists, target)
if levels:has("hidden") then
table.insert(flags_gcc, "-fvisibility=hidden")
end
- cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")")
+ cmakelists:print("if(CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL \"MSVC\")")
if #flags_msvc > 0 then
cmakelists:print(" target_compile_options(%s PRIVATE %s)", target:name(), table.concat(flags_msvc, " "))
end
@@ -1005,7 +1044,7 @@ function _add_target_runtimes(cmakelists, target)
local cmake_minver = _get_cmake_minver()
if cmake_minver:ge("3.15.0") then
local runtimes = target:get("runtimes")
- cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")")
+ cmakelists:print("if(CURRENT_COMPILER_FRONTEND_VARIANT STREQUAL \"MSVC\")")
if runtimes then
if runtimes == "MT" then
runtimes = "MultiThreaded"
@@ -1121,7 +1160,7 @@ function _add_target_link_directories(cmakelists, target, outputdir)
end
cmakelists:print(")")
else
- cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"MSVC\")")
+ cmakelists:print("if(CURRENT_LINKER_FRONTEND_VARIANT STREQUAL \"MSVC\")")
cmakelists:print(" target_link_libraries(%s PRIVATE", target:name())
for _, linkdir in ipairs(linkdirs) do
cmakelists:print(" -libpath:" .. _get_relative_unix_path(linkdir, outputdir))
@@ -1178,18 +1217,10 @@ function _add_target_link_options(cmakelists, target, outputdir)
end
end
_add_target_link_options_for_linker()
- local linkernames = {
- clang = "Clang",
- clangxx = "Clang",
- gcc = "GNU",
- gxx = "GNU",
- cl = "MSVC",
- link = "MSVC"
- }
for _, toolname in toolnames:keys() do
- local name = linkernames[toolname]
- if name then
- cmakelists:print("if(CURRENT_COMPILER_ID STREQUAL \"%s\")", name)
+ local condition = _get_cmake_linker_condition(toolname)
+ if condition then
+ cmakelists:print("if(%s)", condition)
_add_target_link_options_for_linker(toolname)
cmakelists:print("endif()")
end