diff --git a/ghc/compiler/absCSyn/AbsCUtils.lhs b/ghc/compiler/absCSyn/AbsCUtils.lhs
index 07a91bf4335b1781dad294dd0ba4424722c53042..8e4d758545f3e3d90f112287ed81cfda2fab542a 100644
--- a/ghc/compiler/absCSyn/AbsCUtils.lhs
+++ b/ghc/compiler/absCSyn/AbsCUtils.lhs
@@ -29,7 +29,7 @@ import UniqSupply	( uniqFromSupply, uniqsFromSupply, splitUniqSupply,
 			  UniqSupply )
 import CmdLineOpts      ( opt_OutputLanguage, opt_EmitCExternDecls )
 import Maybes		( maybeToBool )
-import PrimOp		( PrimOp(..), CCall(..), CCallTarget(..) )
+import PrimOp		( PrimOp(..), CCall(..), isDynamicTarget )
 import Panic		( panic )
 
 infixr 9 `thenFlt`
@@ -331,16 +331,16 @@ flatAbsC (CSwitch discrim alts deflt)
       = flatAbsC absC	`thenFlt` \ (alt_heres, alt_tops) ->
 	returnFlt ( (tag, alt_heres), alt_tops )
 
-flatAbsC stmt@(COpStmt results (CCallOp ccall) args vol_regs)
+flatAbsC stmt@(COpStmt results (CCallOp ccall@(CCall target is_asm _ _)) args vol_regs)
   | isCandidate && opt_OutputLanguage == Just "C"	-- Urgh
   = returnFlt (stmt, tdef)
+  | otherwise
+  = returnFlt (stmt, AbsCNop)
   where
-    (isCandidate, isDyn) =
-      case ccall of 
-        CCall (DynamicTarget _) _ _ _      -> (True, True)
-	CCall (StaticTarget _) is_asm _ _  -> (opt_EmitCExternDecls && not is_asm, False)
+    isCandidate = is_dynamic || opt_EmitCExternDecls && not is_asm
+    is_dynamic  = isDynamicTarget target
 
-    tdef = CCallTypedef isDyn ccall results args
+    tdef = CCallTypedef is_dynamic ccall results args
 
 flatAbsC stmt@(CSimultaneous abs_c)
   = flatAbsC abs_c		`thenFlt` \ (stmts_here, tops) ->
diff --git a/ghc/compiler/absCSyn/PprAbsC.lhs b/ghc/compiler/absCSyn/PprAbsC.lhs
index f3dd00099fad6bdc77fb1cf6a77c9f09d74022a9..667d1bb8f55c59960a36e4983e649402a5da727d 100644
--- a/ghc/compiler/absCSyn/PprAbsC.lhs
+++ b/ghc/compiler/absCSyn/PprAbsC.lhs
@@ -46,7 +46,7 @@ import Name		( NamedThing(..) )
 import DataCon		( DataCon{-instance NamedThing-}, dataConWrapId )
 import Maybes		( maybeToBool, catMaybes )
 import PrimOp		( primOpNeedsWrapper, pprPrimOp, pprCCallOp, 
-			  PrimOp(..), CCall(..), CCallTarget(..) )
+			  PrimOp(..), CCall(..), CCallTarget(..), isDynamicTarget )
 import PrimRep		( isFloatingRep, PrimRep(..), getPrimRepSize, showPrimRep )
 import SMRep		( pprSMRep )
 import Unique		( pprUnique, Unique{-instance NamedThing-} )
@@ -821,42 +821,30 @@ pprCCall call@(CCall op_str is_asm may_gc cconv) args results vol_regs
 	  [amode]  -> text (showPrimRep (getAmodeRep amode))
 	  _	   -> panic "pprCCall: ccall_res_ty"
 
-    ccall_fun_ty = 
-       ptext SLIT("_ccall_fun_ty") <>
-       case op_str of
-         DynamicTarget u -> ppr u
-	 _     		 -> empty
-
     (declare_local_vars, local_vars, assign_results)
       = ppr_casm_results non_void_results
 
-    (StaticTarget asm_str) = op_str
-    is_dynamic = 
-       case op_str of
-         StaticTarget _  -> False
-	 DynamicTarget _ -> True
-
     casm_str = if is_asm then _UNPK_ asm_str else ccall_str
+    StaticTarget asm_str = op_str	-- Must be static if it's a casm
 
     -- Remainder only used for ccall
 
-    fun_name 
-      | is_dynamic = parens (parens (ccall_fun_ty) <> text "%0")
-      | otherwise  = ptext asm_str
+    fun_name = case op_str of
+		 DynamicTarget u -> parens (parens (ptext SLIT("_ccall_fun_ty") <> ppr u) <> text "%0")
+		 StaticTarget st -> pprCLabelString st
 
     ccall_str = showSDoc
 	(hcat [
 		if null non_void_results
 		  then empty
 		  else text "%r = ",
-		lparen, fun_name, lparen,
+		lparen, parens fun_name, lparen,
 		  hcat (punctuate comma ccall_fun_args),
 		text "));"
 	])
 
-    ccall_fun_args
-     | is_dynamic = tail ccall_args
-     | otherwise  = ccall_args
+    ccall_fun_args | isDynamicTarget op_str = tail ccall_args
+		   | otherwise 		    = ccall_args
 
     ccall_args    = zipWith (\ _ i -> char '%' <> int i) non_void_args [0..]
 
diff --git a/ghc/compiler/deSugar/DsForeign.lhs b/ghc/compiler/deSugar/DsForeign.lhs
index b0d3fb0a049feaffe5e75e046ce47194f80fb7f9..3614d8d69715bbc4d7c5f4a559e5e3a52e8570ad 100644
--- a/ghc/compiler/deSugar/DsForeign.lhs
+++ b/ghc/compiler/deSugar/DsForeign.lhs
@@ -38,7 +38,7 @@ import Type		( unUsgTy, repType,
 			  mkTyVarTy, mkFunTy, splitAppTy, applyTy, funResultTy
 			)
 import PprType		( {- instance Outputable Type -} )
-import PrimOp		( PrimOp(..), CCall(..), CCallTarget(..) )
+import PrimOp		( PrimOp(..), CCall(..), CCallTarget(..), dynamicTarget )
 import Var		( TyVar )
 import TysPrim		( realWorldStatePrimTy, addrPrimTy )
 import TysWiredIn	( unitTy, addrTy, stablePtrTyCon,
@@ -141,14 +141,13 @@ dsFImport fn_id ty may_not_gc ext_name cconv
     mapAndUnzipDs unboxArg (map Var args)	`thenDs` \ (val_args, arg_wrappers) ->
     boxResult io_res_ty				`thenDs` \ (ccall_result_ty, res_wrapper) ->
 
-    (case ext_name of
-       Dynamic       -> getUniqueDs `thenDs` \ u -> 
-			returnDs (DynamicTarget u)
-       ExtName fs _  -> returnDs (StaticTarget fs))	`thenDs` \ lbl ->
-
     getUniqueDs						`thenDs` \ ccall_uniq ->
     getUniqueDs						`thenDs` \ work_uniq ->
     let
+	lbl = case ext_name of
+		Dynamic	     -> dynamicTarget
+	        ExtName fs _ -> StaticTarget fs
+
 	-- Build the worker
 	work_arg_ids  = [v | Var v <- val_args]		-- All guaranteed to be vars
 	worker_ty     = mkForAllTys tvs (mkFunTys (map idType work_arg_ids) ccall_result_ty)
diff --git a/ghc/compiler/prelude/PrimOp.lhs b/ghc/compiler/prelude/PrimOp.lhs
index a55af165de2428bb9e283bf8903d2ffb353bf81f..34d49c78edc3ee5dd0c2006964c4f9c7c2c559c1 100644
--- a/ghc/compiler/prelude/PrimOp.lhs
+++ b/ghc/compiler/prelude/PrimOp.lhs
@@ -19,7 +19,8 @@ module PrimOp (
 
 	pprPrimOp,
 
-	CCall(..), CCallTarget(..), ccallMayGC, ccallIsCasm, pprCCallOp
+	CCall(..), CCallTarget(..), ccallMayGC, ccallIsCasm, pprCCallOp,
+	isDynamicTarget, dynamicTarget, setCCallUnique
     ) where
 
 #include "HsVersions.h"
@@ -2418,13 +2419,34 @@ data CCallTarget
 				--   (unique is used to generate a 'typedef' to cast
 				--    the function pointer if compiling the ccall# down to
 				--    .hc code - can't do this inline for tedious reasons.)
-  deriving( Eq )
+
+instance Eq CCallTarget where
+  (StaticTarget l1) == (StaticTarget l2) = l1 == l2
+  (DynamicTarget _) == (DynamicTarget _) = True	
+	-- Ignore the arbitrary unique; this is important when comparing
+	-- a dynamic ccall read from an interface file A.hi with the
+	-- one constructed from A.hs, when deciding whether the interface
+	-- has changed
+  t1 == t2 = False
 
 ccallMayGC :: CCall -> Bool
 ccallMayGC (CCall _ _ may_gc _) = may_gc
 
 ccallIsCasm :: CCall -> Bool
 ccallIsCasm (CCall _ c_asm _ _) = c_asm
+
+isDynamicTarget (DynamicTarget _) = True
+isDynamicTarget (StaticTarget _)  = False
+
+dynamicTarget :: CCallTarget
+dynamicTarget = DynamicTarget (panic "Unique in DynamicTarget not yet set")
+	-- The unique is really only to do with code generation, so it
+	-- is only set in CoreToStg; before then it's just an error message
+
+setCCallUnique :: CCall -> Unique -> CCall
+setCCallUnique (CCall (DynamicTarget _) is_asm may_gc cconv) uniq
+  = CCall (DynamicTarget uniq) is_asm may_gc cconv
+setCCallUnique ccall uniq = ccall
 \end{code}
 
 \begin{code}
diff --git a/ghc/compiler/stgSyn/CoreToStg.lhs b/ghc/compiler/stgSyn/CoreToStg.lhs
index fc0a8d52c704c8845118f39fde5c9c2bf79b9ad5..44cff7e9450f5eb3aa79e87b4787fd295228c2f2 100644
--- a/ghc/compiler/stgSyn/CoreToStg.lhs
+++ b/ghc/compiler/stgSyn/CoreToStg.lhs
@@ -33,7 +33,7 @@ import Demand		( Demand, isStrict, wwStrict, wwLazy )
 import Name	        ( Name, nameModule, isLocallyDefinedName, setNameUnique )
 import Literal	        ( Literal(..) )
 import VarEnv
-import PrimOp		( PrimOp(..), CCall(..), CCallTarget(..), primOpUsg )
+import PrimOp		( PrimOp(..), setCCallUnique, primOpUsg )
 import Type		( isUnLiftedType, isUnboxedTupleType, Type, splitFunTy_maybe,
                           UsageAnn(..), tyUsg, applyTy, mkUsgTy, repType, seqType,
 			  splitRepFunTys, mkFunTys
@@ -657,11 +657,14 @@ mkStgApp env fn args ty
 	-> saturate fn_alias args ty	$ \ args' ty' ->
 	   returnUs (StgConApp dc args')
 
-      PrimOpId (CCallOp (CCall (DynamicTarget _) a b c))
+      PrimOpId (CCallOp ccall)
 		-- Sigh...make a guaranteed unique name for a dynamic ccall
+		-- Done here, not earlier, because it's a code-gen thing
 	-> saturate fn_alias args ty	$ \ args' ty' ->
-	   getUniqueUs   		`thenUs` \ u ->
-           returnUs (StgPrimApp (CCallOp (CCall (DynamicTarget u) a b c)) args' ty')
+           returnUs (StgPrimApp (CCallOp ccall') args' ty')
+	where
+	   ccall' = setCCallUnique ccall (idUnique fn)	
+			-- The particular unique doesn't matter
 
       PrimOpId op 
 	-> saturate fn_alias args ty	$ \ args' ty' ->