<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def makefile(identifier, dependencies, makepath, compileid, precompile=False, inclfortpy=True, parser=None, executable=True, extralinks=None, inclfpyaux=False, makefpyaux=False, verbose=False):
 """Generates a makefile to create the unit testing executable for the specified test identifier. :arg identifier: the id of the test/library that this makefile should be made for. :arg dependencies: a list of the module names that need to be included in the compilation. :arg makepath: the path to the file to save the Makefile in. :arg compileid: the 'module.executable' that this Makefile is being produced for. :arg precompile: when True, the precompiler flags will be added to the makefile. :arg inclfortpy: when True, the fortpy module will be added first to the list of modules to compile for the executable/library. :arg parser: if the module file names are different from the module names, specify a code parser to use for converting one to the other. :arg executable: when true and executable is compiled for rule 'all', else the library is the default and the executable is set as a different rule for 'identifier'.x. :arg extralinks: a list of additional libraries to link in with the explicitly compiled f90 files. These aren't checked at all, just added to the linklist. :arg verbose: when True, the full compilation header will be printed with flags and module information; otherwise it won't. """

    lines = []

    #Append the general variables
    lines.append("EXENAME\t\t= {}.x".format(identifier))
    lines.append("SHELL\t\t= /bin/bash")
    lines.append("UNAME\t\t= $(shell uname)")
    lines.append("HOSTNAME\t= $(shell hostname)")
    lines.append("LOG\t\t= compile.{}.log".format(identifier if identifier is not None else "default"))
    lines.append("")

    #Now the standard entries for ifort. We will just have the ifort include
    #file so that the MPI and other options can be tested to.
    lines.append(_make_compiler_include(precompile, extralinks))
    lines.append(".SILENT:")
    lines.append("")
    
    #Append all the dependent modules to the makefile
    lines.append("LIBMODULESF90\t= \\")

    for modk in dependencies:
        if modk not in ["fortpy", "fpy_auxiliary", identifier]:
            if parser is not None:
                lines.append("\t\t{} \\".format(_get_mapping(parser, modk)))
            else:
                lines.append("\t\t{} \\".format(modk))
    if makefpyaux:
        lines.append("\t\tfpy_auxiliary.f90 \\")
    lines.append("")
    
    lines.append("MAINF90\t\t= {}.f90".format(identifier))
    lines.append("SRCF90\t\t= $(LIBMODULESF90) $(MAINF90)")
    lines.append("OBJSF90\t\t= $(SRCF90:.f90=.o)")
    lines.append("SLIBF90\t\t= $(LIBMODULESF90:.f90=.o)")
    lines.append("")

    #Add explicitly defined libraries that should be included when linking
    #the unit testing executable.
    linklibs = True
    _add_explicit_includes(lines, dependencies, extralinks)
    if inclfortpy or inclfpyaux:
        import sys
        if len(sys.modules["config"].includes) == 0:
            lines.append("LIBS\t\t= \\")

        if inclfortpy:
            lines.append("\t\tfortpy.o \\")
        if inclfpyaux:
            lines.append("\t\tfpy_aux.so \\")

    lines.append("")

    #We need to add the error handling commands to make debugging compiling easier.
    lines.append(_make_error())
    lines.append("")

    main = "$(EXENAME)" if executable == True else "{}.{}".format(identifier, executable)
    lines.append("all:	info {}".format(main))
    lines.append(_make_info(compileid, verbose))
    lines.append(_make_exe(linklibs, identifier, verbose))

    from os import path
    makedir, makef = path.split(makepath)
    lines[-1] += "	make -f '{}'".format(makef)

    with open(makepath, 'w') as f:
        f.writelines("\n".join(lines))