Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support moduleonly libraries #4707

Merged
merged 40 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4a6acaf
fix objectfile handling
Arthapz Feb 4, 2024
2328ca4
fix missing objectfiles for private modules
Arthapz Feb 4, 2024
538cf30
fix merge
Arthapz Feb 5, 2024
4d3ad3f
fix format
Arthapz Feb 5, 2024
750aa4c
fix gcc
Arthapz Feb 5, 2024
0b8ea93
cull unreferenced modules and fix gcc module mapper
Arthapz Feb 5, 2024
cf0e793
fix tests
Arthapz Feb 5, 2024
6739478
fix gcc
Arthapz Feb 5, 2024
3a7d68d
update relevent tests to use moduleonly target rule
Arthapz Feb 5, 2024
3280d7f
add support of moduleonly targets with c++.moduleonly rule
Arthapz Feb 5, 2024
e8b4daf
fix packages test
Arthapz Feb 5, 2024
effa81f
remove old file
Arthapz Feb 5, 2024
359ad44
fix msvc
Arthapz Feb 5, 2024
cf5c45b
cleanup
Arthapz Feb 5, 2024
3266f5d
fixe module installation
Arthapz Feb 5, 2024
8929c38
implement target kind moduleonly
Arthapz Feb 6, 2024
eb1fd6f
Update xmake.lua
waruqi Feb 7, 2024
50ecef5
Update bar.mpp
waruqi Feb 7, 2024
660d40f
Update xmake.lua
waruqi Feb 7, 2024
ec17990
Update xmake.lua
waruqi Feb 7, 2024
c732c99
Update xmake.lua
waruqi Feb 7, 2024
384256c
improve moduleonly.lua
Arthapz Feb 7, 2024
d98db4c
use table.orderpairs for generate_metadata
Arthapz Feb 7, 2024
618f751
use target:is_binary instead of target:kind() == "binary"
Arthapz Feb 7, 2024
dee7608
fix test
Arthapz Feb 7, 2024
348a74a
update vsxmake to handle moduleonly target kind
Arthapz Feb 7, 2024
56ba14a
fix msvc batchcmds
Arthapz Feb 7, 2024
6f520cf
improve moduleonly vsxmake
Arthapz Feb 7, 2024
6e3d6c4
update vs project generator to support moduleonly target kind
Arthapz Feb 7, 2024
5d08871
cleanup
Arthapz Feb 7, 2024
e721aae
implement basic cmake support for moduleonly
Arthapz Feb 7, 2024
955f2bb
support ProjectReferences for VS project generator
Arthapz Feb 8, 2024
b23959e
fix msvc batchcmds
Arthapz Feb 8, 2024
9354550
fix module compilation for CMake
Arthapz Feb 8, 2024
14a186c
fix CMake moduleonly support
Arthapz Feb 8, 2024
7b6d069
cleanup
Arthapz Feb 8, 2024
b0819c9
support uninstalling modules
Arthapz Feb 8, 2024
3af5f89
add support of xmake package for modules
Arthapz Feb 8, 2024
0550446
Update cmakelists.lua
waruqi Feb 11, 2024
b6983ac
Update main.lua
waruqi Feb 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions tests/projects/c++/modules/link_order/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ add_rules("mode.release", "mode.debug")
set_languages("c++20")

target("foo")
add_rules("c++")
set_kind("static")
add_files("src/foo.mpp", {public = true})
Arthapz marked this conversation as resolved.
Show resolved Hide resolved
set_kind("moduleonly")
add_files("src/foo.mpp")

target("bar")
add_rules("c++")
set_kind("static")
add_files("src/bar.mpp", {public = true})
set_kind("moduleonly")
add_files("src/bar.mpp")

target("link_order_1")
set_kind("binary")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ add_rules("mode.release", "mode.debug")
set_languages("c++20")

