One of my XS-based modules requires some feature flags to be set up before it can be compiled. I seek advice on how best to do this under Module::Build.
The module is Time::UTC::Now, and it needs to know about the existence of certain time-related library functions and the presence of certain members of related structs. These are tested for by attempting to compile and link short test programs. (The test programs are never run; success of linking is what determines the feature flag setting.) The test results are supplied to the XS code in the form of preprocessor definitions that are added to the compiler command line. In my attempt at this so far, I've overridded M::B::compile_c (in a subclass), so that it'll run the tests, add the feature definitions to its arguments, and pass the modified arguments on to the original compile_c method. I also have it cache the test results in a file, and this file along with all the test files are subject to cleanup. This bit works fine. The compilation part of the tests also goes well: I call $self->compile_c on the test file, with an extra flag to bypass the feature testing. I have a problem with the linking part of the test. I can't use M::B::link_c, because that insists on putting the result under blib, which I don't want. I don's see a way to override where the resulting library goes. Instead I'm cheating a bit: I call $self->_cbuilder to get the ExtUtils::CBuilder object, then call ->link_executable on that. (Generating an executable is simpler than generating a library, anyway.) This works, but obviously I'm relying on an internal method of Module::Build. I also have a problem with the dependency of the main object file on the feature definition cache file. M::B generally manages dependencies by having the code to build a file check whether it's up to date, and not generate it if it is. By this means I have the feature definition cache file depend on the feature test code (which is in a separate file). But with the object file the up-to-date-ness is tested by M::B::compile_c, which doesn't know about any dependency other than the source file. There's no way to tell compile_c that the compilation is influenced by, say, a header file, or (in this case) the cache file that is read by the overridden part of compile_c. I have temporarily resolved this by having the overridden compile_c delete the object file if it detects that it is out-of-date with respect to the cache file. However, to find the name of the object file I had to cheat again, by calling $self->_cbuilder->object_file. Is there a cleaner way to incorporate these tests into the build process? Have I missed some bits of M::B that I could override to greater effect? My development version of the module in question is at <http://www.fysh.org/~zefram/tmp/Time-UTC-Now-0.006001.tar.gz>. -zefram