Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/27/2010 09:05 AM, Jesper Eskilson wrote: > On 05/26/2010 05:17 PM, Michael Hertling wrote: > >>> Will this still work with an executable E wich depends on B -> C -> B. >>> Won't C pull in A as well? >> >> OK, I suppose, that means you have targets D *and* E in your project, D >> links against A, E against B, A and B both link against C which finally >> needs A *or* B, right? ['fetching a cup of coffee... ;) ] > > Correct. > >> Now, indeed, you can not associate C with A in this exclusive manner >> anymore, but you can make use of an imported target's decoupling from >> its actual file: Introduce two imported library targets CA and CB, both >> pointing to libC.a on disk, but associated with either A or B. Look here: >> >> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) >> PROJECT(ABCDE C) >> # Generate static libraries A,B,C with circular dependencies: >> FILE(WRITE A.c "void fA(void){ fC(); } void ident(void){}") >> FILE(WRITE B.c "void fB(void){ fC(); } void ident(void){}") >> FILE(WRITE C.c "void fC(void){ ident(); }") >> ADD_LIBRARY(A0 STATIC EXCLUDE_FROM_ALL A.c) >> ADD_LIBRARY(B0 STATIC EXCLUDE_FROM_ALL B.c) >> ADD_LIBRARY(C0 STATIC EXCLUDE_FROM_ALL C.c) >> SET_TARGET_PROPERTIES(A0 PROPERTIES ARCHIVE_OUTPUT_NAME A) >> SET_TARGET_PROPERTIES(B0 PROPERTIES ARCHIVE_OUTPUT_NAME B) >> SET_TARGET_PROPERTIES(C0 PROPERTIES ARCHIVE_OUTPUT_NAME C) >> # Incorporate A and B as imported targets: >> ADD_LIBRARY(A STATIC IMPORTED) >> ADD_LIBRARY(B STATIC IMPORTED) >> SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LOCATION >> ${CMAKE_CURRENT_BINARY_DIR}/libA.a) >> SET_TARGET_PROPERTIES(B PROPERTIES IMPORTED_LOCATION >> ${CMAKE_CURRENT_BINARY_DIR}/libB.a) >> # Incorporate two imported targets CA and CB for C: >> ADD_LIBRARY(CA STATIC IMPORTED) >> ADD_LIBRARY(CB STATIC IMPORTED) >> SET_TARGET_PROPERTIES(CA PROPERTIES IMPORTED_LOCATION >> ${CMAKE_CURRENT_BINARY_DIR}/libC.a) >> SET_TARGET_PROPERTIES(CB PROPERTIES IMPORTED_LOCATION >> ${CMAKE_CURRENT_BINARY_DIR}/libC.a) >> # Declare circular dependencies: >> SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES CA) >> SET_TARGET_PROPERTIES(CA PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES A) >> SET_TARGET_PROPERTIES(B PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES CB) >> SET_TARGET_PROPERTIES(CB PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES B) >> # Generate executable D linking against library A: >> FILE(WRITE D.c "void main(void){ fA(); }") >> ADD_EXECUTABLE(D D.c) >> TARGET_LINK_LIBRARIES(D A) >> # Generate executable E linking against library B: >> FILE(WRITE E.c "void main(void){ fB(); }") >> ADD_EXECUTABLE(E E.c) >> TARGET_LINK_LIBRARIES(E B) >> >> After cmaking, type "make {A,B,C}0" to build lib{A,B,C}.a, and then >> "make VERBOSE=1" for the executables D and E; the link lines are: >> >> gcc CMakeFiles/D.dir/D.c.o -o D -rdynamic libA.a libC.a libA.a libC.a >> gcc CMakeFiles/E.dir/E.c.o -o E -rdynamic libB.a libC.a libB.a libC.a >> >> Thus, the circular dependencies are respected as desired without >> repeating A or B in TARGET_LINK_LIBRARIES() for D and E. > > Sounds like a somewhat convoluted solution, [...] IMO, it is a quite straight solution: One just specifies the immediate dependencies and has CMake find out the mediate ones - as it should be - and the speciality of having two different circles in the dependency graph involving the same node is coped with by the declaration of two targets for the same library, so the circles become discontiguous. Regards, Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/26/2010 05:17 PM, Michael Hertling wrote: Will this still work with an executable E wich depends on B -> C -> B. Won't C pull in A as well? OK, I suppose, that means you have targets D *and* E in your project, D links against A, E against B, A and B both link against C which finally needs A *or* B, right? ['fetching a cup of coffee... ;) ] Correct. Now, indeed, you can not associate C with A in this exclusive manner anymore, but you can make use of an imported target's decoupling from its actual file: Introduce two imported library targets CA and CB, both pointing to libC.a on disk, but associated with either A or B. Look here: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(ABCDE C) # Generate static libraries A,B,C with circular dependencies: FILE(WRITE A.c "void fA(void){ fC(); } void ident(void){}") FILE(WRITE B.c "void fB(void){ fC(); } void ident(void){}") FILE(WRITE C.c "void fC(void){ ident(); }") ADD_LIBRARY(A0 STATIC EXCLUDE_FROM_ALL A.c) ADD_LIBRARY(B0 STATIC EXCLUDE_FROM_ALL B.c) ADD_LIBRARY(C0 STATIC EXCLUDE_FROM_ALL C.c) SET_TARGET_PROPERTIES(A0 PROPERTIES ARCHIVE_OUTPUT_NAME A) SET_TARGET_PROPERTIES(B0 PROPERTIES ARCHIVE_OUTPUT_NAME B) SET_TARGET_PROPERTIES(C0 PROPERTIES ARCHIVE_OUTPUT_NAME C) # Incorporate A and B as imported targets: ADD_LIBRARY(A STATIC IMPORTED) ADD_LIBRARY(B STATIC IMPORTED) SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libA.a) SET_TARGET_PROPERTIES(B PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libB.a) # Incorporate two imported targets CA and CB for C: ADD_LIBRARY(CA STATIC IMPORTED) ADD_LIBRARY(CB STATIC IMPORTED) SET_TARGET_PROPERTIES(CA PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libC.a) SET_TARGET_PROPERTIES(CB PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libC.a) # Declare circular dependencies: SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES CA) SET_TARGET_PROPERTIES(CA PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES A) SET_TARGET_PROPERTIES(B PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES CB) SET_TARGET_PROPERTIES(CB PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES B) # Generate executable D linking against library A: FILE(WRITE D.c "void main(void){ fA(); }") ADD_EXECUTABLE(D D.c) TARGET_LINK_LIBRARIES(D A) # Generate executable E linking against library B: FILE(WRITE E.c "void main(void){ fB(); }") ADD_EXECUTABLE(E E.c) TARGET_LINK_LIBRARIES(E B) After cmaking, type "make {A,B,C}0" to build lib{A,B,C}.a, and then "make VERBOSE=1" for the executables D and E; the link lines are: gcc CMakeFiles/D.dir/D.c.o -o D -rdynamic libA.a libC.a libA.a libC.a gcc CMakeFiles/E.dir/E.c.o -o E -rdynamic libB.a libC.a libB.a libC.a Thus, the circular dependencies are respected as desired without repeating A or B in TARGET_LINK_LIBRARIES() for D and E. Sounds like a somewhat convoluted solution, but thanks anyway. Now at least I know that it can be done. -- /Jesper ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/26/2010 12:31 PM, Jesper Eskilson wrote: > On 05/25/2010 05:35 PM, Michael Hertling wrote: >> On 05/25/2010 03:58 PM, Jesper Eskilson wrote: >>> On 05/25/2010 02:41 PM, Michael Hertling wrote: >>> Exactly: The need for A's repetition in the link line is a sole affair of A and C. Therefore, IMO, it should not be brought explicitly to D's link line whereas an approach with two TARGET_LINK_LIBRARIES() for the A'n'C circular dependency and one for D against A would express the actual relations quite accurately. >>> >>> Can CMake express this for IMPORTED libraries as well. Both A, B, and C >>> in this case are (or can be) IMPORTED libraries, and >>> TARGET_LINK_LIBRARIES() fail if the first argument is an IMPORTED library. >>> >>> Until I can figure out how to do that, I'll have to go with repeating A >>> on D's link line. >> >> Look at the following CMakeLists.txt: >> >> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) >> PROJECT(ICD C) >> # Generate circular dependent static libraries: >> FILE(WRITE A.c "void fA(void){ fC(); } void ident(void){}") >> FILE(WRITE C.c "void fC(void){ ident(); }") >> ADD_LIBRARY(A0 STATIC EXCLUDE_FROM_ALL A.c) >> ADD_LIBRARY(C0 STATIC EXCLUDE_FROM_ALL C.c) >> SET_TARGET_PROPERTIES(A0 PROPERTIES ARCHIVE_OUTPUT_NAME A) >> SET_TARGET_PROPERTIES(C0 PROPERTIES ARCHIVE_OUTPUT_NAME C) >> # Incorporate them as imported targets: >> ADD_LIBRARY(A STATIC IMPORTED) >> ADD_LIBRARY(C STATIC IMPORTED) >> SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LOCATION >> ${CMAKE_CURRENT_BINARY_DIR}/libA.a) >> SET_TARGET_PROPERTIES(C PROPERTIES IMPORTED_LOCATION >> ${CMAKE_CURRENT_BINARY_DIR}/libC.a) >> # Declare their circular dependency: >> SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES C) >> SET_TARGET_PROPERTIES(C PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES A) >> # Executable D linking against library A: >> FILE(WRITE D.c "void main(void){ fA(); }") >> ADD_EXECUTABLE(D D.c) >> TARGET_LINK_LIBRARIES(D A) >> >> After CMaking, type "make A0 C0" to build the circular dependent >> libA.a and libC.a, and then "make VERBOSE=1"; the link line is: >> >> gcc CMakeFiles/D.dir/D.c.o -o D -rdynamic libA.a libC.a libA.a libC.a >> >> The target property IMPORTED_LINK_INTERFACE_LIBRARIES seems to make it. > > Will this still work with an executable E wich depends on B -> C -> B. > Won't C pull in A as well? OK, I suppose, that means you have targets D *and* E in your project, D links against A, E against B, A and B both link against C which finally needs A *or* B, right? ['fetching a cup of coffee... ;) ] Now, indeed, you can not associate C with A in this exclusive manner anymore, but you can make use of an imported target's decoupling from its actual file: Introduce two imported library targets CA and CB, both pointing to libC.a on disk, but associated with either A or B. Look here: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(ABCDE C) # Generate static libraries A,B,C with circular dependencies: FILE(WRITE A.c "void fA(void){ fC(); } void ident(void){}") FILE(WRITE B.c "void fB(void){ fC(); } void ident(void){}") FILE(WRITE C.c "void fC(void){ ident(); }") ADD_LIBRARY(A0 STATIC EXCLUDE_FROM_ALL A.c) ADD_LIBRARY(B0 STATIC EXCLUDE_FROM_ALL B.c) ADD_LIBRARY(C0 STATIC EXCLUDE_FROM_ALL C.c) SET_TARGET_PROPERTIES(A0 PROPERTIES ARCHIVE_OUTPUT_NAME A) SET_TARGET_PROPERTIES(B0 PROPERTIES ARCHIVE_OUTPUT_NAME B) SET_TARGET_PROPERTIES(C0 PROPERTIES ARCHIVE_OUTPUT_NAME C) # Incorporate A and B as imported targets: ADD_LIBRARY(A STATIC IMPORTED) ADD_LIBRARY(B STATIC IMPORTED) SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libA.a) SET_TARGET_PROPERTIES(B PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libB.a) # Incorporate two imported targets CA and CB for C: ADD_LIBRARY(CA STATIC IMPORTED) ADD_LIBRARY(CB STATIC IMPORTED) SET_TARGET_PROPERTIES(CA PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libC.a) SET_TARGET_PROPERTIES(CB PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libC.a) # Declare circular dependencies: SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES CA) SET_TARGET_PROPERTIES(CA PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES A) SET_TARGET_PROPERTIES(B PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES CB) SET_TARGET_PROPERTIES(CB PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES B) # Generate executable D linking against library A: FILE(WRITE D.c "void main(void){ fA(); }") ADD_EXECUTABLE(D D.c) TARGET_LINK_LIBRARIES(D A) # Generate executable E linking against library B: FILE(WRITE E.c "void main(void){ fB(); }") ADD_EXECUTABLE(E E.c) TARGET_LINK_LIBRARIES(E B) After cmaking, type "make {A,B,C}0" to build lib{A,B,C}.a, and then "make VERBOSE=1" for the executables D and E; the link lines are: gcc CMakeFiles/D.dir/D.c.o -o D -rdynamic libA.a libC.a libA.a libC.a gcc CMakeFiles/E.dir/E.c.o -o E -rdynamic libB.a libC.a libB.a libC.a Thus, the circular dependencies are respected as d
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/25/2010 05:35 PM, Michael Hertling wrote: On 05/25/2010 03:58 PM, Jesper Eskilson wrote: On 05/25/2010 02:41 PM, Michael Hertling wrote: Exactly: The need for A's repetition in the link line is a sole affair of A and C. Therefore, IMO, it should not be brought explicitly to D's link line whereas an approach with two TARGET_LINK_LIBRARIES() for the A'n'C circular dependency and one for D against A would express the actual relations quite accurately. Can CMake express this for IMPORTED libraries as well. Both A, B, and C in this case are (or can be) IMPORTED libraries, and TARGET_LINK_LIBRARIES() fail if the first argument is an IMPORTED library. Until I can figure out how to do that, I'll have to go with repeating A on D's link line. Look at the following CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(ICD C) # Generate circular dependent static libraries: FILE(WRITE A.c "void fA(void){ fC(); } void ident(void){}") FILE(WRITE C.c "void fC(void){ ident(); }") ADD_LIBRARY(A0 STATIC EXCLUDE_FROM_ALL A.c) ADD_LIBRARY(C0 STATIC EXCLUDE_FROM_ALL C.c) SET_TARGET_PROPERTIES(A0 PROPERTIES ARCHIVE_OUTPUT_NAME A) SET_TARGET_PROPERTIES(C0 PROPERTIES ARCHIVE_OUTPUT_NAME C) # Incorporate them as imported targets: ADD_LIBRARY(A STATIC IMPORTED) ADD_LIBRARY(C STATIC IMPORTED) SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libA.a) SET_TARGET_PROPERTIES(C PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libC.a) # Declare their circular dependency: SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES C) SET_TARGET_PROPERTIES(C PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES A) # Executable D linking against library A: FILE(WRITE D.c "void main(void){ fA(); }") ADD_EXECUTABLE(D D.c) TARGET_LINK_LIBRARIES(D A) After CMaking, type "make A0 C0" to build the circular dependent libA.a and libC.a, and then "make VERBOSE=1"; the link line is: gcc CMakeFiles/D.dir/D.c.o -o D -rdynamic libA.a libC.a libA.a libC.a The target property IMPORTED_LINK_INTERFACE_LIBRARIES seems to make it. Will this still work with an executable E wich depends on B -> C -> B. Won't C pull in A as well? -- /Jesper ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/25/2010 03:58 PM, Jesper Eskilson wrote: > On 05/25/2010 02:41 PM, Michael Hertling wrote: > >> Exactly: The need for A's repetition in the link line is a sole affair >> of A and C. Therefore, IMO, it should not be brought explicitly to D's >> link line whereas an approach with two TARGET_LINK_LIBRARIES() for the >> A'n'C circular dependency and one for D against A would express the >> actual relations quite accurately. > > Can CMake express this for IMPORTED libraries as well. Both A, B, and C > in this case are (or can be) IMPORTED libraries, and > TARGET_LINK_LIBRARIES() fail if the first argument is an IMPORTED library. > > Until I can figure out how to do that, I'll have to go with repeating A > on D's link line. Look at the following CMakeLists.txt: CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(ICD C) # Generate circular dependent static libraries: FILE(WRITE A.c "void fA(void){ fC(); } void ident(void){}") FILE(WRITE C.c "void fC(void){ ident(); }") ADD_LIBRARY(A0 STATIC EXCLUDE_FROM_ALL A.c) ADD_LIBRARY(C0 STATIC EXCLUDE_FROM_ALL C.c) SET_TARGET_PROPERTIES(A0 PROPERTIES ARCHIVE_OUTPUT_NAME A) SET_TARGET_PROPERTIES(C0 PROPERTIES ARCHIVE_OUTPUT_NAME C) # Incorporate them as imported targets: ADD_LIBRARY(A STATIC IMPORTED) ADD_LIBRARY(C STATIC IMPORTED) SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libA.a) SET_TARGET_PROPERTIES(C PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libC.a) # Declare their circular dependency: SET_TARGET_PROPERTIES(A PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES C) SET_TARGET_PROPERTIES(C PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES A) # Executable D linking against library A: FILE(WRITE D.c "void main(void){ fA(); }") ADD_EXECUTABLE(D D.c) TARGET_LINK_LIBRARIES(D A) After CMaking, type "make A0 C0" to build the circular dependent libA.a and libC.a, and then "make VERBOSE=1"; the link line is: gcc CMakeFiles/D.dir/D.c.o -o D -rdynamic libA.a libC.a libA.a libC.a The target property IMPORTED_LINK_INTERFACE_LIBRARIES seems to make it. Regards, Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/25/2010 02:41 PM, Michael Hertling wrote: Exactly: The need for A's repetition in the link line is a sole affair of A and C. Therefore, IMO, it should not be brought explicitly to D's link line whereas an approach with two TARGET_LINK_LIBRARIES() for the A'n'C circular dependency and one for D against A would express the actual relations quite accurately. Can CMake express this for IMPORTED libraries as well. Both A, B, and C in this case are (or can be) IMPORTED libraries, and TARGET_LINK_LIBRARIES() fail if the first argument is an IMPORTED library. Until I can figure out how to do that, I'll have to go with repeating A on D's link line. -- /Jesper ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/25/2010 10:52 AM, Jesper Eskilson wrote: > On 05/24/2010 03:40 PM, Michael Hertling wrote: >> On 05/24/2010 11:20 AM, Jesper Eskilson wrote: >>> Hi, >>> >>> I have two targets, call them A and B. They both link with a third, >>> static library called C. C attempts to invoke a function which is >>> defined by however links with C, i.e. either A or B. >>> >>> This is not a problem as long as A and B are executables or shared >>> libraries, but if A or B is a static library which in turn is linked >>> into a shared object or executable (call it D), then the command becomes >>> something like >>> >>> cc ... -o libD.so -lA -lC >>> >>> since the method C calls in A is unknown by the linker when A is >>> processed, it is discarded. Instead, I would need the command line to >>> look like this: >>> >>> cc ... -o libD.so -lA -lC -lA >>> >>> but how can I do this without explicitly causing A to depend on C? >> >> According to your first paragraph, A does depend on C; what you're >> asking for is a, say, optional dependency of C on A, right? How do >> you decide whether to use A or B? If this is known at CMake time: >> >> TARGET_LINK_LIBRARIES(A C) >> TARGET_LINK_LIBRARIES(C A) >> TARGET_LINK_LIBRARIES(D A) >> >> should do the job for A, and >> >> TARGET_LINK_LIBRARIES(B C) >> TARGET_LINK_LIBRARIES(C B) >> TARGET_LINK_LIBRARIES(D B) >> >> does it for B, alternatively, since TARGET_LINK_LIBRARIES() attends to >> circular dependencies w.r.t. static libraries, see its documentation. >> Furthermore, I suppose you can't use A and B together due to equally >> named symbols defined in both of them, in fact the ones called by C. > > The functions in A or B called by C actually *idenfities* which of A or > B that C is being linked into. Think of A and B as the compiler and the > assembler which links with a utility library C which calls a method in > either A or B which identifies which if the compiler and assembler the > utility library is being used in. Therefrom, I'd draw the conclusion that A and B indeed can't be linked in at the same time because they provide some identical symbols, namely the functions called by C for identification. So, there must be a point in time when you decide whether to link against A or against B, and if this point is at CMake time you could utilize TARGET_LINK_LIBRARIES() for resolving circular dependencies by itself in the above-mentioned manner. That's why I asked how you decide whether to use A or B. > I've solved this for now by doing > > target_link_libraries(D A C A) > > which seems to work, although D needs to know that A has to be repeated > in the libraries list. Exactly: The need for A's repetition in the link line is a sole affair of A and C. Therefore, IMO, it should not be brought explicitly to D's link line whereas an approach with two TARGET_LINK_LIBRARIES() for the A'n'C circular dependency and one for D against A would express the actual relations quite accurately. Regards, Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/24/2010 03:40 PM, Michael Hertling wrote: On 05/24/2010 11:20 AM, Jesper Eskilson wrote: Hi, I have two targets, call them A and B. They both link with a third, static library called C. C attempts to invoke a function which is defined by however links with C, i.e. either A or B. This is not a problem as long as A and B are executables or shared libraries, but if A or B is a static library which in turn is linked into a shared object or executable (call it D), then the command becomes something like cc ... -o libD.so -lA -lC since the method C calls in A is unknown by the linker when A is processed, it is discarded. Instead, I would need the command line to look like this: cc ... -o libD.so -lA -lC -lA but how can I do this without explicitly causing A to depend on C? According to your first paragraph, A does depend on C; what you're asking for is a, say, optional dependency of C on A, right? How do you decide whether to use A or B? If this is known at CMake time: TARGET_LINK_LIBRARIES(A C) TARGET_LINK_LIBRARIES(C A) TARGET_LINK_LIBRARIES(D A) should do the job for A, and TARGET_LINK_LIBRARIES(B C) TARGET_LINK_LIBRARIES(C B) TARGET_LINK_LIBRARIES(D B) does it for B, alternatively, since TARGET_LINK_LIBRARIES() attends to circular dependencies w.r.t. static libraries, see its documentation. Furthermore, I suppose you can't use A and B together due to equally named symbols defined in both of them, in fact the ones called by C. The functions in A or B called by C actually *idenfities* which of A or B that C is being linked into. Think of A and B as the compiler and the assembler which links with a utility library C which calls a method in either A or B which identifies which if the compiler and assembler the utility library is being used in. In the last resort, the GNU linker provides options "--start-group" and "--end-group", or the short ones "-(" and "-)", respectively, meant to resolve circular dependencies among static libraries, but I don't know if one can have CMake intersperse these options in the link line or if this would be portable regarding the various supported platforms. Perhaps, if possible, you should consider to reorganize your project in order to avoid circular dependencies at all, e.g.: Take those parts of A and B that C refers to and turn them into separate libraries A0 and B0. This results in A, B and C depend on A0 and/or B0, and the link line for libD.so would be: "cc ... -o libD.so -lA -lC -lA0" or "cc ... -o libD.so -lB -lC -lB0" Thus, the circular dependencies are gone. Yes, that would probably be nice, but it is unfortunately not an option at this time. Rewriting this is not an option due to the sheer size of the code base which would need refactoring. I've solved this for now by doing target_link_libraries(D A C A) which seems to work, although D needs to know that A has to be repeated in the libraries list. -- /Jesper ___ 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://www.cmake.org/mailman/listinfo/cmake
Re: [CMake] Reverse dependencies (Unix Makefiles)
On 05/24/2010 11:20 AM, Jesper Eskilson wrote: > Hi, > > I have two targets, call them A and B. They both link with a third, > static library called C. C attempts to invoke a function which is > defined by however links with C, i.e. either A or B. > > This is not a problem as long as A and B are executables or shared > libraries, but if A or B is a static library which in turn is linked > into a shared object or executable (call it D), then the command becomes > something like > > cc ... -o libD.so -lA -lC > > since the method C calls in A is unknown by the linker when A is > processed, it is discarded. Instead, I would need the command line to > look like this: > > cc ... -o libD.so -lA -lC -lA > > but how can I do this without explicitly causing A to depend on C? According to your first paragraph, A does depend on C; what you're asking for is a, say, optional dependency of C on A, right? How do you decide whether to use A or B? If this is known at CMake time: TARGET_LINK_LIBRARIES(A C) TARGET_LINK_LIBRARIES(C A) TARGET_LINK_LIBRARIES(D A) should do the job for A, and TARGET_LINK_LIBRARIES(B C) TARGET_LINK_LIBRARIES(C B) TARGET_LINK_LIBRARIES(D B) does it for B, alternatively, since TARGET_LINK_LIBRARIES() attends to circular dependencies w.r.t. static libraries, see its documentation. Furthermore, I suppose you can't use A and B together due to equally named symbols defined in both of them, in fact the ones called by C. In the last resort, the GNU linker provides options "--start-group" and "--end-group", or the short ones "-(" and "-)", respectively, meant to resolve circular dependencies among static libraries, but I don't know if one can have CMake intersperse these options in the link line or if this would be portable regarding the various supported platforms. Perhaps, if possible, you should consider to reorganize your project in order to avoid circular dependencies at all, e.g.: Take those parts of A and B that C refers to and turn them into separate libraries A0 and B0. This results in A, B and C depend on A0 and/or B0, and the link line for libD.so would be: "cc ... -o libD.so -lA -lC -lA0" or "cc ... -o libD.so -lB -lC -lB0" Thus, the circular dependencies are gone. Regards, Michael ___ 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://www.cmake.org/mailman/listinfo/cmake
[CMake] Reverse dependencies (Unix Makefiles)
Hi, I have two targets, call them A and B. They both link with a third, static library called C. C attempts to invoke a function which is defined by however links with C, i.e. either A or B. This is not a problem as long as A and B are executables or shared libraries, but if A or B is a static library which in turn is linked into a shared object or executable (call it D), then the command becomes something like cc ... -o libD.so -lA -lC since the method C calls in A is unknown by the linker when A is processed, it is discarded. Instead, I would need the command line to look like this: cc ... -o libD.so -lA -lC -lA but how can I do this without explicitly causing A to depend on C? -- /Jesper ___ 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://www.cmake.org/mailman/listinfo/cmake