canonical/libco - "Undefined symbols for architecture" MacOS 上的编译和链接问题
Compilation and linking issues on MacOS for canonical/libco - "Undefined symbols for architecture"
我使用的是 MacOS Catalina 10.15.3。我正在尝试构建 Caonical 的 dqlite
as I want to try the experimental features of k3s
which uses it as distributed database instead of etcd
或其他。
我看到的错误是依赖项之一 libco
.
我使用以下命令构建了库:
clang libco.c -g -O2 -Wall -fPIC -c -DLIBCO_MP
clang libco.o -dynamiclib -Wl,-install_name,libco.dylib -o libco.dylib
并且我已将这些文件分别移动到 /usr/local/lib/libco.dylib
和 /usr/local/include/libco.h
。
当我尝试构建一个简单的测试文件时出现问题(请忽略此文件中的错误,我尝试将 this one 改编为独立测试):
#include <libco.h>
#include <stdlib.h>
#include <assert.h>
/* Execution context of a test coroutine, passed using the global ctx
* variable. */
struct ctx
{
cothread_t main; /* Reference to the main coroutine */
int v1;
int v2;
};
static struct ctx *ctx; /* Argument for test coroutines */
struct fixture
{
cothread_t main; /* Main coroutine */
cothread_t coro1; /* First coroutine */
cothread_t coro2; /* Second coroutine */
struct ctx ctx1; /* Context for first coroutine */
struct ctx ctx2; /* Context for second coroutine */
};
static void coro()
{
struct ctx *c = ctx;
c->v1 = 1;
co_switch(c->main);
c->v2 = 2;
co_switch(c->main);
}
int main()
{
struct fixture *f = malloc(sizeof *f);
f->main = co_active();
f->coro1 = co_create(1024 * 1024, coro);
f->coro2 = co_create(1024 * 1024, coro);
f->ctx1.main = f->main;
f->ctx2.main = f->main;
/* Start executing coro1 */
ctx = &f->ctx1;
co_switch(f->coro1);
/* The v1 field of the context has been initialized, but v2 has not. */
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 0);
/* Start executing coro2 */
ctx = &f->ctx2;
co_switch(f->coro2);
/* The v1 field of the second context has been initialized, but v2 has
* not. */
assert(f->ctx2.v1 == 1);
assert(f->ctx2.v2 == 0);
/* The fields of the first context are still the same. */
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 0);
/* Resume execution of coro2 */
co_switch(f->coro2);
/* The v2 field of the second context has been initialized too, but the
* one of the first context still hasn't. */
assert(f->ctx2.v1 == 1);
assert(f->ctx2.v2 == 2);
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 0);
/* Resume execution of coro1 */
co_switch(f->coro1);
/* The v2 field of the first context has been initialized too now. */
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 2);
co_delete(f->coro1);
co_delete(f->coro2);
free(f);
return 0;
}
尝试使用 clang test.c -o test
进行编译会导致以下结果:
Undefined symbols for architecture x86_64:
"_co_active", referenced from:
_main in test-b98908.o
"_co_create", referenced from:
_main in test-b98908.o
"_co_delete", referenced from:
_main in test-b98908.o
"_co_switch", referenced from:
_main in test-b98908.o
_coro in test-b98908.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
然而,经过进一步检查,我发现这些符号似乎是在 libco.dylib
库中定义的:
$ lipo -info /usr/local/lib/libco.dylib
Non-fat file: /usr/local/lib/libco.dylib is architecture: x86_64
$ nm /usr/local/lib/libco.dylib
U ___assert_rtn
0000000000005058 d __dyld_private
U __tlv_bootstrap
0000000000001d60 T _co_active
0000000000005040 s _co_active_buffer
0000000000005070 s _co_active_buffer$tlv$init
0000000000005028 s _co_active_handle
0000000000005060 s _co_active_handle$tlv$init
0000000000001e60 T _co_create
0000000000001f20 T _co_delete
0000000000001da0 T _co_derive
0000000000001f50 T _co_serializable
0000000000005270 b _co_swap
0000000000002000 s _co_swap_function
0000000000001f30 T _co_switch
0000000000001f60 t _crash
0000000000001f70 t _crash.cold.1
U _free
U _malloc
U _mprotect
U _sysconf
U dyld_stub_binder
我想剩下的唯一选择是编译器没有找到库,所以问题可能是 name
或库路径解析问题,但我似乎无法弄清楚。
我错过了什么?
谢谢。
您需要告诉 clang
包含文件在哪里、库在哪个目录中以及您要使用哪些库:
clang program.c -o program -I/usr/local/include -L/usr/local/lib -lco
我使用的是 MacOS Catalina 10.15.3。我正在尝试构建 Caonical 的 dqlite
as I want to try the experimental features of k3s
which uses it as distributed database instead of etcd
或其他。
我看到的错误是依赖项之一 libco
.
我使用以下命令构建了库:
clang libco.c -g -O2 -Wall -fPIC -c -DLIBCO_MP
clang libco.o -dynamiclib -Wl,-install_name,libco.dylib -o libco.dylib
并且我已将这些文件分别移动到 /usr/local/lib/libco.dylib
和 /usr/local/include/libco.h
。
当我尝试构建一个简单的测试文件时出现问题(请忽略此文件中的错误,我尝试将 this one 改编为独立测试):
#include <libco.h>
#include <stdlib.h>
#include <assert.h>
/* Execution context of a test coroutine, passed using the global ctx
* variable. */
struct ctx
{
cothread_t main; /* Reference to the main coroutine */
int v1;
int v2;
};
static struct ctx *ctx; /* Argument for test coroutines */
struct fixture
{
cothread_t main; /* Main coroutine */
cothread_t coro1; /* First coroutine */
cothread_t coro2; /* Second coroutine */
struct ctx ctx1; /* Context for first coroutine */
struct ctx ctx2; /* Context for second coroutine */
};
static void coro()
{
struct ctx *c = ctx;
c->v1 = 1;
co_switch(c->main);
c->v2 = 2;
co_switch(c->main);
}
int main()
{
struct fixture *f = malloc(sizeof *f);
f->main = co_active();
f->coro1 = co_create(1024 * 1024, coro);
f->coro2 = co_create(1024 * 1024, coro);
f->ctx1.main = f->main;
f->ctx2.main = f->main;
/* Start executing coro1 */
ctx = &f->ctx1;
co_switch(f->coro1);
/* The v1 field of the context has been initialized, but v2 has not. */
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 0);
/* Start executing coro2 */
ctx = &f->ctx2;
co_switch(f->coro2);
/* The v1 field of the second context has been initialized, but v2 has
* not. */
assert(f->ctx2.v1 == 1);
assert(f->ctx2.v2 == 0);
/* The fields of the first context are still the same. */
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 0);
/* Resume execution of coro2 */
co_switch(f->coro2);
/* The v2 field of the second context has been initialized too, but the
* one of the first context still hasn't. */
assert(f->ctx2.v1 == 1);
assert(f->ctx2.v2 == 2);
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 0);
/* Resume execution of coro1 */
co_switch(f->coro1);
/* The v2 field of the first context has been initialized too now. */
assert(f->ctx1.v1 == 1);
assert(f->ctx1.v2 == 2);
co_delete(f->coro1);
co_delete(f->coro2);
free(f);
return 0;
}
尝试使用 clang test.c -o test
进行编译会导致以下结果:
Undefined symbols for architecture x86_64:
"_co_active", referenced from:
_main in test-b98908.o
"_co_create", referenced from:
_main in test-b98908.o
"_co_delete", referenced from:
_main in test-b98908.o
"_co_switch", referenced from:
_main in test-b98908.o
_coro in test-b98908.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
然而,经过进一步检查,我发现这些符号似乎是在 libco.dylib
库中定义的:
$ lipo -info /usr/local/lib/libco.dylib
Non-fat file: /usr/local/lib/libco.dylib is architecture: x86_64
$ nm /usr/local/lib/libco.dylib
U ___assert_rtn
0000000000005058 d __dyld_private
U __tlv_bootstrap
0000000000001d60 T _co_active
0000000000005040 s _co_active_buffer
0000000000005070 s _co_active_buffer$tlv$init
0000000000005028 s _co_active_handle
0000000000005060 s _co_active_handle$tlv$init
0000000000001e60 T _co_create
0000000000001f20 T _co_delete
0000000000001da0 T _co_derive
0000000000001f50 T _co_serializable
0000000000005270 b _co_swap
0000000000002000 s _co_swap_function
0000000000001f30 T _co_switch
0000000000001f60 t _crash
0000000000001f70 t _crash.cold.1
U _free
U _malloc
U _mprotect
U _sysconf
U dyld_stub_binder
我想剩下的唯一选择是编译器没有找到库,所以问题可能是 name
或库路径解析问题,但我似乎无法弄清楚。
我错过了什么?
谢谢。
您需要告诉 clang
包含文件在哪里、库在哪个目录中以及您要使用哪些库:
clang program.c -o program -I/usr/local/include -L/usr/local/lib -lco