diff options
| author | ruki <[email protected]> | 2022-03-02 16:14:48 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-03-02 16:14:48 +0800 |
| commit | f46a4b4a6e5aa5146d46c89987859715f692c727 (patch) | |
| tree | cad88ae6821223ef927c67a43323f72ac8341226 | |
| parent | 0a707bfb27db9d87a8063985f4623c0ed4a81a07 (diff) | |
| parent | f6a48a7481bffa3f8b97ac9cd509eb7f4c202559 (diff) | |
Merge pull request #2118 from xmake-io/export
add export symbols list rule
| -rw-r--r-- | tests/modules/table/test.lua | 20 | ||||
| -rw-r--r-- | tests/projects/c/shared_library_export_all/xmake.lua | 2 | ||||
| -rw-r--r-- | tests/projects/c/shared_library_export_list/src/foo.c | 14 | ||||
| -rw-r--r-- | tests/projects/c/shared_library_export_list/src/foo.export.txt | 2 | ||||
| -rw-r--r-- | tests/projects/c/shared_library_export_list/src/foo.h | 9 | ||||
| -rw-r--r-- | tests/projects/c/shared_library_export_list/src/main.c | 8 | ||||
| -rw-r--r-- | tests/projects/c/shared_library_export_list/test.lua | 3 | ||||
| -rw-r--r-- | tests/projects/c/shared_library_export_list/xmake.lua | 21 | ||||
| -rw-r--r-- | xmake/core/base/interpreter.lua | 24 | ||||
| -rw-r--r-- | xmake/core/base/scopeinfo.lua | 24 | ||||
| -rw-r--r-- | xmake/core/base/table.lua | 42 | ||||
| -rw-r--r-- | xmake/rules/c++/modules/build_modules/msvc.lua | 2 | ||||
| -rw-r--r-- | xmake/rules/utils/symbols/export_list/xmake.lua | 107 |
13 files changed, 247 insertions, 31 deletions
diff --git a/tests/modules/table/test.lua b/tests/modules/table/test.lua index 5ed17620c..569f18e50 100644 --- a/tests/modules/table/test.lua +++ b/tests/modules/table/test.lua @@ -9,3 +9,23 @@ function test_find_if(t) t:are_equal(table.find({1, 2, 4, 4, 5, 6}, 4), {3, 4}) t:are_equal(table.find_first({1, 2, 3, 4, 5, 6}, 4), 4) end + +function test_wrap(t) + t:are_equal(table.wrap(1), {1}) + t:are_equal(table.wrap(nil), {}) + t:are_equal(table.wrap({}), {}) + t:are_equal(table.wrap({1}), {1}) + t:are_equal(table.wrap({{}}), {{}}) + local a = table.wraplock({1}) + t:are_equal(table.wrap({a}), {a}) +end + +function test_unwrap(t) + t:are_equal(table.unwrap(1), 1) + t:are_equal(table.unwrap(nil), nil) + t:are_equal(table.unwrap({}), {}) + t:are_equal(table.unwrap({1}), 1) + t:are_equal(table.unwrap({{}}), {}) + local a = table.wraplock({1}) + t:are_equal(table.unwrap(a), a) +end diff --git a/tests/projects/c/shared_library_export_all/xmake.lua b/tests/projects/c/shared_library_export_all/xmake.lua index 6466a16fc..2797d2024 100644 --- a/tests/projects/c/shared_library_export_all/xmake.lua +++ b/tests/projects/c/shared_library_export_all/xmake.lua @@ -3,7 +3,7 @@ add_rules("mode.release", "mode.debug") target("foo") set_kind("shared") add_files("src/foo.c", "src/bar.cpp") - add_rules("utils.symbols.export_all", {class = true}) + add_rules("utils.symbols.export_all", {export_classes = true}) target("test") set_kind("binary") diff --git a/tests/projects/c/shared_library_export_list/src/foo.c b/tests/projects/c/shared_library_export_list/src/foo.c new file mode 100644 index 000000000..e068c1983 --- /dev/null +++ b/tests/projects/c/shared_library_export_list/src/foo.c @@ -0,0 +1,14 @@ +#include "foo.h" +#include <stdio.h> + +void stub() { + printf("stub\n"); +} + +int sub(int a, int b) { + return a - b; +} + +int add(int a, int b) { + return a + b; +} diff --git a/tests/projects/c/shared_library_export_list/src/foo.export.txt b/tests/projects/c/shared_library_export_list/src/foo.export.txt new file mode 100644 index 000000000..f8c70f59e --- /dev/null +++ b/tests/projects/c/shared_library_export_list/src/foo.export.txt @@ -0,0 +1,2 @@ +add +sub diff --git a/tests/projects/c/shared_library_export_list/src/foo.h b/tests/projects/c/shared_library_export_list/src/foo.h new file mode 100644 index 000000000..d2506bca9 --- /dev/null +++ b/tests/projects/c/shared_library_export_list/src/foo.h @@ -0,0 +1,9 @@ +#ifdef __cplusplus +extern "C" { +#endif + +int add(int a, int b); + +#ifdef __cplusplus +} +#endif diff --git a/tests/projects/c/shared_library_export_list/src/main.c b/tests/projects/c/shared_library_export_list/src/main.c new file mode 100644 index 000000000..1e52e7a81 --- /dev/null +++ b/tests/projects/c/shared_library_export_list/src/main.c @@ -0,0 +1,8 @@ +#include "foo.h" +#include <stdio.h> + +int main(int argc, char** argv) +{ + printf("add(1, 2) = %d\n", add(1, 2)); + return 0; +} diff --git a/tests/projects/c/shared_library_export_list/test.lua b/tests/projects/c/shared_library_export_list/test.lua new file mode 100644 index 000000000..b57362078 --- /dev/null +++ b/tests/projects/c/shared_library_export_list/test.lua @@ -0,0 +1,3 @@ +function main(t) + t:build() +end diff --git a/tests/projects/c/shared_library_export_list/xmake.lua b/tests/projects/c/shared_library_export_list/xmake.lua new file mode 100644 index 000000000..b48e131c2 --- /dev/null +++ b/tests/projects/c/shared_library_export_list/xmake.lua @@ -0,0 +1,21 @@ +add_rules("mode.release", "mode.debug") + +target("foo") + set_kind("shared") + add_files("src/foo.c") + add_rules("utils.symbols.export_list", {symbols = { + "add", + "sub"}}) + +target("foo2") + set_kind("shared") + add_files("src/foo.c") + add_files("src/foo.export.txt") + add_rules("utils.symbols.export_list") + +target("test") + set_kind("binary") + add_deps("foo") + add_files("src/main.c") + + diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua index 8a4ed906c..07aa701dc 100644 --- a/xmake/core/base/interpreter.lua +++ b/xmake/core/base/interpreter.lua @@ -1059,8 +1059,16 @@ function interpreter:api_register_set_values(scope_kind, ...) extra_config = nil end - -- expand values - if not extra_config or extra_config.expand ~= false then + -- @note we need mark table value as meta object to avoid wrap/unwrap + -- if these values cannot be expanded, especially when there is only one value + -- + -- e.g. set_shflags({"-Wl,-exported_symbols_list", exportfile}, {force = true, expand = false}) + if extra_config and extra_config.expand == false then + for _, value in ipairs(values) do + table.wraplock(value) + end + else + -- expand values values = table.join(table.unpack(values)) end @@ -1101,8 +1109,16 @@ function interpreter:api_register_add_values(scope_kind, ...) extra_config = nil end - -- expand values - if not extra_config or extra_config.expand ~= false then + -- @note we need mark table value as meta object to avoid wrap/unwrap + -- if these values cannot be expanded, especially when there is only one value + -- + -- e.g. add_shflags({"-Wl,-exported_symbols_list", exportfile}, {force = true, expand = false}) + if extra_config and extra_config.expand == false then + for _, value in ipairs(values) do + table.wraplock(value) + end + else + -- expand values values = table.join(table.unpack(values)) end diff --git a/xmake/core/base/scopeinfo.lua b/xmake/core/base/scopeinfo.lua index 8a69a9299..b826ac648 100644 --- a/xmake/core/base/scopeinfo.lua +++ b/xmake/core/base/scopeinfo.lua @@ -113,8 +113,16 @@ function _instance:_api_set_values(name, ...) extra_config = nil end - -- expand values - if not extra_config or extra_config.expand ~= false then + -- @note we need mark table value as meta object to avoid wrap/unwrap + -- if these values cannot be expanded, especially when there is only one value + -- + -- e.g. target:set("shflags", {"-Wl,-exported_symbols_list", exportfile}, {force = true, expand = false}) + if extra_config and extra_config.expand == false then + for _, value in ipairs(values) do + table.wraplock(value) + end + else + -- expand values values = table.join(table.unpack(values)) end @@ -154,8 +162,16 @@ function _instance:_api_add_values(name, ...) extra_config = nil end - -- expand values - if not extra_config or extra_config.expand ~= false then + -- @note we need mark table value as meta object to avoid wrap/unwrap + -- if these values cannot be expanded, especially when there is only one value + -- + -- e.g. target:add("shflags", {"-Wl,-exported_symbols_list", exportfile}, {force = true, expand = false}) + if extra_config and extra_config.expand == false then + for _, value in ipairs(values) do + table.wraplock(value) + end + else + -- expand values values = table.join(table.unpack(values)) end diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua index 9868c93d5..6c2b3aaf4 100644 --- a/xmake/core/base/table.lua +++ b/xmake/core/base/table.lua @@ -165,11 +165,7 @@ end -- copy the table to self function table.copy2(self, copied) - - -- clear self first table.clear(self) - - -- copy it copied = copied or {} for k, v in pairs(table.wrap(copied)) do self[k] = v @@ -312,31 +308,35 @@ function table.to_array(iterator, state, var) return result, count end --- unwrap object if be only one -function table.unwrap(object) - if type(object) == "table" then - if #object == 1 then - return object[1] +-- unwrap array if be only one value +function table.unwrap(array) + if type(array) == "table" and not array.__wraplocked__ then + if #array == 1 then + return array[1] end end - return object + return array end --- wrap object to table -function table.wrap(object) - - -- no object? - if nil == object then +-- wrap value to array +function table.wrap(value) + if nil == value then return {} end - - -- wrap it if not table - if type(object) ~= "table" then - return {object} + if type(value) ~= "table" or value.__wraplocked__ then + return {value} end + return value +end - -- ok - return object +-- lock table value to avoid unwrap +-- +-- a = {1}, wrap(a): {1}, unwrap(a): 1 +-- a = wraplock({1}), wrap(a): {a}, unwrap(a): a +function table.wraplock(value) + if type(value) == "table" then + value.__wraplocked__ = true + end end -- remove repeat from the given array diff --git a/xmake/rules/c++/modules/build_modules/msvc.lua b/xmake/rules/c++/modules/build_modules/msvc.lua index dfaf56b41..cb81effd7 100644 --- a/xmake/rules/c++/modules/build_modules/msvc.lua +++ b/xmake/rules/c++/modules/build_modules/msvc.lua @@ -43,7 +43,7 @@ function load_parent(target, opt) local sourcebatches = dep:sourcebatches() if sourcebatches and sourcebatches["c++.build.modules"] then local cachedir = path.join(dep:autogendir(), "rules", "modules", "cache") - target:add("cxxflags", {"/ifcSearchDir", cachedir}, {force = true, expand = true}) + target:add("cxxflags", {"/ifcSearchDir", cachedir}, {force = true, expand = false}) end end end diff --git a/xmake/rules/utils/symbols/export_list/xmake.lua b/xmake/rules/utils/symbols/export_list/xmake.lua new file mode 100644 index 000000000..4184432a4 --- /dev/null +++ b/xmake/rules/utils/symbols/export_list/xmake.lua @@ -0,0 +1,107 @@ +--!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 +-- @file xmake.lua +-- + +-- export the given symbols list +-- +--@code +-- target("foo") +-- set_kind("shared") +-- add_files("src/foo.c") +-- add_rules("utils.symbols.export_list", {symbols = { +-- "add", +-- "sub"}}) +-- +-- target("foo2") +-- set_kind("shared") +-- add_files("src/foo.c") +-- add_files("src/foo.export.txt") +-- add_rules("utils.symbols.export_list") +-- +rule("utils.symbols.export_list") + set_extensions(".export.txt") + on_config(function (target) + assert(target:is_shared(), 'rule("utils.symbols.export_list"): only for shared target(%s)!', target:name()) + local exportfile + local exportkind + local exportsymbols = target:extraconf("rules", "utils.symbols.export_list", "symbols") + if not exportsymbols then + local sourcebatch = target:sourcebatches()["utils.symbols.export_list"] + if sourcebatch then + for _, sourcefile in ipairs(sourcebatch.sourcefiles) do + local list = io.readfile(sourcefile) + if list then + exportsymbols = list:split("\n") + end + break + end + end + end + assert(exportsymbols and #exportsymbols > 0, 'rule("utils.symbols.export_list"): no exported symbols!') + if target:has_tool("ld", "link") then + exportkind = "def" + exportfile = path.join(target:autogendir(), "rules", "symbols", "export_list.def") + target:add("shflags", "/def:" .. exportfile, {force = true}) + elseif target:is_plat("macosx", "iphoneos", "watchos", "appletvos") then + exportkind = "apple" + exportfile = path.join(target:autogendir(), "rules", "symbols", "export_list.exp") + target:add("shflags", {"-Wl,-exported_symbols_list", exportfile}, {force = true, expand = false}) + elseif target:has_tool("ld", "gcc", "gxx", "clang", "clangxx") or + target:has_tool("sh", "gcc", "gxx", "clang", "clangxx") then + exportkind = "ver" + exportfile = path.join(target:autogendir(), "rules", "symbols", "export_list.map") + target:add("shflags", "-Wl,--version-script=" .. exportfile, {force = true}) + elseif target:has_tool("ld", "dmd") or target:has_tool("sh", "dmd") then + exportkind = "ver" + exportfile = path.join(target:autogendir(), "rules", "symbols", "export_list.map") + target:add("shflags", "-L--version-script=" .. exportfile, {force = true}) + elseif target:has_tool("ld", "ld") or target:has_tool("sh", "ld") then + exportkind = "ver" + exportfile = path.join(target:autogendir(), "rules", "symbols", "export_list.map") + target:add("shflags", "--version-script=" .. exportfile, {force = true}) + end + if exportfile and exportkind then + if exportkind == "ver" then + io.writefile(exportfile, ([[{ + global: + %s + + local: + *; +};]]):format(table.concat(exportsymbols, ";\n ") .. ";")) + elseif exportkind == "apple" then + local file = io.open(exportfile, 'w') + for _, symbol in ipairs(exportsymbols) do + if not symbol:startswith("_") then + symbol = "_" .. symbol + end + file:print("%s", symbol) + end + file:close() + elseif exportkind == "def" then + local file = io.open(exportfile, 'w') + file:print("EXPORTS") + for _, symbol in ipairs(exportsymbols) do + file:print("%s", symbol) + end + file:close() + end + end + end) + |
