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 SWIG #1622

Closed
xq114 opened this issue Sep 1, 2021 · 25 comments
Closed

Support SWIG #1622

xq114 opened this issue Sep 1, 2021 · 25 comments

Comments

@xq114
Copy link
Contributor

xq114 commented Sep 1, 2021

你在什么场景下需要该功能?

http://www.swig.org/Doc4.0/SWIGDocumentation.html#Introduction_nn4

支持使用SWIG生成各语言接口module

描述可能的解决方案

add_requires("python 3.x")
target("foo_export")
    add_rules("swig.cpp") -- for -c++ flag
    add_files("foo_export.i", {interface = "python"})
    add_files("foo_impl.cpp")
    add_packages("python")

其中运行swig -c++ -python foo_export.i生成的foo_export.cpp自动加入sourcefile中,整个library在linux上生成.so文件,在windows上生成.pyd文件(本质是.dll文件,改后缀名为pyd以便python识别),生成的foo_export.py可以让用户在on_installafter_install中获取并进行copy、rename等操作

其他信息

一些使用cmake+swig的文档/实例
https://cmake.org/cmake/help/latest/module/UseSWIG.html
https://github.com/Mizux/cmake-swig

@waruqi
Copy link
Member

waruqi commented Sep 1, 2021

先排着吧,后面看具体时间排期~

@waruqi
Copy link
Member

waruqi commented Sep 1, 2021

也可以参考这个 先自己搞下,完全类似的 https://github.com/xmake-io/xmake/blob/master/xmake/rules/lex_yacc/yacc/xmake.lua

再额外加个 after_install 就差不多了。

@waruqi waruqi added this to the v2.5.8 milestone Sep 24, 2021
@waruqi waruqi mentioned this issue Sep 24, 2021
@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

初步支持了,见:#1622

python c

add_rules("mode.release", "mode.debug")
add_requires("python 3.x")

target("example")
    add_rules("swig.c", {moduletype = "python"})
    add_files("src/example.i", {scriptdir = "share"})
    add_files("src/example.c")
    add_packages("python")

python c++

add_rules("mode.release", "mode.debug")
add_requires("python 3.x")

target("example")
    add_rules("swig.cpp", {moduletype = "python"})
    add_files("src/example.i", {scriptdir = "share"})
    add_files("src/example.cpp")
    add_packages("python")

moduletype 用于指定模块类型,比如:python, perl5, tcl 对应 swig -python -perl5 -tcl

后面的 scriptdir 参数是可选的,如果设置了,那么语言特定脚本,比如 example.py 文件在 xmake install 会被自动安装到 /usr/local/share 等子目录。。

如果不设置 scriptdir,那么默认不会安装 example.py ,需要用户自己定义 on_install/after_install 去安装它们。

add_rules("mode.release", "mode.debug")
add_requires("python 3.x")

target("example")
    add_rules("swig.cpp", {moduletype = "python"})
    add_files("src/example.i")
    add_files("src/example.cpp")
    add_packages("python")
    after_install(function (target)
         local scriptfiles = target:data("swig.scriptfiles")
         for _, scriptfile in ipairs(scriptfiles) do
             -- os.cp(...)
         end
    end)

另外,tests/projects/swig 目录下有所有例子工程,但是目前只有 python 的,其他perl5/tcl 的暂时没加,因为 xmake-repo 里面还没收录相关包,等后面有时间再说吧,或者你这也可以帮忙补下对应的包。

@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

@waruqi waruqi closed this as completed Sep 24, 2021
@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

提示找不到swig

> swig -version

SWIG Version 4.0.2

Compiled with i686-w64-mingw32-g++ [i686-w64-mingw32]

Configured options: +pcre

Please see http://www.swig.org for reporting bugs and further information
> xmake        
error: ...mdir\core\sandbox\modules\import\core\base\scheduler.lua:56: swig not found!
stack traceback:
        @programdir\core\base\utils.lua:290: in function <@programdir\core\base\utils.lua:280>
        [C]: in function 'error'
        @programdir\core\base\os.lua:829: in function 'os.raiselevel'
        (...tail calls...)
        ...mdir\core\sandbox\modules\import\core\base\scheduler.lua:56: in field 'co_start_withopt'
        @programdir\modules\private\async\runjobs.lua:199: in function <@programdir\modules\private\async\runjobs.lua:159>
        [C]: in function 'xpcall'
        @programdir\core\base\utils.lua:280: in function 'sandbox/modules/utils.trycall'
        @programdir\core\base\scheduler.lua:487: in function 'base/scheduler.co_group_begin'
        ...mdir\core\sandbox\modules\import\core\base\scheduler.lua:94: in field 'co_group_begin'
        @programdir\modules\private\async\runjobs.lua:159: in function <@programdir\modules\private\async\runjobs.lua:54>
        (...tail calls...)
        @programdir\actions\build\build.lua:220: in function <@programdir\actions\build\build.lua:214>
        (...tail calls...)
        @programdir\actions\build\main.lua:133: in function <@programdir\actions\build\main.lua:123>
        [C]: in function 'xpcall'
        @programdir\core\base\utils.lua:280: in function 'sandbox/modules/utils.trycall'
        @programdir\core\sandbox\modules\try.lua:121: in global 'try'
        @programdir\actions\build\main.lua:121: in function <@programdir\actions\build\main.lua:96>
        (...tail calls...)
        [C]: in function 'xpcall'
        @programdir\core\base\utils.lua:280: in function 'sandbox/modules/utils.trycall'
        (...tail calls...)
        @programdir\core\base\task.lua:519: in function 'base/task.run'
        @programdir\core\main.lua:278: in upvalue 'cotask'
        @programdir\core\base\scheduler.lua:371: in function <@programdir\core\base\scheduler.lua:368>

