Brad King wrote: > On 10/22/2012 05:42 PM, Stephen Kelly wrote: >> Ah, I was wondering about that when I wrote that patch, but forgot to put >> in the email. I thought they would be able to have per-config >> dependencies. >> >> set_property(TARGET foo LINK_LIBRARIES $<$<Config:Debug>:debughelpers> >> >> will never work with IDE generators? That's not a limitation of the >> generators but of the IDEs? > > That can work because the IDEs support per-config link libraries. > It's the logical build ordering dependencies among targets that are > not per-config. That means in a Release build the IDE will still > want to build debughelpers before foo, but will not actually have > to link to it.
Ok, I see. Thanks. > >> target_link_libraries(bar LINK_PUBLIC foo) >> # bar LINK_LIBRARIES is now: >> # "foo;$<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES>" >> # bar INTERFACE_LINK_LIBRARIES is now: >> # "foo;$<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES>" > > Why does "$<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES>" > belong in either one of them? The transitive closure should be > computed by link-aware code that knows it must follow foo's link > interface, not just by generator expression evaluation. The > purpose of GetOriginalLinkLibraries is to get the directly linked > libraries without any transitive dependencies. This is why I was uncertain about this section :). I wasn't sure why or whether it would be important for GetOriginalLinkLibraries to not contain transitive dependencies. What is 'link-aware code'? A part of the cmake implementation that has rules specific to linking where the difference between the direct and transitive dependencies is important? The "$<TARGET_PROPERTY:foo,INTERFACE_LINK_LIBRARIES>" belongs in the INTERFACE_LINK_LIBRARIES of bar because it links to foo with LINK_PUBLIC. If it used LINK_PRIVATE it would not appear there. The expression belongs in LINK_LIBRARIES of bar because it links to foo and therefore must link to things foo says it must link to. This means that by evaluating the LINK_LIBRARIES expression for a target, we get all of its dependencies (probably with duplication, something else I haven't thought through yet if that's a problem). Because we have all dependencies, it should be easier to get the INCLUDE_DIRECTORIES and COMPILE_DEFINITIONS etc too. It also made the code I had to write much less complex (only one place to add the use of generator expressions). However, if the direct and transitive dependencies really must be kept separate, that will have to be rethought anyway. > >> # In my branch WIN32_EXECUTABLE would be defaulted to: >> # >> # $<EACH:$<TARGET_PROPERTY:LINK_LIBRARIES>," >> # "$<OR:$<EACH_ACCUMULATED:0>," >> # "$<BOOL:$<TARGET_PROPERTY:$<EACH_ARG>," >> # "INTERFACE_WIN32_EXECUTABLE>>>" >> # >> # That is, check if any of the link libraries say WIN32_EXECUTABLE >> # should be ON. > > What is the use case for that default? I think enabling the > WIN32_EXECUTABLE option should remain an explicit choice. Sure, for that property maybe so. That's not future-proof though. There may be other properties we want to add in the future where it does make sense. For example, it makes sense for POSITION_INDEPENDENT_CODE, so Qt5Core should have INTERFACE_POSITION_INDEPENDENT_CODE ON and the POSITION_INDEPENDENT_CODE property should be evaluated with EACH as I pseudo-implemented in my patch. I can't think of a reason to link a library based on whether POSITION_INDEPENDENT_CODE is true or false for a target. However, you can see that the dependency from target property to link libraries is in the opposite direction to the direction for WIN32_EXECUTABLE. That means that there may be a property for which it could make sense in either direction (ie, that it could make sense to link a library based on a FOO property, or it might make sense to set the FOO property based on what is linked), and we can't control that choice. If we release CMake 2.8.11 with the FOO property, we can't add something like this to CMake 2.8.12: setPropertyDefault("FOO", "$<EACH:$<TARGET_PROPERTY:LINK_LIBRARIES>," "$<OR:$<EACH_ACCUMULATED:0>," "$<BOOL:$<TARGET_PROPERTY:$<EACH_ARG>," "INTERFACE_FOO>>>") because user code might already be doing this: target_link_libraries(exe $<$<TARGET_PROPERTY:FOO>:bar>) and that would become a cycle. In somewhat more concrete terms, maybe if the STD_CXX11 property ever becomes a reality, a library built with c++11 might require that downstreams also use c++11 because of binary compatibility concerns in the stdlib implementation. (See http://gcc.gnu.org/ml/gcc/2012-06/msg00239.html for example, but even if all issues with GCC are fixed, there are many other compilers out there). Similarly, a cxx98helpers library might be linked if $<NOT$<TARGET_PROPERTY:STD_CXX11>>. So, I don't think we can ignore the issue of cycles completely, but we might be able to simply choose up front the direction of dependence of properties that are there when this feature lands, and when future properties land, how they're going to work and then stick with that choice. >> Can you give more information about the case you mention? I don't see any >> mention in the documentation of using find_package() with a directory. > > Projects may do this: > > if(NOT USE_SYSTEM_FOO) > add_subdirectory(Foo) > set(Foo_DIR ${CMAKE_CURRENT_BINARY_DIR}/Foo) > endif() > find_package(Foo) > ... > target_link_libraries(MyExe ${Foo_LIBRARIES}) > > such that Foo_LIBRARIES ends up with namespaced imported targets > that refer to the in-tree real targets. I see. Thanks. > >>> We need to consider how to handle compatibility here, >>> but only with projects not using the new features enabled by delaying >>> export() until generate time. Can you explain this in more detail? >> >> This may only be doable by duplicating a lot more code and making >> cmExportBuildFileGenerator not inherit from cmExportFileGenerator. The >> latter uses GetLinkInterface, GetSoName and HasSoName. >> >> HasSoName depends on the link languages, and therefore the libraries and >> therefore has to move to cmGeneratorTarget. If export() is to remain a >> configure-time construct, then HasSoName would have to remain in some >> form in cmTarget. That could mean a lot of duplication. > > We may need a policy implemented with minimum duplication to provide > the capabilities that export() used to. Would the policy be used to determine whether to execute the export() at configure-time (and strip out any generator expressions found) or at generate-time (and process the generator expressions)? It still looks like a lot of duplication to me (my commit that moves HasSOName and all previous commits may need to be copied). Maybe it's not as bad as it seems though. Thanks, Steve. -- Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers