July 19, 2010Linking problem with custom associative arrays
I'm working on a rapid webdev thing for D, using my existing cgi library, which has been working excellently in production for a few months now. I hit a weird problem linking it though: ===== dmd -of/var/www/cgi-bin/test test.d program/djs/proxy/cgi.d program/djs/dom.d program/lib/arsd/web.d program/lib/arsd/mysql.d -L-lmysqlclient /var/www/cgi-bin/test.o(.text._D6object31__T16AssociativeArrayTAyaTAAyaZ16AssociativeArray6rehashMFNdZHAyaAAya+0x32): In function `_D6object31__T16AssociativeArrayTAyaTAAyaZ16AssociativeArray6rehashMFNdZHAyaAAya': : undefined reference to `_D17TypeInfo_HAyaAAya6__initZ' /var/www/cgi-bin/test.o(.text._D6object55__T16AssociativeArrayTAyaTS4arsd3cgi3Cgi12UploadedFileZ16AssociativeArray6rehashMFNdZHAyaS4arsd3cgi3Cgi12UploadedFile+0x32): In function `_D6object55__T16AssociativeArrayTAyaTS4arsd3cgi3Cgi12UploadedFileZ16AssociativeArray6rehashMFNdZHAyaS4arsd3cgi3Cgi12UploadedFile': : undefined reference to `_D41TypeInfo_HAyaS4arsd3cgi3Cgi12UploadedFile6__initZ' /var/www/cgi-bin/test.o(.text._D6object56__T16AssociativeArrayTAyaTyS4arsd3cgi3Cgi12UploadedFileZ16AssociativeArray6rehashMFNdZHAyayS4arsd3cgi3Cgi12UploadedFile+0x32): In function `_D6object56__T16AssociativeArrayTAyaTyS4arsd3cgi3Cgi12UploadedFileZ16AssociativeArray6rehashMFNdZHAyayS4arsd3cgi3Cgi12UploadedFile': : undefined reference to `_D42TypeInfo_HAyayS4arsd3cgi3Cgi12UploadedFile6__initZ' ===== Lots of link error spam there, all related to associative array functions in my cgi module - the very same module that compiles and links without error on dozens of other, larger, programs I've used it in. The AA it is complaining about is a UploadedFile[string], where UploadedFile is a struct (nested in the CGI class). Figuring that the actual functions weren't instantiated for the associative array template for my custom struct, I came up with a simple fix: Add this to my dmd command line: d/dmd2/src/druntime/src/object_.d -Id/dmd2/src/druntime/src/ so it can pull the source for object.d out of druntime instead of depending on just the .lib file. That way, the compiler will instantiate the needed template and stick it into my own object file, so it all links correctly. This workaround works for me, but I'm curious: what would be a better solution to the problem? I figure it hits the root of templates: they are instantiated on demand, and you can't do that for custom types in a pre-compiled library. Would it be good for dmd to implicitly add object.d to its source file list? As more and more functionality is moved to library templates, this is bound to come up for more people. Worst case, we could mention in a D FAQ that this command addition is sometimes needed to link programs, but I'd like something more automatic if it is possible without big tradeoffs.