Apparently the %import directive is meant to be used with .i files rather than .h files. impEM isn't doing the right thing  (nor was mine). I haven't yet checked if that solves my problems linking multiple swig libs as I have only had my mac which doesn't exhibit the problems.

In addition, we are not properly sharing the swig runtime info between modules. Apparently we need to add " -DSWIG_TYPE_TABLE=IMP" to each compilation of a _wrap.cc so that the information is properly shared. Unfortunately, this includes EMbed (although EMbed doesn't have to actually see any of the IMP code as the IMP there is just used as a string). 

I would also propose changing IMP_exceptions.i as follows in order to allow other libraries to reuse the exception handling function by %including IMP_exceptions.i rather than redefine a new one:
IMP_exceptions.i should contain:
%{
  void IMP_swig_handle_exception(void);
%}

%exception {
  try {
    $action
  } catch (...) {
    IMP_swig_handle_exception();
    /* This should be unnecessary, since handle_imp_exception cannot return;
       here just to quell lots of warnings about the 'result' variable not
       being initialized. */
    SWIG_fail;
  }
}


and putting the following in IMP.i to define the function uniquely.

%{
  /* Code to convert C++ exceptions into scripting language errors. Saves
     having lots of catch statements in every single wrapper. */
  void IMP_swig_handle_exception(void)
  {
    try {
      throw;
    } catch (std::out_of_range &e) {
      SWIG_exception(SWIG_IndexError, e.what());
    } catch (IMP::IndexException &e) {
      SWIG_exception(SWIG_IndexError, e.what());
    } catch (IMP::InvalidStateException &e) {
      SWIG_exception(SWIG_ValueError, e.what());
    } catch (IMP::ErrorException &e) {
      SWIG_exception(SWIG_RuntimeError, e.what());
    }   
  /* SWIG_exception contains "goto fail" so make sure the label is defined */
  fail:
    return;
  }
%}

Here is a patch for everything in IMP (not for EMbed).