<p>If I have a dependency between files first.c and second.c, I can still build a static library first.a, which is just a packaged form of first.o. </p>
<p>But if I try to then build a go library that uses first.a I get a linker error for the missing symbols of second.</p>
<p>eg. go install -buildmode=c-archive uses_first.go </p>
<p>Now, were I building a executable, it would make perfect sense to reject this on the basis of unresolved symbols. But I'm not building an executable, I'm building another static lib. AFAIK there should be no reason to complain about unresolved dependencies on a lib.</p>
<p>At the end of the day I'm looking to link everything together, but I can't get past this intermediate step.</p>
<hr/>**评论:**<br/><br/>mdempsky: <pre><p>I believe your question can be summarized as why doesn't this file build:</p>
<pre><code>package p
// extern int foo();
import "C"
var x = C.foo()
</code></pre>
<p>The short answer is during package compilation, cgo links the object files into a stub executable so that it can analyze the executable. If <code>foo</code> is not defined, then this stub link will fail. The expected use case is that packages should provide <code>#cgo LDFLAGS</code> directives that link in any necessary dependencies so that the stub executable links okay.</p>
<p>It looks like we could perhaps prevent this failure (e.g., link the stub executable with something like <code>--unresolved-symbols=ignore-all</code>), but I would expect that will just delay the linker errors until later in the build process.</p>
<p>Do you have a need for packages that utilize undefined symbols?</p></pre>Ahhmyface: <pre><p>Temporarily, yes. Because I have a cyclical dependency. If I include the LDFLAGS then it presumes that lib has been built, despite the fact that I have no need for it. The headers can be generated independently. I'm trying to avoid the linking until the final call.</p>
<p>I would like to be able to build like so:
gcc bar.o -L-lfoo -lc_archive -o bar</p>
<p>c-archive depends on foo, foo depends on bar, bar depends on c-archive</p>
<p>Is my only option to break the cycle?</p></pre>mdempsky: <pre><p>I think the only supported way is to break the cycle. I would suggest that as the ideal solution.</p>
<p>You may be able to workaround it with weak symbols. For example, changing the <code>import "C"</code> directive above to:</p>
<pre><code>// extern int foo();
// #pragma weak foo
import "C"
</code></pre>
<p>That at least works around the package link failure.</p></pre>Ahhmyface: <pre><p>I've examined breaking the cycle somewhat, but it strikes me as counterproductive. I have a program written in C that I thought could benefit from some Go. But either I can call it and it can't make any useful changes to state, or I can't call it at all. </p>
<p>The circular dependency is actually really what makes it useful.</p></pre>mdempsky: <pre><p>Can you provide a representative standalone example of your cyclic dependency?</p></pre>Ahhmyface: <pre><p>Sure. something like this</p>
<p>foo.c:</p>
<pre><code>int test = 0;
int main() {
GoIncrementTest();
return test;
}
</code></pre>
<p>foo.go:</p>
<pre><code>/*
#cgo
extern int test;
*/
//export GoIncrementTest
func GoIncrementTest() {
test+=1
}
</code></pre></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
0 回复
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传