<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Linker semantics vary significantly by platform. The behavior you are describing is required for correctness with standard Unix semantics.<div class=""><br class=""></div><div class="">A standard Unix linker proceses command line arguments in the order they are listed. When it processes object files it includes them in the image it is generating by resolving unresolved symbols against the object file, and adding the object file's unresolved symbols to the list of symbols to be resolved. When a library or archive is encountered it uses that library to resolve only the existing unresolved symbols. It does not pull in all symbols from the library. This means that when libraries have dependencies on other libraries you often need to repeat them in order to link correctly. To illustrate this concept better, let me give a more concrete example.</div><div class=""><br class=""></div><div class="">Let's say se have a software project where we have libraries FooBar.a (comprised of Foo.c and Bar.c), and Baz.a (comprised of Baz.c), and we are linking those libraries into a tool named FooBarBaz. If your sources looked something like:</div><div class=""><br class=""></div><div class="">Foo.c:</div><div class=""><br class=""></div><div class="">int Foo() {</div><div class="">  return Baz();</div><div class="">}</div><div class=""><br class=""></div><div class="">Bar.c:</div><div class=""><br class=""></div><div class="">int Bar() {</div><div class="">  return 1</div><div class="">}</div><div class=""><br class=""></div><div class="">Baz.c:</div><div class=""><br class=""></div><div class="">int Baz() {</div><div class="">  return Bar();</div><div class="">}</div><div class=""><br class=""></div><div class="">FooBarBaz.c</div><div class=""><br class=""></div><div class="">int main(..) {</div><div class="">  printf("%i", Foo());</div><div class="">  return 0;</div><div class="">}</div><div class=""><br class=""></div><div class="">Your linker command will need to look like:</div><div class=""><br class=""></div><div class="">ld FooBarBaz.o -lFooBar -lBaz -lFooBar</div><div class=""><br class=""></div><div class="">The reason is because when the linker processes FooBarBaz.o it sees the unresolved symbol Foo, it then sees FooBar, which provides an implementation of Foo (which gets pulled in), but has an unresolved reference to Baz. When Baz is pulled in you end up with an unresolved reference to Bar, so you need to revisit FooBar.</div><div class=""><br class=""></div><div class="">So, that's the basics of *why* CMake is doing what it is doing. The *how* is a little bit more complicated.</div><div class=""><br class=""></div><div class="">At a very basic level CMake has a concept called interface dependencies. The interface dependencies of a target are the libraries that you need to link whenever you link that target. In the example above FooBar would have an interface dependency on Baz, and Baz would have an interface dependency on FooBar.</div><div class=""><br class=""></div><div class="">When CMake constructs the linker command line for FooBarBaz it adds the interface dependencies of each library after the library is visited, and this is applied transitively. So, FooBarBaz links FooBar, which depends on Baz, which depends on FooBar which depends on Baz... When CMAke detects a cycle like that it stops after one repetition (that is a configurable value though). This results in a CMake-generated linker line being something like:</div><div class=""><br class=""></div><div class="">ld FooBarBaz.o -lFooBar -lBaz -lFooBar -lBaz</div><div class=""><br class=""></div><div class="">The second listing of Baz is not strictly required, but it is very hard to detect that in advance so CMake takes a conservative approach.</div><div class=""><br class=""></div><div class="">WRT the delaying question. Not really. CMake doesn't expose direct control over interface library dependencies, and this is largely as a conservative way of ensuring deterministic and correct builds. Because it is possible that multiple libraries could provide different implementations of the same symbols (think link-once-ODRs), the ordering of libraries and the relation to each other impacts the correctness of the output. CMake's approach is probably overly conservative for most situations, but without changing the behavior of CMake (the tool, not our config scripts), I don't believe you can change this.</div><div class=""><br class=""></div><div class="">One other thing to point out is that we actually have two mechanisms for feeding library dependencies in LLVM. In CMake we specify the library dependencies, but we also specify the dependencies in the LLVMBuild.txt files which feed llvm-config. We also have a script that runs during CMake configuration that brings in LLVMBuild's dependency graph and we also incorporate that into our linker dependencies.</div><div class=""><br class=""></div><div class="">Hope this answers your questions.</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 24, 2017, at 12:32 AM, SANJAY SRIVALLABH SINGAPURAM via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><div class="">Hello,</div><div class=""><br class=""></div>I'd like to understand how CMake orders the libraries in <span style="font-family:monospace" class="">LLVM_LINK_COMPONENTS</span> for proper linking in the build command, and especially why it repeats some of them. This is in the context of a patch to link NVPTX libraries into bugpoint (<a href="https://reviews.llvm.org/D32003" class="">D32003</a>) for Polly when <font face="monospace" class="">LLVM_POLLY_LINK_INTO_TOOLS=ON </font>and <span style="font-family:monospace" class="">POLLY_ENABLE_GPGPU_CODEGEN=ON.</span></div><div class=""><br class=""></div><div class="">This patch <a href="https://reviews.llvm.org/D31859" class="">D31859</a> initialises the NVPTX backend within Polly when <span style="font-family:monospace" class="">POLLY_ENABLE_GPGPU_CODEGEN=ON</span> and requires the NVPTX libraries to be linked into the application or library that also links to Polly, e.g. <span style="font-family:monospace" class="">opt, bugpoint</span>. <font face="monospace" class="">opt</font> already links to the backend by adding <span style="font-family:monospace" class="">${LLVM_TARGETS_TO_BUILD</span><span style="font-family:monospace" class="">}</span> to <span style="font-family:monospace" class="">LLVM_LINK_COMPONENTS</span>. I had attempted to link NVPTX into bugpoint in similar ways (<a href="https://reviews.llvm.org/D32003#728913" class="">D32003#728913</a>) and the build kept failing, before finding out that <span style="font-family:monospace" class="">add_llvm_tool</span> was linking the libraries in <span style="font-family:monospace" class="">LLVM_LINK_COMPONENTS</span> to bugpoint. It seemed that CMake was processing LLVM_LINK_COMPONENTS on bugpoint's files before it did on Polly, and hence optimised out <span style="font-family:monospace" class="">COMPONENTS</span> (e.g. NVPTX) which weren't required by bugpoint although required by Polly. Please correct me if I'm wrong here.</div><div class=""><br class=""></div><div class="">Is it possible to indicate to CMake to delay ordering the libraries in <span style="font-family:monospace" class="">LLVM_LINK_COMPONENTS</span> till Polly is linked to bugpoint ?</div><div class="">Or link Polly to bugpoint before the <span style="font-family:monospace" class="">LINK_COMPONENTS</span> ?</div><div class="">Or link NVPTX to bugpoint even if it didn't contain any calls to the NVPTX back-end (like -Wl,--no-as-needed) ?</div><div class=""><br class=""></div><div class=""><a href="https://reviews.llvm.org/D32003#725937" class="">Previous versions</a> of the patch had <font face="monospace" class="">target_link_libraries( bugpoint LLVMNVPTXTargetInfo ...)</font> right after <span style="font-family:monospace" class="">target_link_libraries( bugpoint<span class="inbox-inbox-Apple-converted-space"> Polly)</span></span> which did the job, but I was asked find a less complicated way of accomplishing the same thing.</div><div class=""><br class=""></div><div class="">It was interesting to find to <a href="https://reviews.llvm.org/D32003#728913" class="">some of the libraries repeated in the build command</a>. Can anyone help me understand why this is the case ?</div><div class=""><br class=""></div><div class="">Thank You,</div><div class="">Sanjay</div></div>
_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class=""></div></blockquote></div><br class=""></div></body></html>