@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

我是mac下测试的走brew安装的swig 没--version参数 所以走了-help测试,你可以改进下 find_swig.lua

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

swig的参数只有单横线,-version,没有--version

@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

刚改了下,再试试

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

现在可以找到swig了;但是找不到的时候,即使没加参数-D,也会print stack trace,我感觉这是个问题

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

另外windows下动态库的命名必须加下划线,所以输出的动态链接库应该是_example.pyd而不是example.pyd,不然python无法识别

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

gcc -shared example.o example_wrap.o -o _example.so

根据文档,linux下生成的是_example.so,应该下划线是每个系统都要加的

@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

gcc -shared example.o example_wrap.o -o _example.so

根据文档,linux下生成的是_example.so,应该下划线是每个系统都要加的

就 linux 下需要?没 lib 前缀么?

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

就 linux 下需要?没 lib 前缀么?

所有系统都需要,没有lib前缀

@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

就 linux 下需要?没 lib 前缀么?

所有系统都需要,没有lib前缀

mac 也是?win 呢?

@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

我改了,再试试

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

image
现在可以了

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

但是找不到的时候,即使没加参数-D,也会print stack trace,我感觉这是个问题

这个问题还是没解决

@waruqi
Copy link
Member

waruqi commented Sep 24, 2021

我没遇到

sandisk:python_c ruki$ xmake
error: swig not found!

@xq114
Copy link
Contributor Author

xq114 commented Sep 24, 2021

我这边测试只有windows上有这个问题,linux上正常

@waruqi
Copy link
Member

waruqi commented Sep 27, 2021

我 dev 上稍微改了下,之前有些设计的不对,moduletype = "python" 模块类型应该放置到 add_rules 上配置,而不是 add_files

因为一个target 只能构建一个同类型模块,还要根据 moduletype 来调整这个模块的 文件名,粒度到 files 就不好控制了

比如 python 模块,是 _example.so/_example.pyd

但是对于 lua 模块,应该是 example.so

其他模块的命名都不一定相同,只能全局配置 moduletype 来控制

add_rules("mode.release", "mode.debug")
add_requires("python 3.x")

target("example")
    add_rules("swig.cpp", {moduletype = "python"})
    add_files("src/example.i", {scriptdir = "share"})
    add_files("src/example.cpp")
    add_packages("python")

Lua + c

https://github.com/xmake-io/xmake/tree/dev/tests/projects/swig/lua_c

另外,我额外加了 lua 模块的支持和 test 例子

add_rules("mode.release", "mode.debug")
add_requires("lua")

target("example")
    add_rules("swig.c", {moduletype = "lua"})
    add_files("src/example.i", {swigflags = "-no-old-metatable-bindings"})
    add_files("src/example.c")
    add_packages("lua")

并且新增了 swigflags 可以单独对某个 xx.i 的 swig 附加额外的 flags 。。

而且之前仅仅处理支持python模块,很多逻辑不够通用,没法适配其他模块,另外我修复了一些其他的小问题

@waruqi
Copy link
Member

waruqi commented Sep 27, 2021

还有 macOS 上 python 模块命名是 _example.so 还是 _example.dylib? 我需要确认下,目前设置了是 _example.dylib

waruqi referenced this issue in RayquazaGX/swigraylib Sep 27, 2021
@Rinkaa
Copy link
Contributor

Rinkaa commented Sep 27, 2021

我试了一下把我这边一个用swig绑定raylib的工程修改了一下,用上了这个新特性:(Rinkaa/swigraylib@6e8cdb2 ):

但是遇到了点问题,xmake编译时最后把.o编译到.so的一步里:
更改前产生的指令:

/usr/bin/g++ -o build/linux/x86_64/release/libswigraylib_lua.so build/.objs/swigraylib_lua/linux/x86_64/release/raylib_wrap.c.o -shared -fPIC -m64 -L/home/ikigai/.xmake/packages/r/raylib/3.7.0/eabe86ecc0a040b7a344e2d58c6a57be/lib -L/usr/lib/x86_64-linux-gnu -L/home/ikigai/.xmake/packages/l/luajit/2.1.0-beta3/149f592bd4fd4f488cf136afa504023b/lib -s -lraylib -lOpenGL -lXext -lX11 -lxcb -lXdmcp -lXau -lXi -lXfixes -lXcursor -lXrender -lXinerama -lXrandr -lluajit -lpthread -lm -ldl

更改后产生的指令:

/usr/bin/g++ -o build/linux/x86_64/release/swigraylib_lua.so build/.objs/swigraylib_lua/linux/x86_64/release/gens/rules/swig/raylib.c.o -shared -fPIC -m64

虽然xmake.lua里add_packages("raylib")一直都在,但是改用新特性后raylib的编译依赖看起来像被吞了……

@waruqi
Copy link
Member

waruqi commented Sep 27, 2021

我试了一下把我这边一个用swig绑定raylib的工程修改了一下,用上了这个新特性:(Rinkaa/swigraylib@6e8cdb2 ):

但是遇到了点问题,xmake编译时最后把.o编译到.so的一步里:
更改前产生的指令:

/usr/bin/g++ -o build/linux/x86_64/release/libswigraylib_lua.so build/.objs/swigraylib_lua/linux/x86_64/release/raylib_wrap.c.o -shared -fPIC -m64 -L/home/ikigai/.xmake/packages/r/raylib/3.7.0/eabe86ecc0a040b7a344e2d58c6a57be/lib -L/usr/lib/x86_64-linux-gnu -L/home/ikigai/.xmake/packages/l/luajit/2.1.0-beta3/149f592bd4fd4f488cf136afa504023b/lib -s -lraylib -lOpenGL -lXext -lX11 -lxcb -lXdmcp -lXau -lXi -lXfixes -lXcursor -lXrender -lXinerama -lXrandr -lluajit -lpthread -lm -ldl

更改后产生的指令:

/usr/bin/g++ -o build/linux/x86_64/release/swigraylib_lua.so build/.objs/swigraylib_lua/linux/x86_64/release/gens/rules/swig/raylib.c.o -shared -fPIC -m64

虽然xmake.lua里add_packages("raylib")一直都在,但是改用新特性后raylib的编译依赖看起来像被吞了……

这个是因为你的target 没有add_files任何c/c++文件,所以xmake没探测到语言类型导致。

你可以先add_files一个空 .c 文件进去就好了

回头我再改进下

@waruqi
Copy link
Member

waruqi commented Sep 27, 2021

我试了一下把我这边一个用swig绑定raylib的工程修改了一下,用上了这个新特性:(Rinkaa/swigraylib@6e8cdb2 ):

但是遇到了点问题,xmake编译时最后把.o编译到.so的一步里:
更改前产生的指令:

/usr/bin/g++ -o build/linux/x86_64/release/libswigraylib_lua.so build/.objs/swigraylib_lua/linux/x86_64/release/raylib_wrap.c.o -shared -fPIC -m64 -L/home/ikigai/.xmake/packages/r/raylib/3.7.0/eabe86ecc0a040b7a344e2d58c6a57be/lib -L/usr/lib/x86_64-linux-gnu -L/home/ikigai/.xmake/packages/l/luajit/2.1.0-beta3/149f592bd4fd4f488cf136afa504023b/lib -s -lraylib -lOpenGL -lXext -lX11 -lxcb -lXdmcp -lXau -lXi -lXfixes -lXcursor -lXrender -lXinerama -lXrandr -lluajit -lpthread -lm -ldl

更改后产生的指令:

/usr/bin/g++ -o build/linux/x86_64/release/swigraylib_lua.so build/.objs/swigraylib_lua/linux/x86_64/release/gens/rules/swig/raylib.c.o -shared -fPIC -m64

虽然xmake.lua里add_packages("raylib")一直都在,但是改用新特性后raylib的编译依赖看起来像被吞了……

刚改进了下,更新到 dev 再试试

@Rinkaa
Copy link
Contributor

Rinkaa commented Sep 27, 2021

现在可以了,感谢处理👍

> xmake
[ 50%]: linking.release swigraylib_lua.so
[100%]: build ok!
> luajit -i -e "package.cpath=package.cpath..';./build/linux/x86_64/release/swig?_lua.so'"
LuaJIT 2.1.0-beta3 -- Copyright (C) 2005-2017 Mike Pall. http://luajit.org/
JIT: ON SSE2 SSE3 SSE4.1 AMD BMI2 fold cse dce fwd dse narrow loop abc sink fuse
> a=require"raylib"
> print(a.RAYLIB_VERSION)
3.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants