Commit 8449f6e5 authored by simonmar's avatar simonmar
Browse files

[project @ 2003-10-21 11:42:30 by simonmar]

Change the filename policies (again).  Now the interface file and
object file always follow the source file unless the -odir or -hidir
options are specified.
parent 629f0224
......@@ -230,16 +230,17 @@ mkPackageModLocation hisuf mod_name path basename _ext = do
return result
hiOnlyModLocation path basename hisuf
= do { obj_fn <- mkObjPath path basename ;
return (ModLocation{ ml_hspp_file = Nothing,
= do let full_basename = path++'/':basename
obj_fn <- mkObjPath full_basename basename
return ModLocation{ ml_hspp_file = Nothing,
ml_hs_file = Nothing,
ml_hi_file = path ++ '/':basename ++ '.':hisuf,
ml_hi_file = full_basename ++ '.':hisuf,
-- Remove the .hi-boot suffix from
-- hi_file, if it had one. We always
-- want the name of the real .hi file
-- in the ml_hi_file field.
ml_obj_file = obj_fn
})}
}
-- -----------------------------------------------------------------------------
-- Constructing a home module location
......@@ -275,59 +276,57 @@ hiOnlyModLocation path basename hisuf
-- The filename extension of the source file (usually "hs" or "lhs").
mkHomeModLocation mod_name src_filename = do
let mod_basename = dots_to_slashes (moduleNameUserString mod_name)
(basename,extension) = splitFilename src_filename
case maybePrefixMatch (reverse mod_basename) (reverse basename) of
Just "" ->
mkHomeModLocationSearched mod_name "." mod_basename extension
Just rest@(r:_) | isPathSeparator r -> do
let path = reverse (dropWhile (=='/') rest)
mkHomeModLocationSearched mod_name path mod_basename extension
_ -> do
-- hPutStrLn stderr ("Warning: " ++ src_filename ++
-- ": filename and module name do not match")
let (dir,basename,ext) = splitFilename3 src_filename
mkHomeModLocationSearched mod_name dir basename ext
mkHomeModLocationSearched mod_name path src_basename ext = do
hisuf <- readIORef v_Hi_suf
hidir <- readIORef v_Hi_dir
let mod_basename = dots_to_slashes (moduleNameUserString mod_name)
obj_fn <- mkObjPath path mod_basename
let (basename,extension) = splitFilename src_filename
mkHomeModLocation' mod_name basename extension
let -- hi filename, always follows the module name
hi_path | Just d <- hidir = d
| otherwise = path
mkHomeModLocationSearched mod_name path basename ext =
mkHomeModLocation' mod_name (path ++ '/':basename) ext
hi_fn = hi_path ++ '/':mod_basename ++ '.':hisuf
mkHomeModLocation' mod_name src_basename ext = do
let mod_basename = dots_to_slashes (moduleNameUserString mod_name)
-- source filename
source_fn = path ++ '/':src_basename ++ '.':ext
obj_fn <- mkObjPath src_basename mod_basename
hi_fn <- mkHiPath src_basename mod_basename
result = ( mkHomeModule mod_name,
ModLocation{ ml_hspp_file = Nothing,
ml_hs_file = Just source_fn,
ml_hi_file = hi_fn,
ml_obj_file = obj_fn,
let result = ( mkHomeModule mod_name,
ModLocation{ ml_hspp_file = Nothing,
ml_hs_file = Just (src_basename ++ '.':ext),
ml_hi_file = hi_fn,
ml_obj_file = obj_fn
})
addToFinderCache mod_name result
return result
mkObjPath :: FilePath -> String -> IO FilePath
-- Construct the filename of a .o file.
-- Does *not* check whether the .o file exists
mkObjPath path basename
-- | Constructs the filename of a .o file for a given source file.
-- Does /not/ check whether the .o file exists
mkObjPath
:: FilePath -- the filename of the source file, minus the extension
-> String -- the module name with dots replaced by slashes
-> IO FilePath
mkObjPath basename mod_basename
= do odir <- readIORef v_Output_dir
osuf <- readIORef v_Object_suf
let obj_path | Just d <- odir = d
| otherwise = path
let obj_basename | Just dir <- odir = dir ++ '/':mod_basename
| otherwise = basename
return (obj_basename ++ '.':osuf)
-- | Constructs the filename of a .hi file for a given source file.
-- Does /not/ check whether the .hi file exists
mkHiPath
:: FilePath -- the filename of the source file, minus the extension
-> String -- the module name with dots replaced by slashes
-> IO FilePath
mkHiPath basename mod_basename
= do hidir <- readIORef v_Hi_dir
hisuf <- readIORef v_Hi_suf
let hi_basename | Just dir <- hidir = dir ++ '/':mod_basename
| otherwise = basename
return (obj_path ++ '/':basename ++ '.':osuf)
return (hi_basename ++ '.':hisuf)
-- -----------------------------------------------------------------------------
-- findLinkable isn't related to the other stuff in here,
......
......@@ -79,121 +79,61 @@
<para>Every module has a <emphasis>module name</emphasis>
defined in its source code (<literal>module A.B.C where
...</literal>). Unless overridden with the
<literal>-o</literal> and <literal>-ohi</literal> flags
respectively, GHC always puts the object file for module
<literal>A.B.C</literal> in
<replaceable>odir</replaceable><literal>/A/B/C.</literal><replaceable>osuf</replaceable>,
and the interface file in the file
<replaceable>hidir</replaceable><literal>/A/B/C.</literal><replaceable>hisuf</replaceable>,
where <replaceable>hidir</replaceable>,
<replaceable>hisuf</replaceable>,
<replaceable>odir</replaceable>, and
<replaceable>osuf</replaceable>, defined as follows:
...</literal>).</para>
<variablelist>
<varlistentry>
<term><replaceable>hidir</replaceable></term>
<listitem>
<para>is the value of the <option>-hidir</option> option if
one was given (<xref linkend="options-output">), or
<replaceable>root-path</replaceable> otherwise.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>hisuf</replaceable></term>
<listitem>
<para>is the value of the <option>-hisuf</option> option if
one was given (<xref linkend="options-output">), or <literal>hi</literal>
otherwise.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>odir</replaceable></term>
<listitem>
<para>is the value of the <option>-odir</option> option if
one was given (<xref linkend="options-output">), or
<replaceable>root-path</replaceable> otherwise.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>osuf</replaceable></term>
<listitem>
<para>is the value of the <option>-osuf</option> option if
one was given (<xref linkend="options-output">), or <literal>o</literal>
otherwise (<literal>obj</literal> on Windows).</para>
</listitem>
</varlistentry>
</variablelist>
The <replaceable>root-path</replaceable>, used in the above definitions, is derived from the
location of the source file, <replaceable>source-filename</replaceable>, as follows:
<para>The name of the object file generated by GHC is derived
according to the following rules, where
<replaceable>osuf</replaceable> is the object-file suffix (this
can be changed with the <option>-osuf</option> option).</para>
<variablelist>
<varlistentry>
<term>Rule 1</term>
<listitem>
<para>GHC matches <replaceable>source-filename</replaceable> against the pattern:
<screen><replaceable>root-path</replaceable>/<literal>A/B/C.</literal><replaceable>extension</replaceable></screen>
where:
<itemizedlist>
<listitem>
<para>If there is no <option>-odir</option> option (the
default), then the object filename is derived from the
source filename by replacing the suffix with
<replaceable>osuf</replaceable>.</para>
</listitem>
<listitem>
<para>If
<option>-odir</option>&nbsp;<replaceable>dir</replaceable>
has been specified, then the object filename is
<replaceable>dir</replaceable>/<replaceable>mod</replaceable>.<replaceable>osuf</replaceable>,
where <replaceable>mod</replaceable> is the module name with
dots replaced by slashes.</para>
</listitem>
</itemizedlist>
<variablelist>
<varlistentry>
<term><replaceable>extension</replaceable></term>
<listitem>
<para>is the source file extension (usually
<literal>.hs</literal> or <literal>.lhs</literal>).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>root-path</replaceable></term>
<listitem>
<para>is what is left after <literal>A/B/C.</literal><replaceable>extension</replaceable>
has been stripped off the end of <replaceable>source-file</replaceable>.</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Rule 2</term>
<listitem>
<para>If <replaceable>source-filename</replaceable> does not match the pattern
above (presumably because it doesn't finish with <literal>A/B/C.hs</literal>
or <literal>A/B/C.lhs</literal>)
then <replaceable>root-path</replaceable> becomes the
whole of the directory portion of the filename. </para>
</listitem>
</varlistentry>
</variablelist>
<para>The name of the interface file is derived using the same
rules, except that the suffix is
<replaceable>hisuf</replaceable> (<literal>.hi</literal> by
default) instead of <replaceable>osuf</replaceable>, and the
relevant options are <option>-hidir</option> and
<option>-hisuf</option> instead of <option>-odir</option> and
<option>-osuf</option> respectively.</para>
For example, if GHC compiles the module
<para>For example, if GHC compiles the module
<literal>A.B.C</literal> in the file
<filename>src/A/B/C.hs</filename>, with no <literal>-odir</literal> or <literal>-hidir</literal> flags,
the interface file will be put in <literal>src/A/B/C.hi</literal> and the object file in
<literal>src/A/B/C.o</literal> (using Rule 1).
If the same module <literal>A.B.C</literal> was in file
<filename>src/ABC.hs</filename>,
the interface file will still be put in <literal>src/A/B/C.hi</literal> and the object file in
<literal>src/A/B/C.o</literal> (using Rule 2).
</para>
<para>A common use for Rule 2 is to have many modules all called <literal>Main</literal> held in
files <literal>Test1.hs</literal> <literal>Test2.hs</literal>, etc. Beware, though: when compiling
(say) <literal>Test2.hs</literal>, GHC will consult <literal>Main.hi</literal> for version information
from the last recompilation. Currently (a bug, really) GHC is not clever enough to spot that the source file has changed,
and so there is a danger that the recompilation checker will declare that no recompilation is needed when in fact it is.
Solution: delete the interface file first.
</para>
<para>Notice that (unless overriden with <option>-o</option> or <option>-ohi</option>) the filenames
of the object and interface files are always based on the module name. The reason for this is so that
GHC can find the interface file for module <literal>A.B.C</literal> when compiling the declaration
"<literal>import A.B.C</literal>".
</para>
<filename>src/A/B/C.hs</filename>, with no
<literal>-odir</literal> or <literal>-hidir</literal> flags, the
interface file will be put in <literal>src/A/B/C.hi</literal>
and the object file in <literal>src/A/B/C.o</literal>.</para>
<para>Note that it is reasonable to have a module
<literal>Main</literal> in a file named
<filename>foo.hs</filename>, but this only works because GHC
never needs to search for the interface for module
<literal>Main</literal> (because it is never imported). It is
therefore possible to have several <literal>Main</literal>
modules in separate source files in the same directory, and GHC
will not get confused. For modules other than
<literal>Main</literal>, it is strongly recommended that you
name the source file after the module name, replacing dots with
slashes in hierarchical module names.</para>
<para>In batch compilation mode, the name of the object file can
also be overriden using the <option>-o</option> option, and the
name of the interface file can be specified directly using the
<option>-ohi</option> option.</para>
</sect2>
<sect2 id="search-path">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment