summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-05-07 19:28:50 +0800
committerGitHub <[email protected]>2022-05-07 19:28:50 +0800
commit9781f7bd7e55bea7a4641f991f8bed2d9233f6a6 (patch)
tree50248d3ada1ffe463062967726983148a210dd2b
parentbbcd0a0ecce2f57295de995c4c84984f6ed1a572 (diff)
parent17d95435a75ccace7b9e34a31288099c9e822192 (diff)
Merge pull request #2342 from SirLynix/cmake_outputdir_fix
cmakelists: Fix generation when using a specific output dir
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua149
1 files changed, 75 insertions, 74 deletions
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index fed2f7e42..eea74d04f 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -43,18 +43,19 @@ function _get_cmake_minver()
end
-- get unix path
-function _get_unix_path(filepath)
+function _get_unix_path(filepath, outputdir)
if path.is_absolute(filepath) and filepath:startswith(os.projectdir()) then
filepath = path.relative(filepath, os.projectdir())
end
+ filepath = path.relative(filepath, outputdir)
filepath = path.translate(filepath):gsub('\\', '/')
return os.args(filepath)
end
-- get unix path relative to the cmake path
-- @see https://github.com/xmake-io/xmake/issues/2026
-function _get_unix_path_relative_to_cmake(filepath)
- filepath = _get_unix_path(filepath)
+function _get_unix_path_relative_to_cmake(filepath, outputdir)
+ filepath = _get_unix_path(filepath, outputdir)
if filepath and not path.is_absolute(filepath) then
filepath = "${CMAKE_SOURCE_DIR}/" .. filepath
end
@@ -94,7 +95,7 @@ function _get_configs_from_target(target, name)
end
-- add project info
-function _add_project(cmakelists, languages)
+function _add_project(cmakelists, languages, outputdir)
local cmake_version = _get_cmake_minver()
cmakelists:print([[# this is the build file for project %s
@@ -148,29 +149,29 @@ function _add_target_phony(cmakelists, target)
end
-- add target: binary
-function _add_target_binary(cmakelists, target)
+function _add_target_binary(cmakelists, target, outputdir)
cmakelists:print("add_executable(%s \"\")", target:name())
cmakelists:print("set_target_properties(%s PROPERTIES OUTPUT_NAME \"%s\")", target:name(), target:basename())
- cmakelists:print("set_target_properties(%s PROPERTIES RUNTIME_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir()))
+ cmakelists:print("set_target_properties(%s PROPERTIES RUNTIME_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir(), outputdir))
end
-- add target: static
-function _add_target_static(cmakelists, target)
+function _add_target_static(cmakelists, target, outputdir)
cmakelists:print("add_library(%s STATIC \"\")", target:name())
cmakelists:print("set_target_properties(%s PROPERTIES OUTPUT_NAME \"%s\")", target:name(), target:basename())
- cmakelists:print("set_target_properties(%s PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir()))
+ cmakelists:print("set_target_properties(%s PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir(), outputdir))
end
-- add target: shared
-function _add_target_shared(cmakelists, target)
+function _add_target_shared(cmakelists, target, outputdir)
cmakelists:print("add_library(%s SHARED \"\")", target:name())
cmakelists:print("set_target_properties(%s PROPERTIES OUTPUT_NAME \"%s\")", target:name(), target:basename())
if target:is_plat("windows") then
-- @see https://github.com/xmake-io/xmake/issues/2192
- cmakelists:print("set_target_properties(%s PROPERTIES RUNTIME_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir()))
- cmakelists:print("set_target_properties(%s PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir()))
+ cmakelists:print("set_target_properties(%s PROPERTIES RUNTIME_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir(), outputdir))
+ cmakelists:print("set_target_properties(%s PROPERTIES ARCHIVE_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir(), outputdir))
else
- cmakelists:print("set_target_properties(%s PROPERTIES LIBRARY_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir()))
+ cmakelists:print("set_target_properties(%s PROPERTIES LIBRARY_OUTPUT_DIRECTORY \"%s\")", target:name(), _get_unix_path_relative_to_cmake(target:targetdir(), outputdir))
end
end
@@ -192,14 +193,14 @@ function _add_target_dependencies(cmakelists, target)
end
-- add target sources
-function _add_target_sources(cmakelists, target)
+function _add_target_sources(cmakelists, target, outputdir)
local has_cuda = false
cmakelists:print("target_sources(%s PRIVATE", target:name())
for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
local sourcekind = sourcebatch.sourcekind
if sourcekind == "cc" or sourcekind == "cxx" or sourcekind == "as" or sourcekind == "cu" then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
- cmakelists:print(" " .. _get_unix_path(sourcefile))
+ cmakelists:print(" " .. _get_unix_path(sourcefile, outputdir))
end
end
if sourcekind == "cu" then
@@ -207,7 +208,7 @@ function _add_target_sources(cmakelists, target)
end
end
for _, headerfile in ipairs(target:headerfiles()) do
- cmakelists:print(" " .. _get_unix_path(headerfile))
+ cmakelists:print(" " .. _get_unix_path(headerfile, outputdir))
end
cmakelists:print(")")
if has_cuda then
@@ -221,7 +222,7 @@ end
-- add target source groups
-- @see https://github.com/xmake-io/xmake/issues/1149
-function _add_target_source_groups(cmakelists, target)
+function _add_target_source_groups(cmakelists, target, outputdir)
local filegroups = target:get("filegroups")
for _, filegroup in ipairs(filegroups) do
local files = target:extraconf("filegroups", filegroup, "files") or "**"
@@ -231,60 +232,60 @@ function _add_target_source_groups(cmakelists, target)
local sources = {}
local recurse_sources = {}
if path.is_absolute(rootdir) then
- rootdir = _get_unix_path(rootdir)
+ rootdir = _get_unix_path(rootdir, outputdir)
else
- rootdir = string.format("${CMAKE_CURRENT_SOURCE_DIR}/%s", _get_unix_path(rootdir))
+ rootdir = string.format("${CMAKE_CURRENT_SOURCE_DIR}/%s", _get_unix_path(rootdir, outputdir))
end
for _, filepattern in ipairs(files) do
if filepattern:find("**", 1, true) then
filepattern = filepattern:gsub("%*%*", "*")
- table.insert(recurse_sources, _get_unix_path(path.join(rootdir, filepattern)))
+ table.insert(recurse_sources, _get_unix_path(path.join(rootdir, filepattern), outputdir))
else
- table.insert(sources, _get_unix_path(path.join(rootdir, filepattern)))
+ table.insert(sources, _get_unix_path(path.join(rootdir, filepattern), outputdir))
end
end
if #sources > 0 then
cmakelists:print("FILE(GLOB %s_GROUP_SOURCE_LIST %s)", target:name(), table.concat(sources, " "))
if mode and mode == "plain" then
cmakelists:print("source_group(%s FILES ${%s_GROUP_SOURCE_LIST})",
- _get_unix_path(filegroup), target:name())
+ _get_unix_path(filegroup, outputdir), target:name())
else
cmakelists:print("source_group(TREE %s PREFIX %s FILES ${%s_GROUP_SOURCE_LIST})",
- rootdir, _get_unix_path(filegroup), target:name())
+ rootdir, _get_unix_path(filegroup, outputdir), target:name())
end
end
if #recurse_sources > 0 then
cmakelists:print("FILE(GLOB_RECURSE %s_GROUP_RECURSE_SOURCE_LIST %s)", target:name(), table.concat(recurse_sources, " "))
if mode and mode == "plain" then
cmakelists:print("source_group(%s FILES ${%s_GROUP_RECURSE_SOURCE_LIST})",
- _get_unix_path(filegroup), target:name())
+ _get_unix_path(filegroup, outputdir), target:name())
else
cmakelists:print("source_group(TREE %s PREFIX %s FILES ${%s_GROUP_RECURSE_SOURCE_LIST})",
- rootdir, _get_unix_path(filegroup), target:name())
+ rootdir, _get_unix_path(filegroup, outputdir), target:name())
end
end
end
end
--- add target precompilied header
-function _add_target_precompiled_header(cmakelists, target)
+-- add target precompiled header
+function _add_target_precompiled_header(cmakelists, target, outputdir)
local precompiled_header = target:get("pcheader") or target:get("pcxxheader")
if precompiled_header then
cmakelists:print("target_precompile_headers(%s PRIVATE", target:name())
cmakelists:print(" $<$<COMPILE_LANGUAGE:%s>:${CMAKE_CURRENT_SOURCE_DIR}/%s>",
target:get("pcxxheader") and "CXX" or "C",
- _get_unix_path(precompiled_header))
+ _get_unix_path(precompiled_header, outputdir))
cmakelists:print(")")
end
end
-- add target include directories
-function _add_target_include_directories(cmakelists, target)
+function _add_target_include_directories(cmakelists, target, outputdir)
local includedirs = _get_configs_from_target(target, "includedirs")
if #includedirs > 0 then
cmakelists:print("target_include_directories(%s PRIVATE", target:name())
for _, includedir in ipairs(includedirs) do
- cmakelists:print(" " .. _get_unix_path(includedir))
+ cmakelists:print(" " .. _get_unix_path(includedir, outputdir))
end
cmakelists:print(")")
end
@@ -294,27 +295,27 @@ function _add_target_include_directories(cmakelists, target)
if includedirs_interface then
cmakelists:print("target_include_directories(%s INTERFACE", target:name())
for _, headerdir in ipairs(includedirs_interface) do
- cmakelists:print(" " .. _get_unix_path(headerdir))
+ cmakelists:print(" " .. _get_unix_path(headerdir, outputdir))
end
cmakelists:print(")")
end
-- export config header directory (deprecated)
local configheader = target:configheader()
if configheader then
- cmakelists:print("target_include_directories(%s PUBLIC %s)", target:name(), _get_unix_path(path.directory(configheader)))
+ cmakelists:print("target_include_directories(%s PUBLIC %s)", target:name(), _get_unix_path(path.directory(configheader), outputdir))
end
end
-- add target system include directories
-- we disable system/external includes first, because cmake doesn’t seem to be able to support msvc /external:I
-- https://github.com/xmake-io/xmake/issues/1050
-function _add_target_sysinclude_directories(cmakelists, target)
+function _add_target_sysinclude_directories(cmakelists, target, outputdir)
local includedirs = _get_configs_from_target(target, "sysincludedirs")
if #includedirs > 0 then
-- TODO should be `SYSTEM PRIVATE`
cmakelists:print("target_include_directories(%s PRIVATE", target:name())
for _, includedir in ipairs(includedirs) do
- cmakelists:print(" " .. _get_unix_path(includedir))
+ cmakelists:print(" " .. _get_unix_path(includedir, outputdir))
end
cmakelists:print(")")
end
@@ -322,7 +323,7 @@ function _add_target_sysinclude_directories(cmakelists, target)
if includedirs_interface then
cmakelists:print("target_include_directories(%s INTERFACE", target:name())
for _, headerdir in ipairs(includedirs_interface) do
- cmakelists:print(" " .. _get_unix_path(headerdir))
+ cmakelists:print(" " .. _get_unix_path(headerdir, outputdir))
end
cmakelists:print(")")
end
@@ -543,27 +544,27 @@ function _add_target_link_libraries(cmakelists, target)
end
-- add target link directories
-function _add_target_link_directories(cmakelists, target)
+function _add_target_link_directories(cmakelists, target, outputdir)
local linkdirs = _get_configs_from_target(target, "linkdirs")
if #linkdirs > 0 then
local cmake_minver = _get_cmake_minver()
if cmake_minver:ge("3.13.0") then
cmakelists:print("target_link_directories(%s PRIVATE", target:name())
for _, linkdir in ipairs(linkdirs) do
- cmakelists:print(" " .. _get_unix_path(linkdir))
+ cmakelists:print(" " .. _get_unix_path(linkdir, outputdir))
end
cmakelists:print(")")
else
cmakelists:print("if(MSVC)")
cmakelists:print(" target_link_libraries(%s PRIVATE", target:name())
for _, linkdir in ipairs(linkdirs) do
- cmakelists:print(" -libpath:" .. _get_unix_path(linkdir))
+ cmakelists:print(" -libpath:" .. _get_unix_path(linkdir, outputdir))
end
cmakelists:print(" )")
cmakelists:print("else()")
cmakelists:print(" target_link_libraries(%s PRIVATE", target:name())
for _, linkdir in ipairs(linkdirs) do
- cmakelists:print(" -L" .. _get_unix_path(linkdir))
+ cmakelists:print(" -L" .. _get_unix_path(linkdir, outputdir))
end
cmakelists:print(" )")
cmakelists:print("endif()")
@@ -598,7 +599,7 @@ function _add_target_link_options(cmakelists, target)
end
-- get command string
-function _get_command_string(cmd)
+function _get_command_string(cmd, outputdir)
local kind = cmd.kind
local opt = cmd.opt
if cmd.program then
@@ -606,32 +607,32 @@ function _get_command_string(cmd)
local argv = {}
for _, v in ipairs(table.join(cmd.program, cmd.argv)) do
if path.is_absolute(v) then
- v = _get_unix_path_relative_to_cmake(v)
+ v = _get_unix_path_relative_to_cmake(v, outputdir)
end
table.insert(argv, v)
end
local command = os.args(argv)
if opt and opt.curdir then
- command = "${CMAKE_COMMAND} -E chdir " .. _get_unix_path_relative_to_cmake(opt.curdir) .. " " .. command
+ command = "${CMAKE_COMMAND} -E chdir " .. _get_unix_path_relative_to_cmake(opt.curdir, outputdir) .. " " .. command
end
return command
elseif kind == "cp" then
if os.isdir(cmd.srcpath) then
return string.format("${CMAKE_COMMAND} -E copy_directory %s %s",
- _get_unix_path_relative_to_cmake(cmd.srcpath), _get_unix_path_relative_to_cmake(cmd.dstpath))
+ _get_unix_path_relative_to_cmake(cmd.srcpath, outputdir), _get_unix_path_relative_to_cmake(cmd.dstpath, outputdir))
else
return string.format("${CMAKE_COMMAND} -E copy %s %s",
- _get_unix_path_relative_to_cmake(cmd.srcpath), _get_unix_path_relative_to_cmake(cmd.dstpath))
+ _get_unix_path_relative_to_cmake(cmd.srcpath, outputdir), _get_unix_path_relative_to_cmake(cmd.dstpath, outputdir))
end
elseif kind == "rm" then
- return string.format("${CMAKE_COMMAND} -E rm -rf %s", _get_unix_path_relative_to_cmake(cmd.filepath))
+ return string.format("${CMAKE_COMMAND} -E rm -rf %s", _get_unix_path_relative_to_cmake(cmd.filepath, outputdir))
elseif kind == "mv" then
return string.format("${CMAKE_COMMAND} -E rename %s %s",
- _get_unix_path_relative_to_cmake(cmd.srcpath), _get_unix_path_relative_to_cmake(cmd.dstpath))
+ _get_unix_path_relative_to_cmake(cmd.srcpath, outputdir), _get_unix_path_relative_to_cmake(cmd.dstpath, outputdir))
elseif kind == "cd" then
- return string.format("cd %s", _get_unix_path_relative_to_cmake(cmd.dir))
+ return string.format("cd %s", _get_unix_path_relative_to_cmake(cmd.dir, outputdir))
elseif kind == "mkdir" then
- return string.format("${CMAKE_COMMAND} -E make_directory %s", _get_unix_path_relative_to_cmake(cmd.dir))
+ return string.format("${CMAKE_COMMAND} -E make_directory %s", _get_unix_path_relative_to_cmake(cmd.dir, outputdir))
elseif kind == "show" then
return string.format("echo %s", cmd.showtext)
end
@@ -666,7 +667,7 @@ function _add_target_custom_command(cmakelists, target, command, suffix)
end
-- add target custom commands for target
-function _add_target_custom_commands_for_target(cmakelists, target, suffix)
+function _add_target_custom_commands_for_target(cmakelists, target, outputdir, suffix)
for _, ruleinst in ipairs(target:orderules()) do
local scriptname = "buildcmd" .. (suffix and ("_" .. suffix) or "")
local script = ruleinst:script(scriptname)
@@ -675,7 +676,7 @@ function _add_target_custom_commands_for_target(cmakelists, target, suffix)
script(target, batchcmds_, {})
if not batchcmds_:empty() then
for _, cmd in ipairs(batchcmds_:cmds()) do
- local command = _get_command_string(cmd)
+ local command = _get_command_string(cmd, outputdir)
if command then
_add_target_custom_command(cmakelists, target, command, suffix)
end
@@ -686,7 +687,7 @@ function _add_target_custom_commands_for_target(cmakelists, target, suffix)
end
-- add target custom commands for object rules
-function _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, suffix)
+function _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, outputdir, suffix)
-- get rule
local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!")
@@ -700,7 +701,7 @@ function _add_target_custom_commands_for_objectrules(cmakelists, target, sourceb
script(target, batchcmds_, sourcebatch, {})
if not batchcmds_:empty() then
for _, cmd in ipairs(batchcmds_:cmds()) do
- local command = _get_command_string(cmd)
+ local command = _get_command_string(cmd, outputdir)
if command then
_add_target_custom_command(cmakelists, target, command, suffix)
end
@@ -719,7 +720,7 @@ function _add_target_custom_commands_for_objectrules(cmakelists, target, sourceb
script(target, batchcmds_, sourcefile, {})
if not batchcmds_:empty() then
for _, cmd in ipairs(batchcmds_:cmds()) do
- local command = _get_command_string(cmd)
+ local command = _get_command_string(cmd, outputdir)
if command then
_add_target_custom_command(cmakelists, target, command, suffix)
end
@@ -731,17 +732,17 @@ function _add_target_custom_commands_for_objectrules(cmakelists, target, sourceb
end
-- add target custom commands
-function _add_target_custom_commands(cmakelists, target)
- _add_target_custom_commands_for_target(cmakelists, target, "before")
+function _add_target_custom_commands(cmakelists, target, outputdir)
+ _add_target_custom_commands_for_target(cmakelists, target, outputdir, "before")
for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
local sourcekind = sourcebatch.sourcekind
if sourcekind ~= "cc" and sourcekind ~= "cxx" and sourcekind ~= "as" then
- _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, "before")
- _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch)
- _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, "after")
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, outputdir, "before")
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, outputdir)
+ _add_target_custom_commands_for_objectrules(cmakelists, target, sourcebatch, outputdir, "after")
end
end
- _add_target_custom_commands_for_target(cmakelists, target, "after")
+ _add_target_custom_commands_for_target(cmakelists, target, outputdir, "after")
end
-- TODO export target headers (deprecated)
@@ -760,7 +761,7 @@ function _export_target_headers(target)
end
-- add target
-function _add_target(cmakelists, target)
+function _add_target(cmakelists, target, outputdir)
-- add comment
cmakelists:print("# target")
@@ -770,14 +771,14 @@ function _add_target(cmakelists, target)
if target:is_phony() then
return _add_target_phony(cmakelists, target)
elseif targetkind == "binary" then
- _add_target_binary(cmakelists, target)
+ _add_target_binary(cmakelists, target, outputdir)
elseif targetkind == "static" then
- _add_target_static(cmakelists, target)
+ _add_target_static(cmakelists, target, outputdir)
elseif targetkind == "shared" then
- _add_target_shared(cmakelists, target)
+ _add_target_shared(cmakelists, target, outputdir)
elseif targetkind == 'headeronly' then
_add_target_headeronly(cmakelists, target)
- _add_target_include_directories(cmakelists, target)
+ _add_target_include_directories(cmakelists, target, outputdir)
return
else
raise("unknown target kind %s", target:kind())
@@ -790,13 +791,13 @@ function _add_target(cmakelists, target)
_add_target_dependencies(cmakelists, target)
-- add target precompilied header
- _add_target_precompiled_header(cmakelists, target)
+ _add_target_precompiled_header(cmakelists, target, outputdir)
-- add target include directories
- _add_target_include_directories(cmakelists, target)
+ _add_target_include_directories(cmakelists, target, outputdir)
-- add target system include directories
- _add_target_sysinclude_directories(cmakelists, target)
+ _add_target_sysinclude_directories(cmakelists, target, outputdir)
-- add target compile definitions
_add_target_compile_definitions(cmakelists, target)
@@ -823,33 +824,33 @@ function _add_target(cmakelists, target)
_add_target_link_libraries(cmakelists, target)
-- add target link directories
- _add_target_link_directories(cmakelists, target)
+ _add_target_link_directories(cmakelists, target, outputdir)
-- add target link options
_add_target_link_options(cmakelists, target)
-- add target custom commands
- _add_target_custom_commands(cmakelists, target)
+ _add_target_custom_commands(cmakelists, target, outputdir)
-- add target sources
- _add_target_sources(cmakelists, target)
+ _add_target_sources(cmakelists, target, outputdir)
-- add target source groups
- _add_target_source_groups(cmakelists, target)
+ _add_target_source_groups(cmakelists, target, outputdir)
-- end
cmakelists:print("")
end
-- generate cmakelists
-function _generate_cmakelists(cmakelists)
+function _generate_cmakelists(cmakelists, outputdir)
-- add project info
- _add_project(cmakelists, _get_project_languages(project.targets()))
+ _add_project(cmakelists, _get_project_languages(project.targets()), outputdir)
-- add targets
for _, target in table.orderpairs(project.targets()) do
- _add_target(cmakelists, target)
+ _add_target(cmakelists, target, outputdir)
end
end
@@ -863,7 +864,7 @@ function make(outputdir)
local cmakelists = io.open(path.join(outputdir, "CMakeLists.txt"), "w")
-- generate cmakelists
- _generate_cmakelists(cmakelists)
+ _generate_cmakelists(cmakelists, outputdir)
-- close the cmakelists
cmakelists:close()