Skip to content

Commit

Permalink
improve flags support for target
Browse files Browse the repository at this point in the history
  • Loading branch information
waruqi committed Aug 20, 2024
1 parent 624b853 commit 4a647b1
Showing 1 changed file with 134 additions and 37 deletions.
171 changes: 134 additions & 37 deletions xmake/plugins/project/cmake/cmakelists.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 4a647b1

Please sign in to comment.