From: Wheeler, F. (Research) <wh...@cr...> - 2002-08-08 21:26:33
|
Amitha, It seems like a month ago, with CMake 1.4 beta, we got all the vgui examples compiling in Cygwin with glut. I think we just did TARGET_LINK_LIBRARIES(vgui vgui_glut) and TARGET_LINK_LIBRARIES(vgui_glut vgui) and it somehow all worked. Does CMake now do something differently in the face of a circular dependency? One of the execs that does not successfully link right now in Cygwin is raw-glut1. This is the link line, notice no -lvgui_glut. % make raw-glut1 c++ -Wall -g -O2 raw-glut1.o -L/home/wsroot/work_vxl/vxl_bld_cyg/lib -L/usr/lib/w32api -lvgui -losl -lglut32 -lvgui_base -lvul -lvpl -lQv -lopengl32 -lglut32 -lglu32 -lvnl_algo -lvnl -lnetlib -lvil -ltiff -lpng -lzlib -ljpeg -lvgl -lvbl -lvcl -lm -o raw-glut1 I could get raw-glut1 to link (and then run!) using ... % c++ -Wall -g -O2 raw-glut1.o -L/home/wsroot/work_vxl/vxl_bld_cyg/lib -L/usr/lib/w32api -lvgui -losl -lglut32 -lvgui_base -lvul -lvpl -lQv -lopengl32 -lglut32 -lglu32 -lvnl_algo -lvnl -lnetlib -lvil -ltiff -lpng -lzlib -ljpeg -lvgl -lvbl -lvcl -lm -lvgui -lvgui_base -lvgui_glut -lopengl32 -lglut32 -lglu32 -lvgui_glut -lvgui_base -o raw-glut1 I just kept throwing extra -l options at it until it linked. I could search for a minimal addition, if you think it would be helpful. It looks to me that the dependencies between vgui, vgui_base and vgui_glut are not correct in the cache file. Here is an explanation... CMake knows that I have glut ... % grep vgui_IMPL_GLUT CMakeCache.txt vgui_IMPL_GLUT:INTERNAL=vgui_glut And in vgui/CMakeLists.txt, this stanza should cause vgui to depend on vgui_glut ... IF (vgui_IMPL_GLUT) TARGET_LINK_LIBRARIES(vgui ${vgui_IMPL_GLUT}) ENDIF (vgui_IMPL_GLUT) But in the cache file it seems that vgui does not depend on vgui_glut!! ... % grep vgui_LIB_DEPENDS CMakeCache.txt vgui_LIB_DEPENDS:STATIC=vgui_base; Nor does vgui_base depend on vgui_glut!! ... % grep vgui_base_LIB_DEPENDS CMakeCache.txt vgui_base_LIB_DEPENDS:STATIC=vnl_algo;vil;vgl;vpl;vbl;vul;/usr/lib/w32api/libglut32.a;Qv;/usr/lib/w32 api/libglu32.a;/usr/lib/w32api/libopengl32.a; The fact that the cache thinks that neither vgui nor vgui_base depend on vgui_glut does not seem right to me. -Fred > -----Original Message----- > From: Amitha Perera [mailto:pe...@cs...] > Sent: Thursday, August 08, 2002 12:36 PM > To: vxl...@li... > Subject: [Vxl-maintainers] Cyclic libraries in vxl (vgui) > > > [ If you know of any of the original vgui designers that are not on > this mailing list, please forward this email to them. Thanks. ] > > Summary: > 1) vgui is designed with cyclic dependencies in its libraries. > 2) What should we do about it? > > (This is the cause of the broken Cygwin build on the dashboard.) > > > Detail: > > 1) > > Some of you have probably observed my attempts to get vgui linking > without cyclic dependencies, and functioning correctly in a portable > manner. The vgui design attempts to decouple the conceptual vgui > implementation from the windowing toolkit implementation. This makes > vgui multi-platform because the base vgui, that clients would use, has > no knowledge of any particular windowing toolkit. However, the current > implementation requires that the toolkits register with the base > implementation, which implies that the toolkit depends on the base (at > least, this is so in the current implementation). The toolkits provide > registration functions calling which will effect the registration. The > problem is: how do you cause these functions to be called? A classic > way is to use a global variable: > > int registration_function(); > static int registration_trigger = registration_function(); > > Here, the system must initialize the global variable, which triggers > the registration function. However, this is not a reliable method in > our context, because a compiler is only required to initialize the > variable *before first use*. That means if the variable is never > used during the execution of the client program, it needn't be > initialized. > > In practice, with shared libraries the problem doesn't exist, because > the run-time linker generally initializes all global variables when > the library is linked in. With static libraries, the situation is > different. The compiler will selectively link in object files from the > libraries, provided that the client executable refers (directly or > indirectly) to something in that object file. Now, the client program > does not know about any of the toolkits, so can't refer to the trigger > variable. Same for the base implementation. Thus, the linker will > happily exclude the toolkit implementations from the final executable, > and disater strikes. > > This means there must be some higher level that knows both about the > base implementation and the toolkits, and can serve as a tie. The > issue is: how to ensure that that the client executable refers to > something in this higher level? We want to do this without causing > modification to existing client code. > > > > > 2) > > 2.1) > One solution is to allow the cyclic dependency. Then, the base > implementation can be told about the available toolkits at compile > time, and can call the registration functions. I don't like this > solution, since a key goal of vxl is to avoid cyclic dependencies in > libraries. > > 2.2) > Another solution is to move some function that the client is > guaranteed to call (e.g. vgui::init) into the higher level tie > library. My changes yesterday attempts to do this. Unfortunately, > moving vgui::init implies moving vgui::quit, etc, but the toolkit > implementations call those functions. This causes another cyclic > dependency. > > 2.3) > A final solution is to insert some variable or function into a header > file that is included by the client. (This was the solution in the old > vgui_linker_hack.h.) This solves the problem because the preprocessor > nature of include files mean that the client executable "refers" to > whatever variable is declared in the header. However, if we try to > avoid modification of client code, this "inserting header" must be > something the client is already including. A good candidate is > "vgui.h". But implementing this would imply things like declaring the > vgui struct in the tie library, but implementing it in the base > library. Ugly. > > > Does anyone have any other ideas or solutions? > > My own preference is for 2.3: it is ugly, and may break good > programming practice in this once case, but avoid cyclic library > dependencies. > > Amitha. > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Vxl-maintainers mailing list > Vxl...@li... > https://lists.sourceforge.net/lists/listinfo/vxl-maintainers > |