我该如何在 Vlang 中创建静态库?

Alb*_*ett 5 vlang

我对 Vlang 比较陌生,正在尝试创建一个静态库来尝试和测试它。我认为它只涉及编译到 C,然后从这些 C 文件创建静态库,并从那里调用,但任何帮助将不胜感激。谢谢。

Key*_*Usr 5

TL;DR:愚蠢而肮脏的方式。但我鼓励进一步阅读解释:

\n
v -shared -o mylibrary.c mylibrary.v\ngcc -c mylibrary.c -o mylibrary.o\nar rcs mylibrary.a mylibrary.o\ngcc -o main main.c mylibrary.a\n./main\n
Run Code Online (Sandbox Code Playgroud)\n
\n

没有官方的方法(或者至少没有weekly.2021.42.1),但是非官方的方法,正如 @AlexanderBielby 提到的。这里是:

\n

注意:对于简单的东西,V 内部的初始化应该不那么重要,但是,对于任何至少稍微复杂一点的东西,几乎所有的地狱都可能会松动,所以对于只是玩,请随意尝试,但如果它\'这是用于生产的,我宁愿不要用 2m 的杆子碰它,除非有官方的方法或者创建者同意这种方法。

\n

注意2:由于它使用-sharedswitch 并且它通常用于共享对象(动态库),所以应该没问题。但这样的“应该”在 C/C++ 世界中是相当危险的。:)

\n

排除了这一点,我假设一个非常简单的mylibrary.v文件。当前的方法可以使用V 的module mainmodule <anything>+-shared开关。我正在使用后者。

\n

将有一个私有fn函数和一个公共pub fn函数:

\n
module notmain\n\nfn say_hi() {\n    println("Hi!")\n}\n\npub fn say_hello() {\n    println("Hello!")\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在,为了构建,让我们从简单的转译到 C 开始:

\n
module notmain\n\nfn say_hi() {\n    println("Hi!")\n}\n\npub fn say_hello() {\n    println("Hello!")\n}\n
Run Code Online (Sandbox Code Playgroud)\n

该文件通常用于创建mylibrary.so文件并包含我们函数的引用。

\n

现在让我们组装一个标头。V 发出的 C 具有模块名称的前缀,这将作为grep. 如果您使用常量、可变变量等,您将需要更多地检查这对最终二进制文件的影响。我假设您不想使用库中的全局变量来使事情变得更简单(尽管如果发出的 C 没问题,“应该”仍然可以工作)。

\n
v -shared -o mylibrary.c mylibrary.v\n
Run Code Online (Sandbox Code Playgroud)\n

我得到这样的东西:

\n
VV_LOCAL_SYMBOL void notmain__say_hi();\nvoid notmain__say_hello();\nVV_LOCAL_SYMBOL void notmain__say_hi(void) {\nvoid notmain__say_hello(void) {\n    // Initializations for module notmain :\n
Run Code Online (Sandbox Code Playgroud)\n

这意味着发出的 C 区分pub fnfn。我将只从公共函数中组装一个标头:

\n
grep notmain mylibrary.c\n
Run Code Online (Sandbox Code Playgroud)\n

然后只需编译它并使用以下命令创建一个静态库ar

\n
VV_LOCAL_SYMBOL void notmain__say_hi();\nvoid notmain__say_hello();\nVV_LOCAL_SYMBOL void notmain__say_hi(void) {\nvoid notmain__say_hello(void) {\n    // Initializations for module notmain :\n
Run Code Online (Sandbox Code Playgroud)\n

并通过示例main.c文件运行它:

\n
cat <<EOF > mylibrary.h\n#pragma once\n#ifndef MYLIBRARY_H\n#define MYLIBRARY_H\nEOF\n\nfor func in $(grep "pub fn" $1|cut -f 3 -d " "|sed -e "s/()//")\ndo\n    grep notmain__${func} mylibrary.c|grep \';\' >> mylibrary.h\ndone\n\necho \'#endif\' >> mylibrary.h\n
Run Code Online (Sandbox Code Playgroud)\n

您可以通过两种(或多种)方式编译它:

\n
gcc -c mylibrary.c -o mylibrary.o\nar rcs mylibrary.a mylibrary.o\n
Run Code Online (Sandbox Code Playgroud)\n

如果您将库命名为lib<something>.a,则可以使用-l<something>flag 代替。正在:指定文件名。

\n

GCC 显然会告诉我们隐式声明,因为该声明不存在于标头中或其他任何地方,并且您仍然会看到它在运行时工作(原因如下)。

\n

让我们让它更有用一点(用 来清理rm *.a *.c *.h *.o main_*):

\n

构建.sh

\n
#include "mylibrary.h"\nint main(void) {\n    notmain__say_hi();\n    notmain__say_hello();\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

和日志:

\n
# ./build.sh mylibrary.v\n+ [ -z mylibrary.v ]\n+ echo mylibrary.v\n+ sed -e s/\\.v//\n+ NAME=mylibrary\n+ grep module  mylibrary.v\n+ cut -f 2 -d \n+ MOD=notmain\n+ grep pub fn+ cut -f 3 -d  \n mylibrary.v\n+ sed -e s/()//\n+ FUNCS=say_hello\n+ tr+  [:lower:] [:upper:]\necho mylibrary_H\n+ GUARD=MYLIBRARY_H\n+ V=./v\n+ CC=gcc\n+ AR=ar\n+ transpile\n+ ./v -shared -o mylibrary.c mylibrary.v\n+ headerify\n+ cat\n+ + grep notmain__say_hello mylibrary.c\ngrep ;\n+ echo #endif\n+ static_compile\n+ gcc -c mylibrary.c -o mylibrary.o\n+ archive\n+ ar rcs mylibrary.a mylibrary.o\n+ create_main\n+ cat\n+ compile_direct\n+ gcc -o main_direct main.c mylibrary.a\nmain.c: In function \xe2\x80\x98main\xe2\x80\x99:\nmain.c:2:17: warning: implicit declaration of function \xe2\x80\x98notmain__say_hi\xe2\x80\x99; did you mean \xe2\x80\x98notmain__say_hello\xe2\x80\x99? [-Wimplicit-function-declaration]\n    2 | int main(void) {notmain__say_hi();notmain__say_hello();return 0;}\n      |                 ^~~~~~~~~~~~~~~\n      |                 notmain__say_hello\n+ compile_link\n+ gcc -o main_link main.c -L. -l:mylibrary.a\nmain.c: In function \xe2\x80\x98main\xe2\x80\x99:\nmain.c:2:17: warning: implicit declaration of function \xe2\x80\x98notmain__say_hi\xe2\x80\x99; did you mean \xe2\x80\x98notmain__say_hello\xe2\x80\x99? [-Wimplicit-function-declaration]\n    2 | int main(void) {notmain__say_hi();notmain__say_hello();return 0;}\n      |                 ^~~~~~~~~~~~~~~\n      |                 notmain__say_hello\n+ run\n+ ./main_direct\nHi!\nHello!\n+ ./main_link\nHi!\nHello!\n
Run Code Online (Sandbox Code Playgroud)\n

玩得开心!^^

\n