target("mod")
set_kind("static")
set_kind("moduleonly")
add_files("src/mod.mpp")
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export module bar2;

export namespace bar {
const char *hello2() {
return "Hello world";
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
add_rules("mode.release", "mode.debug")
set_languages("c++20")

target("bar2")
set_kind("moduleonly")
add_files("*.mpp")
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package("bar2")
set_kind("library")
set_sourcedir(path.join(os.scriptdir(), "src"))

on_install(function(package)
import("package.tools.xmake").install(package, {})
end)
2 changes: 2 additions & 0 deletions tests/projects/c++/modules/packages/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import foo;
import bar;
import bar2;

int main() {
foo::say(bar::hello());
foo::say(bar::hello2());
return 0;
}
4 changes: 2 additions & 2 deletions tests/projects/c++/modules/packages/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ add_rules("mode.release", "mode.debug")
set_languages("c++2b")

add_repositories("my-repo my-repo")
add_requires("foo", "bar")
add_requires("foo", "bar", "bar2")

target("packages")
set_kind("binary")
add_files("src/*.cpp")
add_packages("foo", "bar")
add_packages("foo", "bar", "bar2")
set_policy("build.c++.modules", true)
3 changes: 2 additions & 1 deletion tests/projects/c++/modules/staticlib/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ set_languages("c++20")

target("mod")
set_kind("static")
add_files("src/mod.mpp", "src/mod.cpp", {public = true})
add_files("src/mod.mpp", {public = true})
add_files("src/mod.cpp")

target("hello")
set_kind("binary")
Expand Down
5 changes: 3 additions & 2 deletions tests/projects/c++/modules/user_headerunit2/a/xmake.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
target("a")
set_kind("moduleonly")
add_headerfiles("*.hpp")
add_files("a.mpp")
set_languages("cxxlatest")
set_kind("object")
add_files("a.mpp", {public = true})
4 changes: 2 additions & 2 deletions tests/projects/c++/modules/user_headerunit2/b/xmake.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
target("b")
add_deps("a")
set_kind("moduleonly")
add_files("b.mpp")
set_languages("cxxlatest")
set_kind("object")
add_files("b.mpp", {public = true})
2 changes: 1 addition & 1 deletion xmake/actions/build/build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function _add_batchjobs_builtin(batchjobs, rootjob, target)
end

-- uses the builtin target script
if not job and (target:is_static() or target:is_binary() or target:is_shared() or target:is_object()) then
if not job and (target:is_static() or target:is_binary() or target:is_shared() or target:is_object() or target:is_moduleonly()) then
job, job_leaf = import("kinds." .. target:kind(), {anonymous = true})(batchjobs, rootjob, target)
end
job = job or rootjob
Expand Down
22 changes: 22 additions & 0 deletions xmake/actions/build/kinds/moduleonly.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, TBOOX Open Source Group.
--
-- @author ruki, Arthapz
-- @file moduleonly.lua
--

Arthapz marked this conversation as resolved.
Show resolved Hide resolved
-- imports
inherit("object")
102 changes: 102 additions & 0 deletions xmake/actions/package/local/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ function _package_library(target)
local binarydir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "bin")
local librarydir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "lib")
local headerdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "include")
local modulesdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "modules")

-- copy the library file to the output directory
local targetfile = target:targetfile()
Expand Down Expand Up @@ -142,6 +143,32 @@ function _package_library(target)
end
end

-- copy modules
if target:data("cxx.has_modules") then
import(".rules.c++.modules.modules_support.compiler_support")
import(".rules.c++.modules.modules_support.builder")
Arthapz marked this conversation as resolved.
Show resolved Hide resolved

local modules = compiler_support.localcache():get2(target:name(), "c++.modules")
builder.generate_metadata(target, modules)

local sourcebatch = target:sourcebatches()["c++.build.modules.install"]
if sourcebatch and sourcebatch.sourcefiles then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local fileconfig = target:fileconfig(sourcefile)
local install = fileconfig and fileconfig.public or false
if install then
local modulehash = compiler_support.get_modulehash(target, sourcefile)
local prefixdir = path.join(modulesdir, modulehash)
os.vcp(sourcefile, path.join(prefixdir, path.filename(sourcefile)))
local metafile = compiler_support.get_metafile(target, sourcefile)
if os.exists(metafile) then
os.vcp(metafile, path.join(prefixdir, path.filename(metafile)))
end
end
end
end
end

-- generate xmake.lua
local file = io.open(path.join(packagedir, "xmake.lua"), "w")
if file then
Expand Down Expand Up @@ -261,6 +288,80 @@ function _package_headeronly(target)
print("package(%s): %s generated", packagename, packagedir)
end

function _package_moduleonly(target)
import(".rules.c++.modules.modules_support.compiler_support")
import(".rules.c++.modules.modules_support.builder")
Arthapz marked this conversation as resolved.
Show resolved Hide resolved

-- get the output directory
local packagedir = target:packagedir()
local packagename = target:name():lower()
local headerdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "include")
local modulesdir = path.join(packagedir, target:plat(), target:arch(), config.mode(), "modules")

local modules = compiler_support.localcache():get2(target:name(), "c++.modules")
builder.generate_metadata(target, modules)

-- copy headers
local srcheaders, dstheaders = target:headerfiles(headerdir)
if srcheaders and dstheaders then
local i = 1
for _, srcheader in ipairs(srcheaders) do
local dstheader = dstheaders[i]
if dstheader then
os.vcp(srcheader, dstheader)
end
i = i + 1
end
end

-- copy modules
local sourcebatch = target:sourcebatches()["c++.build.modules.install"]
if sourcebatch and sourcebatch.sourcefiles then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
local modulehash = compiler_support.get_modulehash(target, sourcefile)
local prefixdir = path.join(modulesdir, modulehash)
os.vcp(sourcefile, path.join(prefixdir, path.filename(sourcefile)))
local metafile = compiler_support.get_metafile(target, sourcefile)
if os.exists(metafile) then
os.vcp(metafile, path.join(prefixdir, path.filename(metafile)))
end
end
end

-- generate xmake.lua
local file = io.open(path.join(packagedir, "xmake.lua"), "w")
if file then
local deps = _get_librarydeps(target)
file:print("package(\"%s\")", packagename)
local homepage = option.get("homepage")
if homepage then
file:print(" set_homepage(\"%s\")", homepage)
end
local description = option.get("description") or ("The " .. packagename .. " package")
file:print(" set_description(\"%s\")", description)
if target:license() then
file:print(" set_license(\"%s\")", target:license())
end
if #deps > 0 then
file:print(" add_deps(\"%s\")", table.concat(deps, "\", \""))
end
file:print("")
file:print([[
on_load(function (package)
package:set("installdir", path.join(os.scriptdir(), package:plat(), package:arch(), package:mode()))
end)

on_fetch(function (package)
local result = {}
result.includedirs = package:installdir("include")
return result
end)]])
file:close()
end

-- show tips
print("package(%s): %s generated", packagename, packagedir)
end
-- do package target
function _do_package_target(target)
if not target:is_phony() then
Expand All @@ -269,6 +370,7 @@ function _do_package_target(target)
binary = _package_binary
, static = _package_library
, shared = _package_library
, moduleonly = _package_moduleonly
, headeronly = _package_headeronly
}
local kind = target:kind()
Expand Down
9 changes: 7 additions & 2 deletions xmake/core/project/target.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1201,9 +1201,14 @@ function _instance:is_headeronly()
return self:kind() == "headeronly"
end

-- is moduleonly target?
function _instance:is_moduleonly()
return self:kind() == "moduleonly"
end

-- is library target?
function _instance:is_library()
return self:is_static() or self:is_shared() or self:is_headeronly()
return self:is_static() or self:is_shared() or self:is_headeronly() or self:is_moduleonly()
end

-- is default target?
Expand Down Expand Up @@ -1555,7 +1560,7 @@ end
function _instance:filename()

-- no target file?
if self:is_object() or self:is_phony() or self:is_headeronly() then
if self:is_object() or self:is_phony() or self:is_headeronly() or self:is_moduleonly() then
return
end

Expand Down
2 changes: 1 addition & 1 deletion xmake/modules/private/check/checkers/api/target/kind.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ import(".api_checker")

function main(opt)
opt = opt or {}
api_checker.check_targets("kind", table.join(opt, {values = {"object", "binary", "static", "shared", "headeronly", "phony"}}))
api_checker.check_targets("kind", table.join(opt, {values = {"object", "binary", "static", "shared", "headeronly", "moduleonly", "phony"}}))
end
9 changes: 9 additions & 0 deletions xmake/modules/target/action/uninstall/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ function _uninstall_files(target)
end
end

-- uninstall modules
function _uninstall_modules(target, opt)
local moduledir = path.join(target:installdir(), opt and opt.moduledir or "modules")
os.vrm(moduledir)
end

-- the builtin uninstall main entry
function main(target, opt)

Expand All @@ -47,6 +53,9 @@ function main(target, opt)
end
end

-- remove modules
_uninstall_modules(target, opt)

-- uninstall the other files
_uninstall_files(target)
end
Expand Down
14 changes: 12 additions & 2 deletions xmake/plugins/project/cmake/cmakelists.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ end
function _escape_path(filepath)
if is_host("windows") then
filepath = filepath:gsub('\\', '/')
filepath = filepath:gsub(' ', '\\ ')
end
return filepath
end
Expand Down Expand Up @@ -323,6 +324,11 @@ function _add_target_headeronly(cmakelists, target)
cmakelists:print("add_library(%s INTERFACE)", target:name())
end

-- add target: headeronly
Arthapz marked this conversation as resolved.
Show resolved Hide resolved
function _add_target_moduleonly(cmakelists, target)
cmakelists:print("add_custom_target(%s)", target:name())
end

-- add target dependencies
function _add_target_dependencies(cmakelists, target)
local deps = target:get("deps")
Expand All @@ -340,8 +346,8 @@ function _add_target_sources(cmakelists, target, outputdir)
local has_cuda = false
cmakelists:print("target_sources(%s PRIVATE", target:name())
local sourcebatches = target:sourcebatches()
for _, sourcebatch in table.orderpairs(sourcebatches) do
if _sourcebatch_is_built(sourcebatch) then
for name, sourcebatch in table.orderpairs(sourcebatches) do
if _sourcebatch_is_built(sourcebatch) and not name:startswith("c++.build.modules") then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
cmakelists:print(" " .. _get_relative_unix_path(sourcefile, outputdir))
end
Expand Down Expand Up @@ -894,6 +900,7 @@ function _get_command_string(cmd, outputdir)
table.insert(argv, _translate_flag(v, outputdir))
end
local command = _escape_path(cmd.program) .. " " .. os.args(argv)
print(cmd.program, _escape_path(cmd.program))
Arthapz marked this conversation as resolved.
Show resolved Hide resolved
if opt and opt.curdir then
command = "${CMAKE_COMMAND} -E chdir " .. _get_relative_unix_path_to_cmake(opt.curdir, outputdir) .. " " .. command
end
Expand Down Expand Up @@ -1003,6 +1010,9 @@ function _add_target(cmakelists, target, outputdir)
_add_target_headeronly(cmakelists, target)
_add_target_include_directories(cmakelists, target, outputdir)
return
elseif targetkind == 'moduleonly' then
_add_target_moduleonly(cmakelists, target)
return
else
raise("unknown target kind %s", target:kind())
end
Expand Down
Loading
Loading