Code Search for Developers
 
 
  

makefile.py from The Nebula Device at Krugle


Show makefile.py syntax highlighted

#--------------------------------------------------------------------------
# Makefile generator for nebula2
#
# (C) 2005 James Urquhart,
# derived from the example scripts (c) 2005 Vadim Macagon.
#
# Contents are licensed under the Nebula license.
#--------------------------------------------------------------------------

import os, string

#--------------------------------------------------------------------------
#   Description of system:
#   One main Makefile is generated, which contains references to the base targets -
#   the "workspaces" of nebula.
#   Each workspace is generated in a seperate <workspace>.mak file, which contains
#   all the targets required to build every project in the workspace.

#--------------------------------------------------------------------------
class makefile:

    #--------------------------------------------------------------------------
    def __init__(self, buildSys):
        self.buildSys = buildSys
        self.description = 'Makefile ' \
                           'Generates Win, Mac, and Linux compatible makefiles'
        self.incDirStr = ''
        self.libDirStr = ''
        self.workspacePath = ''

    #--------------------------------------------------------------------------
    def HasSettings(self):
        return False

    #--------------------------------------------------------------------------
    # Gets basenames of all module sources
    def getModuleSources(self, module):
        retSources = ""
        for source in module.resolvedFiles:
            retSources += "$(N_INTERDIR)%s$(OBJ) " % string.join(string.split(os.path.split(source)[-1], '.')[0:-1])
        return retSources

    #--------------------------------------------------------------------------
    # Entrypoint
    def Generate(self, workspaceNames):
        defaultLocation = os.path.join('build', 'makefile')
        releaseObjLocation = os.path.join('build', 'makefile', 'inter', 'linux')
        debugObjLocation = os.path.join('build', 'makefile', 'inter', 'linuxd')
        try:
            os.makedirs(releaseObjLocation)
        except OSError:
            pass # in case the dir already exists
        try:
            os.makedirs(debugObjLocation)
        except OSError:
            pass # in case the dir already exists

        progressVal = 0
        self.buildSys.CreateProgressDialog('Generating Makefiles', '',
                                           len(workspaceNames))

        try:
            makeFile = file(os.path.join(defaultLocation, 'Makefile'), "w")

            makeFile.write("# Makefile for nebula\n")
            makeFile.write("include ../../buildsys3/config.mak\n\n")

            for workspaceName in workspaceNames:
                workspace = self.buildSys.workspaces[workspaceName]

                # calculate these once for the workspace
                self.workspacePath = workspace.GetWorkspacePath(defaultLocation)
                self.incDirStr = workspace.GetIncSearchDirsString(defaultLocation)
                self.libDirStr = workspace.GetLibSearchDirsString('win32_vc_i386',
                                                                  defaultLocation)

                # make sure the workspace/projects directory exists
                absPath = os.path.join(self.buildSys.homeDir, self.workspacePath)
                if not os.path.exists(absPath):
                    os.makedirs(absPath)

                self.buildSys.UpdateProgressDialog(progressVal,
                    'Generating %s...' % workspaceName)
                if self.buildSys.ProgressDialogCancelled():
                    break

                # spit out the target
                makeFile.write("%s: \n" % workspaceName)
                makeFile.write("\t@$(MAKE) -f ./%s.mak EXTRA_CFLAGS=\"" % workspaceName)
                for include in string.split(self.incDirStr, ';'):
                    makeFile.write("$(IPATH_OPT)%s " % include)
                for lib in string.split(self.libDirStr, ';'):
                    makeFile.write("$(LPATH_OPT)%s " % lib)
                makeFile.write("\"\n\n")

                # spit out the files
                self.generateWorkspace(workspace)

                progressVal += 1

            # generic targets
            makeFile.write("all: ")
            for workspaceName in workspaceNames:
                makeFile.write("%s " % workspaceName)
            makeFile.write("\n\n")

            # spring clean
            makeFile.write("clean: \n")
            makeFile.write("\t$(RM) $(N_TARGETDIR)*\n")
            makeFile.write("\t$(RM) $(N_INTERDIR)*\n")

            makeFile.write("default: all\n")

            # none of these are real
            makeFile.write(".PHONY: all ")
            for workspaceName in workspaceNames:
                makeFile.write("%s " % workspaceName)
            makeFile.write("\n\n")

            makeFile.close()
        except:
            self.buildSys.logger.exception('Exception in makefile.Generate()')

        self.buildSys.DestroyProgressDialog()

        summaryDetails = { 'numOfWorkspacesBuilt' : progressVal,
                           'totalNumOfWorkspaces' : len(workspaceNames) }
        self.buildSys.DisplaySummaryDialog(summaryDetails)

    #--------------------------------------------------------------------------
    # Private Stuff
    #--------------------------------------------------------------------------

    #--------------------------------------------------------------------------
    # Writes each module section
    def writeModule(self, module, makeFile):
        safeModName = module.GetFullNameNoColons()
        more_syms = "$(SYM_OPT)N_INIT=n_init_%s $(SYM_OPT)N_NEW=n_new_%s $(SYM_OPT)N_INITCMDS=n_initcmds_%s" % (safeModName, safeModName, safeModName)

        if module.modType == "c":
            makeFile.write("DO_COMPILE_%s = $(CC) $(NOLINK_OPT) $(CFLAGS) %s $< $(OBJ_OPT) $@\n" % (safeModName, more_syms))
        elif module.modType == "cpp":
            makeFile.write("DO_COMPILE_%s = $(CXX) $(NOLINK_OPT) $(CXXFLAGS) %s $< $(OBJ_OPT) $@\n" % (safeModName, more_syms))
        else:
            makeFile.write("DO_COMPILE_%s = @echo ""Warning: Dummy Target for %s!""\n" % safeModName)

        for fileName in module.resolvedFiles:
            base_name = string.join(string.split(os.path.split(fileName)[-1], '.')[0:-1])
            relPath = self.buildSys.FindRelPath(self.workspacePath, fileName)
            makeFile.write("$(N_INTERDIR)%s$(OBJ): %s\n\t$(DO_COMPILE_%s)\n" % (base_name, relPath, safeModName))
        makeFile.write("\n")

    #--------------------------------------------------------------------------
    # Writes each target section
    def writeTarget(self, target, makeFile):
        print "Generating target line for %s" % target.name

        makeFile.write("\n# Target %s\n" % target.name)
        # handle platform specific targets (unless non-specified)
        needsEnd = False
        if not target.SupportsPlatform("all"):
            if target.SupportsPlatform("win32"):
                makeFile.write("ifeq ($(N_PLATFORM),__WIN32__)\n")
            elif target.SupportsPlatform("linux"):
                makeFile.write("ifeq ($(N_PLATFORM),__LINUX__)\n")
            elif target.SupportsPlatform("macosx"):
                makeFile.write("ifeq ($(N_PLATFORM),__MACOSX__)\n")
            needsEnd = True

        targetType = target.type
        filesWin32  = ""
        filesLinux  = ""
        filesMacOSX = ""

        # Add modules we need to the files line
        for moduleName in target.modules:
            module = self.buildSys.modules[moduleName]
            sources = self.getModuleSources(module)
            # Module has sources, onto the platform...
            if not module.SupportsPlatform("all"):
                if module.SupportsPlatform("win32"):
                    filesWin32  += sources
                elif module.SupportsPlatform("linux"):
                    filesLinux  += sources
                elif module.SupportsPlatform("macosx"):
                    filesMacOSX += sources
                else:
                    print "Module %s not found on any regular platform! RUN!!!" % module.name
            else:
                filesWin32  += " %s" % sources
                filesLinux  += " %s" % sources
                filesMacOSX += " %s" % sources

        # handle resource files
        resourceFiles = ""
        if targetType == "exe" or targetType == "dll":
            makeFile.write("# Resource Files\n")
            # add standard nebula resource (exe or dll)
            relPath = os.path.join(self.buildSys.FindRelPath(self.workspacePath,
                                                os.path.join('build',
                                                             'pkg')), "res_%s.rc" % target.name)
            resourceFiles += "./pkg/res_%s.res " % relPath

            # add any custom resource files
            if target.win32Resource != "":
                resourceFiles += self.buildSys.FindRelPath(self.workspacePath,
                                                           target.win32Resource) + " "

            makeFile.write("\n")

        # Get a list of libs to plonk on command
        libsWin32  = ""
        libsLinux  = ""
        libsMacOSX = ""
        #for lib in target.libsWin32DebugAll:
        for lib in target.libsWin32ReleaseAll:
            libsWin32  += "$(LIB_OPT)%s$(LIB_OPT_POST) " % lib
        for lib in target.libsLinux:
            libsLinux  += "$(LIB_OPT)%s$(LIB_OPT_POST) " % lib
        for lib in target.libsMacOSX:
            libsMacOSX += "$(LIB_OPT)%s$(LIB_OPT_POST) " % lib

        # generate list of target dependencies for that target
        depsWin32 = ""
        depsLinux = ""
        depsMacOSX = ""
        for dep in target.depends:
            if not self.buildSys.targets[dep].SupportsPlatform("all"):
                if self.buildSys.targets[dep].SupportsPlatform("win32"):
                    depsWin32  += " %s" % dep
                elif self.buildSys.targets[dep].SupportsPlatform("linux"):
                    depsLinux  += " %s" % dep
                elif self.buildsys.targets[dep].SupportsPlatform("macosx"):
                    depsMacOSX += " %s" % dep
                else:
                    print "Dependancy %s not found on any regular platform! RUN!!!"
            else:
                depsWin32  += " %s" % dep
                depsLinux  += " %s" % dep
                depsMacOSX += " %s" % dep

        makeFile.write("# Linking targets\n")

        # compile target itself
        # TODO: fix erroneous "only __VC__ must be win32" assumption
        if targetType == "dll":
            # A Dynamic Lazy Lounger (or Shared Library)
            # Add on special .def if required
            if target.modDefFile != "":
                modDefFileName = self.buildSys.FindRelPath(self.workspacePath,
                                                           target.modDefFile)
                # NOTE: seems like "dlltool" is requred to generate the linking lib,
                # which def's are used with. Need to find a better way of handling this...
                #gccDef = " %s" % modDefFileName
                vccDef = "/DEF:%s" % modDefFileName
            else:
                vccDef = ""
                #gccDef = ""

            # Generate target lines
            endTarget = "$(N_TARGETDIR)$(DLL_PRE)%s$(DLL_POST)" % target.name
            makeFile.write("ifeq ($(N_COMPILER),__VC__)\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsWin32, endTarget))
            makeFile.write("%s : %s %s\n" % (endTarget, filesWin32, resourceFiles))
            makeFile.write("\t$(LD) $(LFLAGS) $^ %s /OUT:$@ $(LIBDIR) $(LIBS) %s /DLL\n" % (vccDef, libsWin32))
            makeFile.write("else\n")
            makeFile.write("ifeq ($(N_PLATFORM),__MACOSX__)\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsMacOSX, endTarget))
            makeFile.write("%s : %s\n" % (endTarget, filesMacOSX))
            makeFile.write("\t$(CXX) -dynamiclib -compatibility_version 0.1 -current_version 0.1.0 $^ -o $@ $(CFLAGS) $(LIBDIR) $(LIBS) %s\n" % (libsMacOSX))
            makeFile.write("else\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsLinux, endTarget))
            makeFile.write("%s : %s\n" % (endTarget, filesLinux))
            makeFile.write("\t$(CXX) $^ -o $@ $(CFLAGS) $(LIBDIR) $(LIBS) %s -shared\n" % (libsLinux))
            makeFile.write("endif\n")
            makeFile.write("endif\n")
        elif targetType == "exe":
            # our trusty executable
            endTarget = "$(N_TARGETDIR)%s$(EXE)" % target.name
            makeFile.write("ifeq ($(N_COMPILER),__VC__)\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsWin32, endTarget))
            makeFile.write("%s : %s %s\n" % (endTarget, filesWin32, resourceFiles))
            makeFile.write("\t$(LD) $(LFLAGS) $^ /OUT:$@ $(LIBDIR) $(LIBS) %s\n" % libsWin32)
            makeFile.write("else\n")
            makeFile.write("ifeq ($(N_PLATFORM),__MACOSX__)\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsMacOSX, endTarget))
            makeFile.write("%s : %s\n" % (endTarget, filesMacOSX))
            makeFile.write("\t$(CXX) $^ -o $@ $(LIBDIR) $(LIBS) %s -flat_namespace\n" % libsMacOSX)
            makeFile.write("else\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsLinux, endTarget))
            makeFile.write("%s : %s\n" % (endTarget, filesLinux))

            # write depsLinux, which appears to be a list of nebula libs
            # as libraries to be linked. write it twice, for circular deps.
            # we could use a topological sort instead, but this is easier.
            depsAsLibs = ''.join(["$(LIB_OPT)" + entry + "$(LIB_OPT_POST) "
                                  for entry in depsLinux.split()])
            makeFile.write("\t$(CXX) $^ -o $@ $(LIBDIR) $(LIBS) %s %s %s\n" %\
                           (libsLinux, depsAsLibs, depsAsLibs))
            makeFile.write("endif\n")
            makeFile.write("endif\n")
        elif targetType == "lib":
            # our static lib; previously known as a "package"
            # TODO: need to fix the MACOSX options...

            endTarget = "$(N_TARGETDIR)$(LIB_PRE)%s$(LIB_POST)" % target.name
            makeFile.write("ifeq ($(N_COMPILER),__VC__)\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsWin32, endTarget))
            makeFile.write("%s : %s %s\n" % (endTarget, filesWin32, resourceFiles))
            makeFile.write("\t$(AR) $(LFLAGS) $^ /OUT:$@ $(LIBDIR) $(LIBS) %s\n" % libsWin32)
            makeFile.write("else\n")
            makeFile.write("ifeq ($(N_PLATFORM),__MACOSX__)\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsMacOSX, endTarget))
            makeFile.write("%s : %s\n" % (endTarget, filesMacOSX))
            makeFile.write("\t$(CXX) -dynamiclib -compatibility_version 0.1 -current_version 0.1.0 $^ -o $@ $(CFLAGS) $(LIBDIR) $(LIBS) %s\n" % libsMacOSX)
            makeFile.write("%s : packages/%s_bundle$(OBJ)\n" % (endTarget, target.name))
            makeFile.write("\t$(CXX) $^ -o $@ $(CFLAGS) $(LIBDIR) $(LIBS) $(LIB_OPT)%s %s -bundle -flat_namespace\n" % (target.name, libsMacOSX))
            makeFile.write("else\n")
            makeFile.write("%s : %s %s\n" % (target.name, depsLinux, endTarget))
            makeFile.write("%s : %s\n" % (endTarget, filesLinux))
            makeFile.write("\t$(AR) -cr $@ $^\n")
            makeFile.write("endif\n")
            makeFile.write("endif\n")

        # Put the end on if we are platform specific
        if needsEnd:
            makeFile.write("endif\n")

    #--------------------------------------------------------------------------
    # Writes each workspace makefile
    def generateWorkspace(self, workspace):

        makeFile = file("%s.mak" % os.path.join(self.buildSys.homeDir, self.workspacePath,
                                workspace.name), 'w')

        # Generate all possible lists of targets
        targetsWin32  = ""
        targetsLinux  = ""
        targetsMacOSX = ""
        modulesList = []
        for targetName in workspace.targets:
            if not self.buildSys.targets[targetName].SupportsPlatform("all"):
                if self.buildSys.targets[targetName].SupportsPlatform("win32"):
                    targetsWin32  += " %s" % targetName
                elif self.buildSys.targets[targetName].SupportsPlatform("linux"):
                    targetsLinux  += " %s" % targetName
                elif self.buildSys.targets[targetName].SupportsPlatform("macosx"):
                    targetsMacOSX += " %s" % targetName
                else:
                    print "Target %s not found on any regular platform! PANIC!!!" % targetName
            else:
                targetsWin32  += " %s" % targetName
                targetsLinux  += " %s" % targetName
                targetsMacOSX += " %s" % targetName

             # Add this target's modules to a temp list
            for moduleName in self.buildSys.targets[targetName].modules:
                 module = self.buildSys.modules[moduleName]
                 modulesList.append(module)

        # Header...
        makeFile.write("#--------------------------------------------------------------------\n")
        makeFile.write("#    %s.mak\n" % workspace.name)
        makeFile.write("#    AUTOMATICALLY GENERATED, DO NOT EDIT\n")
        makeFile.write("#--------------------------------------------------------------------\n")
        makeFile.write("include ../../buildsys3/config.mak\n")
        makeFile.write("BASECFLAGS += $(EXTRA_CFLAGS)\n")
        makeFile.write("LIBDIR += $(EXTRA_LIBDIR)\n\n")
        makeFile.write("ifeq ($(N_PLATFORM),__WIN32__)\n")
        makeFile.write("%s: %s\n" % (workspace.name, targetsWin32))
        makeFile.write("endif\n")
        makeFile.write("ifeq ($(N_PLATFORM),__LINUX__)\n")
        makeFile.write("%s: %s\n" % (workspace.name, targetsLinux))
        makeFile.write("endif\n")
        makeFile.write("ifeq ($(N_PLATFORM),__MACOSX__)\n")
        makeFile.write("%s: %s\n" % (workspace.name, targetsMacOSX))
        makeFile.write("endif\n\n")

        # Modules...
        makeFile.write("# Modules\n")
        for module in modulesList:
            self.writeModule(module, makeFile)

        # Targets...
        for targetName in workspace.targets:
            makeFile.write("# Targets\n\n")
            self.writeTarget(self.buildSys.targets[targetName], makeFile)

        makeFile.write("\n# Errata\n")
        # All base targets need to be .PHONY
        makeFile.write(".PHONY: ")
        for targetName in workspace.targets:
            makeFile.write("%s " % targetName)
        makeFile.write("\n\n")

        makeFile.close()

#--------------------------------------------------------------------------
# EOF
#--------------------------------------------------------------------------




See more files for this project here

The Nebula Device

Realtime 3D game/visualization engine, written in C++, scriptable through Tcl/Tk, Python and Lua. Supports D3D and OpenGL for rendering, runs under Linux and Windows.

Project homepage: http://sourceforge.net/projects/nebuladevice
Programming language(s): C,C++,Python
License: other

  __init__.py
  doxygen.py
  factory.py
  makefile.py
  vstudio7.py
  vstudio71.py
  vstudio8.py