diff options
| author | ruki <[email protected]> | 2024-08-20 23:35:41 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2024-08-20 23:35:41 +0800 |
| commit | 4a647b14f86e336e178ba71b7c45c6a5e9e289d8 (patch) | |
| tree | e5468b63330a77f5c0d5dcbdd7519f1691628601 | |
| parent | 624b853a4ec3397eb79c4745e365a87f079f9a0f (diff) | |
improve flags support for target
| -rw-r--r-- | xmake/plugins/project/cmake/cmakelists.lua | 171 |
1 files changed, 134 insertions, 37 deletions
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua index f36f3deed..eb20f6647 100644 --- a/xmake/plugins/project/cmake/cmakelists.lua +++ b/xmake/plugins/project/cmake/cmakelists.lua @@ -255,6 +255,17 @@ function _map_compflags(toolname, langkind, name, values) return compiler.map_flags(langkind, name, values, {target = fake_target}) end +-- split flag with tool prefix, e.g. clang::-Dclang +function _split_flag_with_tool_prefix(flag) + local prefix + local splitinfo = flag:split("::") + if #splitinfo == 2 then + prefix = splitinfo[1] + flag = splitinfo[2] + end + return prefix, flag +end + -- get flags from fileconfig function _get_flags_from_fileconfig(fileconfig, outputdir, name) local flags = {} @@ -271,8 +282,19 @@ end -- get flags from target -- @see https://github.com/xmake-io/xmake/issues/3594 function _get_flags_from_target(target, flagkind) + local results = {} local flags = _get_configs_from_target(target, flagkind) - return target_utils.translate_flags_in_tool(target, flagkind, flags) + for _, flag in ipairs(flags) do + local tools = target:extraconf(flagkind, flag, "tools") + if not flag:find("::", 1, true) and tools then + for _, toolname in ipairs(tools) do + table.insert(results, toolname .. "::" .. flag) + end + else + table.insert(results, flag) + end + end + return results end -- set compiler @@ -634,26 +656,74 @@ function _add_target_compile_options(cmakelists, target, outputdir) local cxflags = _get_flags_from_target(target, "cxflags") local cxxflags = _get_flags_from_target(target, "cxxflags") local cuflags = _get_flags_from_target(target, "cuflags") - if #cflags > 0 or #cxflags > 0 or #cxxflags > 0 or #cuflags > 0 then - cmakelists:print("target_compile_options(%s PRIVATE", target:name()) - for _, flag in ipairs(_translate_flags(cflags, outputdir)) do - flag = _escape_path_in_flag(target, flag) - cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">") - end - for _, flag in ipairs(_translate_flags(cxflags, outputdir)) do - flag = _escape_path_in_flag(target, flag) - cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">") - cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">") - end - for _, flag in ipairs(_translate_flags(cxxflags, outputdir)) do - flag = _escape_path_in_flag(target, flag) - cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">") + local toolnames = hashset.new() + local function _add_target_compile_options_for_compiler(toolname) + if #cflags > 0 or #cxflags > 0 or #cxxflags > 0 or #cuflags > 0 then + cmakelists:print("target_compile_options(%s PRIVATE", target:name()) + for _, flag in ipairs(_translate_flags(cflags, outputdir)) do + local prefix + prefix, flag = _split_flag_with_tool_prefix(flag) + if prefix == toolname then + flag = _escape_path_in_flag(target, flag) + cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">") + end + if prefix then + toolnames:insert(prefix) + end + end + for _, flag in ipairs(_translate_flags(cxflags, outputdir)) do + local prefix + prefix, flag = _split_flag_with_tool_prefix(flag) + if prefix == toolname then + flag = _escape_path_in_flag(target, flag) + cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">") + cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">") + end + if prefix then + toolnames:insert(prefix) + end + end + for _, flag in ipairs(_translate_flags(cxxflags, outputdir)) do + local prefix + prefix, flag = _split_flag_with_tool_prefix(flag) + if prefix == toolname then + flag = _escape_path_in_flag(target, flag) + cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">") + end + if prefix then + toolnames:insert(prefix) + end + end + for _, flag in ipairs(_translate_flags(cuflags, outputdir)) do + local prefix + prefix, flag = _split_flag_with_tool_prefix(flag) + if prefix == toolname then + flag = _escape_path_in_flag(target, flag) + cmakelists:print(" $<$<COMPILE_LANGUAGE:CUDA>:" .. flag .. ">") + end + if prefix then + toolnames:insert(prefix) + end + end + cmakelists:print(")") end - for _, flag in ipairs(_translate_flags(cuflags, outputdir)) do - flag = _escape_path_in_flag(target, flag) - cmakelists:print(" $<$<COMPILE_LANGUAGE:CUDA>:" .. flag .. ">") + end + _add_target_compile_options_for_compiler() + local compilernames = { + clang = "Clang", + clangxx = "Clang", + gcc = "Gcc", + gxx = "Gcc", + cl = "MSVC", + link = "MSVC" + } + for _, toolname in toolnames:keys() do + local name = compilernames[toolname] + if name then + cmakelists:print("if(%s)", name) + _add_target_compile_options_for_compiler(toolname) + cmakelists:print("endif()") end - cmakelists:print(")") end -- add cflags/cxxflags for the specific source files @@ -962,28 +1032,55 @@ end function _add_target_link_options(cmakelists, target, outputdir) local ldflags = _get_configs_from_target(target, "ldflags") local shflags = _get_configs_from_target(target, "shflags") - if #ldflags > 0 or #shflags > 0 then - local flags = {} - for _, flag in ipairs(table.unique(table.join(ldflags, shflags))) do - table.insert(flags, _translate_flag(flag, outputdir)) - end - if #flags > 0 then - local cmake_minver = _get_cmake_minver() - if cmake_minver:ge("3.13.0") then - cmakelists:print("target_link_options(%s PRIVATE", target:name()) - else - cmakelists:print("target_link_libraries(%s PRIVATE", target:name()) + local toolnames = hashset.new() + local function _add_target_link_options_for_linker(toolname) + if #ldflags > 0 or #shflags > 0 then + local flags = {} + for _, flag in ipairs(table.unique(table.join(ldflags, shflags))) do + table.insert(flags, _translate_flag(flag, outputdir)) end - for _, flag in ipairs(flags) do - flag = _escape_path_in_flag(target, flag) - -- @see https://github.com/xmake-io/xmake/issues/4196 - if cmake_minver:ge("3.12.0") and #os.argv(flag) > 1 then - cmakelists:print(" " .. os.args("SHELL:" .. flag)) + if #flags > 0 then + local cmake_minver = _get_cmake_minver() + if cmake_minver:ge("3.13.0") then + cmakelists:print("target_link_options(%s PRIVATE", target:name()) else - cmakelists:print(" " .. flag) + cmakelists:print("target_link_libraries(%s PRIVATE", target:name()) end + for _, flag in ipairs(flags) do + local prefix + prefix, flag = _split_flag_with_tool_prefix(flag) + if prefix == toolname then + flag = _escape_path_in_flag(target, flag) + -- @see https://github.com/xmake-io/xmake/issues/4196 + if cmake_minver:ge("3.12.0") and #os.argv(flag) > 1 then + cmakelists:print(" " .. os.args("SHELL:" .. flag)) + else + cmakelists:print(" " .. flag) + end + end + if prefix then + toolnames:insert(prefix) + end + end + cmakelists:print(")") end - cmakelists:print(")") + end + end + _add_target_link_options_for_linker() + local linkernames = { + clang = "Clang", + clangxx = "Clang", + gcc = "Gcc", + gxx = "Gcc", + cl = "MSVC", + link = "MSVC" + } + for _, toolname in toolnames:keys() do + local name = linkernames[toolname] + if name then + cmakelists:print("if(%s)", name) + _add_target_link_options_for_linker(toolname) + cmakelists:print("endif()") end end end |
