def generateConfig(self, asyncConfigPath=None, asyncConfigFileName=None): outIncludeDir = os.path.join(FileSystem.getDirectory(FileSystem.OUT_ROOT), "include") projectLogDir = FileSystem.getDirectory(FileSystem.LOG_DIR, self._config, self._project_name) asyncConfig = None if asyncConfigPath is None: asyncConfig = os.path.join(FileSystem.getDirectory(FileSystem.CLIENT_CONFIG), (asyncConfigFileName if asyncConfigFileName is not None else "AsyncConfig.xml")) else: asyncConfig = asyncConfigPath Utilities.mkdir(outIncludeDir) configArgs = [] configArgs.append(['std::string', 'LOGGING_ROOT', 'dir', projectLogDir.replace("\\", "/")]) if "Robos" in self._project_name: configArgs.append(['std::string', 'ASYNC_CONFIG_PATH', 'file', asyncConfig.replace("\\", "/")]) (formattedConfigArgsHeader, formattedConfigArgsSrc) = self.checkConfigArgsAndFormat("\t", configArgs) if os.path.exists(projectLogDir): Utilities.rmTree(projectLogDir) Utilities.mkdir(projectLogDir) projNameUpper = self._project_name.upper() with open(os.path.join(outIncludeDir, self._project_name + "Config.hpp"), 'w') as file: file.write("#pragma once\n" "#ifndef " + projNameUpper + "_CONFIG_" + projNameUpper + "CONFIG_HPP\n" "#define " + projNameUpper + "_CONFIG_" + projNameUpper + "CONFIG_HPP\n\n" "// SYSTEM INCLUDES\n" "#include <string>\n\n" "// C++ PROJECT INCLUDES\n\n" "namespace " + self._project_name + "\n" "{\n" "namespace Config\n" "{\n\n" + formattedConfigArgsHeader + "} // end of namespace Config\n" "} // end of namespace " + self._project_name + "\n" "#endif // end of " + projNameUpper + "_CONFIG_" + projNameUpper + "CONFIG_HPP\n") with open(os.path.join(outIncludeDir, self._project_name + "Config.cpp"), 'w') as file: file.write("// SYSTEM INCLUDES\n\n" "// C++ PROJECT INCLUDES\n" "#include \"" + self._project_name + "Config.hpp\"\n\n" "namespace " + self._project_name + "\n" "{\n" "namespace Config\n" "{\n\n" + formattedConfigArgsSrc + "} // end of namespace Config\n" "} // end of namespace " + self._project_name + "\n")
def moveDependentProjectsToWorkingDir(self, projectToCopyFrom, projectType, rootToCopyFrom): destinationDir = FileSystem.getDirectory(FileSystem.INSTALL_ROOT, self._config, self._project_name) destLibDir = os.path.join(destinationDir, "lib") if not os.path.exists(destLibDir): Utilities.mkdir(destLibDir) if platform.system() == "Windows": destBinDir = os.path.join(destinationDir, "bin") if not os.path.exists(destBinDir): Utilities.mkdir(destBinDir) # copy dll and lib if projectType is None or projectType.upper() == "SHARED": Utilities.copyTree(os.path.join(rootToCopyFrom, "bin", projectToCopyFrom + ".dll"), destBinDir) Utilities.copyTree(os.path.join(rootToCopyFrom, "lib", projectToCopyFrom + ".lib"), destLibDir) else: if projectType is None or projectType.upper() == "SHARED": # copy .so baseRoot = os.path.join(rootToCopyFrom, "lib") if not os.path.exists(baseRoot): baseRoot = os.path.join(rootToCopyFrom, "lib64") if not os.path.exists(baseRoot): Utilities.failExecution("directories [%s, %s] do not exist" % (os.path.join(rootToCopyFrom, "lib"), baseRoot)) fileRegex = "lib" + projectToCopyFrom currentFilePath = None for entry in os.listdir(baseRoot): currentFilePath = os.path.join(baseRoot, entry) if fileRegex in entry and not os.path.isdir(currentFilePath): Utilities.copyTree(currentFilePath, destLibDir) else: # copy .a Utilities.copyTree(os.path.join(rootToCopyFrom, "lib", "lib" + projectToCopyFrom + ".a"), destLibDir) Utilities.copyTree(os.path.join(rootToCopyFrom, "include", projectToCopyFrom), os.path.join(destinationDir, "include", projectToCopyFrom))
def parseDependencyFile(self): dependencyFilePath = os.path.join(FileSystem.getDirectory(FileSystem.DEPENDENCIES), "dependencies.txt") if not os.path.exists(dependencyFilePath): Utilities.failExecution("dependency file [%s] does not exist" % dependencyFilePath) requiredProjects = [] with open(dependencyFilePath, 'r') as file: flag = False lineNum = 0 splitLine = None for line in file: splitLine = line.strip().split(None) if len(splitLine) == 0 or splitLine[0] == '#': continue if splitLine[0] == '-' + self._project_name: flag = True elif flag and '-' not in splitLine[0]: requiredProjects.append(splitLine) elif flag and '-' in splitLine[0] and ('-' + self._project_name) != splitLine[0]: flag = False elif not flag: continue else: Utilities.failExecution("Parse error in dependency file [%s] at line [%s]" % (dependencyFilePath, lineNum)) lineNum += 1 print("Required projects for project [%s] are %s" % (self._project_name, requiredProjects)) return requiredProjects
def makeVisualStudioProjects(self, test="OFF", logging="OFF"): wd = FileSystem.getDirectory(FileSystem.VISUAL_STUDIO_ROOT, self._config, self._project_name) Utilities.mkdir(wd) CMakeArgs = self.getCMakeArgs("", wd, test, logging) if platform.system() == "Windows": visualStudioVersion = Utilities.formatVisualStudioVersion(Utilities.getVisualStudioVersion()) CMakeArgs.extend(["-G", '"Visual Studio %s"' % visualStudioVersion]) Utilities.PForkWithVisualStudio(appToExecute="cmake", argsForApp=CMakeArgs, wd=wd)
def makeTarget(self, targets): # make directory that CMake will dump all output to wd = FileSystem.getDirectory(FileSystem.WORKING, self._config, self._project_name) if platform.system() == "Windows": Utilities.PForkWithVisualStudio(appToExecute="nmake", argsForApp=targets, wd=wd) else: Utilities.PFork(appToExecute="make", argsForApp=targets, wd=wd, failOnError=True)
def buildAndLoadDependencies(self): dependentProjects = self.parseDependencyFile() print("dependentProjects %s" % dependentProjects) projectBuild = None Utilities.mkdir(FileSystem.getDirectory(FileSystem.INSTALL_ROOT, self._config, self._project_name)) allBuiltOutDir = FileSystem.getDirectory(FileSystem.OUT_ROOT, self._config) for project in dependentProjects: dependentProjectPath = FileSystem.getDirectory(FileSystem.INSTALL_ROOT, self._config, project[0]) # build the project if necessary if not os.path.exists(dependentProjectPath): projectBuild = LocalBuildRules.LocalBuild(project[0]) projectBuild.run(([], self._custom_args)) # copy over necessary objects to link self.moveDependentProjectsToWorkingDir(project[0], project[1] if len(project) >= 2 else None, allBuiltOutDir)
def cmake(self, test="OFF", logging="OFF", python="OFF"): # make directory that CMake will dump output to wd = FileSystem.getDirectory(FileSystem.WORKING, self._config, self._project_name) Utilities.mkdir(wd) CMakeArgs = self.getCMakeArgs("", wd, test, logging, python) if platform.system() == "Windows": CMakeArgs.extend(["-G", '"NMake Makefiles"']) Utilities.PForkWithVisualStudio(appToExecute="cmake", argsForApp=CMakeArgs, wd=wd) else: CMakeArgs.extend(["-G", "Unix Makefiles"]) Utilities.PFork(appToExecute="cmake", argsForApp=CMakeArgs, wd=wd, failOnError=True)
def generateProjectVersion(self): outIncludeDir = os.path.join( FileSystem.getDirectory(FileSystem.OUT_ROOT), 'include' ) print("making directory %s" % outIncludeDir) Utilities.mkdir(outIncludeDir) with open(os.path.join(outIncludeDir, 'Version.hpp'), 'w') as file: file.write("#pragma once\n" "#ifndef VERSION_H\n" "#define VERSION_H\n\n" "#define VERSION " + self._project_build_number + "\n" "#define VERSION_STR \"" + self._project_build_number + "\"\n\n" "#endif // VERSION_H\n\n")
def __init__(self): self._project_name = "" self._project_namespace = "" self._source_dirs = ["cpp"] self._build_steps = [] self._project_build_number = "0.0.0.0" self._configurations = ["debug", "release"] self._build_directory = FileSystem.getDirectory(FileSystem.WORKING) # execute local environment projectSpecificEnvVars = { # project specific static environment variables } localEnv = LocalEnvironment.LocalEnvironment(projectSpecificEnvVars) localEnv.injectAllEnvironmentVariables()
def runUnitTests(self, iterations=1, test="OFF", valgrind="OFF"): print("Running unit tests for project [%s]" % self._project_name) if test == "OFF": print("Unit tests disables for project [%s]" % self._project_name) return installRoot = FileSystem.getDirectory(FileSystem.INSTALL_ROOT, self._config, self._project_name) args = [] for iteration in range(0, int(iterations)): print("Running unit tests [%s/%s]" % (iteration + 1, iterations)) for testToRun in self._tests_to_run: executablePath = os.path.join(installRoot, "bin", testToRun) if platform.system() == "Windows": executablePath += ".exe" else: if valgrind == "ON": args = ['valgrind', '--leak-check=yes', executablePath] if os.path.exists(executablePath): Utilities.PFork(appToExecute=(executablePath if len(args) == 0 else None), argsForApp=args, failOnError=True) else: print("%s does NOT exist!" % executablePath) if iterations > 1: print("\n\n")
def customSetupWorkspace(self, node): print("Setting up workspaces for package [%s]" % node._name) self.cleanBuildWorkspace(node) Utilities.mkdir(FileSystem.getDirectory(FileSystem.WORKING, self._config, node._name)) self.loadDependencies(node)
def cleanBuildWorkspace(self): print("Cleaning build directory for project [%s]" % self._project_name) buildDirectory = FileSystem.getDirectory(FileSystem.WORKING, self._config, self._project_name) if os.path.exists(buildDirectory): Utilities.rmTree(buildDirectory)
def getCMakeArgs(self, pathPrefix, workingDirectory, test, logging, python): CMakeProjectDir = "projects" relCMakeProjectDir = os.path.relpath(CMakeProjectDir, workingDirectory) dummyDir = os.path.join( FileSystem.getDirectory(FileSystem.OUT_ROOT, self._config, self._project_name), 'dummy') # projectWorkingDir = getDirectory(FileSystemDirectory.ROOT, self._config, self._project_name) installRootDir = FileSystem.getDirectory(FileSystem.INSTALL_ROOT, self._config, self._project_name) # all of these are relative paths that are used by CMake # to place the appropriate build components in the correct # directories. binDir = os.path.relpath( os.path.join(FileSystem.getDirectory(FileSystem.INSTALL_ROOT, self._config, self._project_name), "bin"), dummyDir ) libDir = os.path.relpath( os.path.join(FileSystem.getDirectory(FileSystem.INSTALL_ROOT, self._config, self._project_name), "lib"), dummyDir ) outIncludeDir = os.path.join(FileSystem.getDirectory(FileSystem.OUT_ROOT, self._config, self._project_name), "include") toolchainDir = os.path.relpath(FileSystem.getDirectory(FileSystem.CMAKE_TOOLCHAIN_DIR), workingDirectory) allBuiltOutDir = FileSystem.getDirectory(FileSystem.OUT_ROOT, self._config) if platform.system() == "Windows": installRootDir = "\"%s\"" % installRootDir.replace("\\", "/") outIncludeDir = "\"%s\"" % outIncludeDir.replace("\\", "/") # toolchain = "\"%s\"" % toolchainDir.replace("\\", "/") if self._config == "release": cmake_config = "Release" else: cmake_config = "Debug" fullToolchainPath = None if platform.system() == "Windows": fullToolchainPath = os.path.join(toolchainDir, "toolchain_windows_%s.cmake" % Utilities.getMachineBits()) # "x86") else: fullToolchainPath = os.path.join(toolchainDir, "toolchain_unix_%s.cmake" % Utilities.getMachineBits()) monoPath = os.environ.get("MONO_BASE_PATH").replace("\\", "/") \ if os.environ.get("MONO_BASE_PATH") is not None else "" pythonPath = os.environ.get("PYTHON_BASE_PATH").replace("\\", "/") \ if os.environ.get("PYTHON_BASE_PATH") is not None else "" pythonVer = os.environ.get("PYTHON_VERSION") if os.environ.get("PYTHON_VERSION") is not None else 0 # remember CMake paths need to be relative to the top level # directory that CMake is called (in this case projects/<project_name>) CMakeArgs = [ relCMakeProjectDir, "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=%s%s" % (pathPrefix, binDir), "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=%s%s" % (pathPrefix, libDir), "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=%s%s" % (pathPrefix, libDir), "-DCMAKE_PREFIX_PATH=%s" % (installRootDir), # absolute path "-DCMAKE_BUILD_TYPE=%s" % cmake_config, "-DPROCESSOR=%s" % Utilities.getProcessorInfo(), "-DCMAKE_TOOLCHAIN_FILE=%s" % fullToolchainPath, # toolchain file path (relative) "-DBUILD_%s=ON" % self._project_name.upper(), "-DCMAKE_INSTALL_PREFIX=%s" % allBuiltOutDir, # install root dir "-DRUN_UNIT_TESTS=%s" % test, "-DENABLE_LOGGING=%s" % logging, "-DMONO_PATH=\"%s\"" % monoPath, "-DPYTHON_PATH=\"%s\"" % pythonPath, "-DPYTHON_VERSION=%s" % pythonVer, "-DPYTHON_ENABLED=%s" % python, ] return CMakeArgs
def setupWorkspace(self): print("Setting up workspaces for project [%s]" % self._project_name) self.cleanBuildWorkspace() Utilities.mkdir(FileSystem.getDirectory(FileSystem.WORKING, self._config, self._project_name)) self.buildAndLoadDependencies()