summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-08-14 21:26:02 +0800
committerruki <[email protected]>2022-08-14 21:26:18 +0800
commitdc58599ef5524ab5bd54126b992a3b2d19be0d30 (patch)
tree596aeaf9cd3f0bbb9c0af95b5aaf37b46f074445
parentcbf9452ce0bf312b6ddcc4ab4bcdf61553100a3c (diff)
improve cmakelists
-rw-r--r--tests/projects/c++/modules/dependence/CMakeLists.txt64
-rw-r--r--xmake/plugins/project/cmake/cmakelists.lua133
2 files changed, 163 insertions, 34 deletions
diff --git a/tests/projects/c++/modules/dependence/CMakeLists.txt b/tests/projects/c++/modules/dependence/CMakeLists.txt
index 19eb7793a..fe09acca6 100644
--- a/tests/projects/c++/modules/dependence/CMakeLists.txt
+++ b/tests/projects/c++/modules/dependence/CMakeLists.txt
@@ -10,16 +10,60 @@ project(dependence LANGUAGES CXX C)
# target
add_executable(dependence "")
set_target_properties(dependence PROPERTIES OUTPUT_NAME "dependence")
-set_target_properties(dependence PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/macosx/x86_64/release")
+set_target_properties(dependence PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build/linux/x86_64/release")
+add_custom_command(OUTPUT output_dependence_932361E8
+ COMMAND echo ${color.build.progress}[ 0%]:${clear} ${color.build.object}generating.cxx.module.bmi mod
+ VERBATIM
+)
+add_custom_target(target_dependence_932361E8
+ DEPENDS output_dependence_932361E8
+)
+add_dependencies(dependence target_dependence_932361E8)
+add_custom_command(OUTPUT output_dependence_981BF74C
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/build/.objs/dependence/linux/x86_64/release/src
+ VERBATIM
+)
+add_custom_target(target_dependence_981BF74C
+ DEPENDS output_dependence_981BF74C
+)
+add_dependencies(dependence target_dependence_981BF74C)
+add_custom_command(OUTPUT output_dependence_812F1CA0
+ COMMAND /usr/bin/gcc -m64 -std=c++20 -fmodules-ts -fmodule-mapper=${CMAKE_SOURCE_DIR}/build/mapper.txt -x c++ -o ${CMAKE_SOURCE_DIR}/build/.objs/dependence/linux/x86_64/release/src/mod.mpp.o -c ${CMAKE_SOURCE_DIR}/src/mod.mpp
+ VERBATIM
+)
+add_custom_target(target_dependence_812F1CA0
+ DEPENDS output_dependence_812F1CA0
+)
+add_dependencies(dependence target_dependence_812F1CA0)
+add_custom_command(OUTPUT output_dependence_A56A2AC8
+ COMMAND echo ${color.build.progress}[ 0%]:${clear} ${color.build.object}generating.cxx.module.bmi hello
+ VERBATIM
+)
+add_custom_target(target_dependence_A56A2AC8
+ DEPENDS output_dependence_A56A2AC8
+)
+add_dependencies(dependence target_dependence_A56A2AC8)
+add_custom_command(OUTPUT output_dependence_E41992DB
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/build/.objs/dependence/linux/x86_64/release/src
+ VERBATIM
+)
+add_custom_target(target_dependence_E41992DB
+ DEPENDS output_dependence_E41992DB
+)
+add_dependencies(dependence target_dependence_E41992DB)
+add_custom_command(OUTPUT output_dependence_EAE69E5A
+ COMMAND /usr/bin/gcc -m64 -std=c++20 -fmodules-ts -fmodule-mapper=${CMAKE_SOURCE_DIR}/build/mapper.txt -x c++ -o ${CMAKE_SOURCE_DIR}/build/.objs/dependence/linux/x86_64/release/src/hello.mpp.o -c ${CMAKE_SOURCE_DIR}/src/hello.mpp
+ VERBATIM
+)
+add_custom_target(target_dependence_EAE69E5A
+ DEPENDS output_dependence_EAE69E5A
+)
+add_dependencies(dependence target_dependence_EAE69E5A)
target_compile_options(dependence PRIVATE
$<$<COMPILE_LANGUAGE:C>:-m64>
$<$<COMPILE_LANGUAGE:CXX>:-m64>
- $<$<COMPILE_LANGUAGE:C>:-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk>
- $<$<COMPILE_LANGUAGE:CXX>:-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk>
- $<$<COMPILE_LANGUAGE:CXX>:-fmodules>
- $<$<COMPILE_LANGUAGE:CXX>:-fbuiltin-module-map>
- $<$<COMPILE_LANGUAGE:CXX>:-fimplicit-modules>
- $<$<COMPILE_LANGUAGE:CXX>:-fno-implicit-module-maps>
+ $<$<COMPILE_LANGUAGE:CXX>:-fmodules-ts>
+ $<$<COMPILE_LANGUAGE:CXX>:-fmodule-mapper=${CMAKE_SOURCE_DIR}/build/mapper.txt>
)
target_compile_features(dependence PRIVATE cxx_std_20)
if(MSVC)
@@ -28,16 +72,10 @@ if(MSVC)
endif()
target_link_options(dependence PRIVATE
-m64
- -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk
)
target_sources(dependence PRIVATE
src/hello_impl.cpp
- src/mod_impl.cpp
src/main.cpp
- src/hello_impl.cpp
src/mod_impl.cpp
- src/main.cpp
- src/mod.mpp
- src/hello.mpp
)
diff --git a/xmake/plugins/project/cmake/cmakelists.lua b/xmake/plugins/project/cmake/cmakelists.lua
index 24d78d209..9565bcb40 100644
--- a/xmake/plugins/project/cmake/cmakelists.lua
+++ b/xmake/plugins/project/cmake/cmakelists.lua
@@ -109,6 +109,67 @@ function _get_configs_from_target(target, name)
return table.unique(values)
end
+-- this sourcebatch is built?
+function _sourcebatch_is_built(sourcebatch)
+ -- we can only use rulename to filter them because sourcekind may be bound to multiple rules
+ local rulename = sourcebatch.rulename
+ if rulename == "c++.build" or rulename == "asm.build" or rulename == "cuda.build" then
+ return true
+ end
+end
+
+-- translate flag
+function _translate_flag(flag, outputdir)
+ if flag then
+ if path.instance_of(flag) then
+ flag = flag:clone():set(_get_unix_path_relative_to_cmake(flag:rawstr(), outputdir)):str()
+ elseif path.is_absolute(flag) then
+ flag = _get_unix_path_relative_to_cmake(flag, outputdir)
+ elseif flag:startswith("-fmodule-file=") then
+ flag = "-fmodule-file=" .. _get_unix_path_relative_to_cmake(flag:sub(15), outputdir)
+ elseif flag:startswith("-fmodule-mapper=") then
+ flag = "-fmodule-mapper=" .. _get_unix_path_relative_to_cmake(flag:sub(17), outputdir)
+ elseif flag:match("(.+)=(.+)") then
+ local k, v = flag:match("(.+)=(.+)")
+ if v and v:endswith(".ifc") then -- e.g. hello=xxx/hello.ifc
+ flag = k .. "=" .. _get_unix_path_relative_to_cmake(v, outputdir)
+ end
+ end
+ end
+ return flag
+end
+
+-- translate flags
+function _translate_flags(flags, outputdir)
+ if not flags then
+ return
+ end
+ local result = {}
+ for _, flag in ipairs(flags) do
+ if type(flag) == "table" and not path.instance_of(flag) then
+ for _, v in ipairs(flag) do
+ table.insert(result, _translate_flag(v, outputdir))
+ end
+ else
+ table.insert(result, _translate_flag(flag, outputdir))
+ end
+ end
+ return result
+end
+
+-- get flags from fileconfig
+function _get_flags_from_fileconfig(fileconfig, outputdir, name)
+ local flags = {}
+ table.join2(flags, fileconfig[name])
+ if fileconfig.force then
+ table.join2(flags, fileconfig.force[name])
+ end
+ flags = _translate_flags(flags, outputdir)
+ if #flags > 0 then
+ return table.concat(flags, " ")
+ end
+end
+
-- add project info
function _add_project(cmakelists, languages, outputdir)
@@ -212,9 +273,7 @@ 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
- -- we can only use rulename to filter them because sourcekind may be bound to multiple rules
- local rulename = sourcebatch.rulename
- if rulename == "c++.build" or rulename == "asm.build" or rulename == "cuda.build" then
+ if _sourcebatch_is_built(sourcebatch) then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
cmakelists:print(" " .. _get_unix_path(sourcefile, outputdir))
end
@@ -392,28 +451,66 @@ function _add_target_compile_definitions(cmakelists, target)
end
-- add target compile options
-function _add_target_compile_options(cmakelists, target)
+function _add_target_compile_options(cmakelists, target, outputdir)
local cflags = _get_configs_from_target(target, "cflags")
local cxflags = _get_configs_from_target(target, "cxflags")
local cxxflags = _get_configs_from_target(target, "cxxflags")
local cuflags = _get_configs_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(cflags) do
+ for _, flag in ipairs(_translate_flags(cflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
end
- for _, flag in ipairs(cxflags) do
+ for _, flag in ipairs(_translate_flags(cxflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:C>:" .. flag .. ">")
cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
end
- for _, flag in ipairs(cxxflags) do
+ for _, flag in ipairs(_translate_flags(cxxflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:CXX>:" .. flag .. ">")
end
- for _, flag in ipairs(cuflags) do
+ for _, flag in ipairs(_translate_flags(cuflags, outputdir)) do
cmakelists:print(" $<$<COMPILE_LANGUAGE:CUDA>:" .. flag .. ">")
end
cmakelists:print(")")
end
+
+ -- add cflags/cxxflags for the specific source files
+ for _, sourcebatch in table.orderpairs(target:sourcebatches()) do
+ if _sourcebatch_is_built(sourcebatch) then
+ for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig then
+ local cxxflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cxxflags")
+ if cxxflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CXX>:\"" .. cxxflags .. "\">)")
+ end
+ local cflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cflags")
+ if cflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:C>:\"" .. cflags .. "\">)")
+ end
+ local cxflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cxflags")
+ if cxflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:C>:\"" .. cxflags .. "\">)")
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CXX>:\"" .. cxflags .. "\">)")
+ end
+ local cuflags = _get_flags_from_fileconfig(fileconfig, outputdir, "cuflags")
+ if cuflags then
+ cmakelists:print("set_source_files_properties("
+ .. _get_unix_path_relative_to_cmake(sourcefile, outputdir)
+ .. " PROPERTIES COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CUDA>:\"" .. cuflags .. "\">)")
+ end
+ end
+ end
+ end
+ end
end
-- add target language standards
@@ -700,12 +797,7 @@ function _get_command_string(cmd, outputdir)
-- @see https://github.com/xmake-io/xmake/discussions/2156
local argv = {}
for _, v in ipairs(cmd.argv) do
- if path.instance_of(v) then
- v = v:clone():set(_get_unix_path_relative_to_cmake(v:rawstr(), outputdir)):str()
- elseif path.is_absolute(v) then
- v = _get_unix_path_relative_to_cmake(v, outputdir)
- end
- table.insert(argv, v)
+ table.insert(argv, _translate_flag(v, outputdir))
end
local command = _get_unix_path_relative_to_cmake(cmd.program) .. " " .. os.args(argv)
if opt and opt.curdir then
@@ -831,9 +923,7 @@ end
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
- -- we can only use rulename to filter them because sourcekind may be bound to multiple rules
- local rulename = sourcebatch.rulename
- if rulename ~= "c++.build" and rulename ~= "asm.build" and rulename ~= "cuda.build" then
+ if not _sourcebatch_is_built(sourcebatch) then
_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")
@@ -887,6 +977,10 @@ function _add_target(cmakelists, target, outputdir)
-- add target dependencies
_add_target_dependencies(cmakelists, target)
+ -- add target custom commands
+ -- we need call it first for running all rules, these rules will change some flags, e.g. c++modules
+ _add_target_custom_commands(cmakelists, target, outputdir)
+
-- add target precompilied header
_add_target_precompiled_header(cmakelists, target, outputdir)
@@ -906,7 +1000,7 @@ function _add_target(cmakelists, target, outputdir)
_add_target_language_standards(cmakelists, target)
-- add target compile options
- _add_target_compile_options(cmakelists, target)
+ _add_target_compile_options(cmakelists, target, outputdir)
-- add target warnings
_add_target_warnings(cmakelists, target)
@@ -932,9 +1026,6 @@ function _add_target(cmakelists, target, outputdir)
-- add target link options
_add_target_link_options(cmakelists, target)
- -- add target custom commands
- _add_target_custom_commands(cmakelists, target, outputdir)
-
-- add target sources
_add_target_sources(cmakelists, target, outputdir)