/// <summary> /// Constructor /// </summary> private MakefileBuilder_Project_CPP(ProjectInfo_CPP project, ProjectInfo_CUDA projectInfoCuda) { m_projectInfo = project; m_projectInfoCuda = projectInfoCuda; try { // We create the file '[project-name].makefile', and set it to // use unix-style line endings... string path = String.Format("{0}/{1}.makefile", m_projectInfo.RootFolderAbsolute, m_projectInfo.Name); m_file = new StreamWriter(path, false); m_file.NewLine = MakeItSoConfig.Instance.NewLine; // We create variables... createCompilerVariables(); createIncludePathVariables(); createLibraryPathVariables(); createLibrariesVariables(); createPreprocessorDefinitionsVariables(); createImplicitlyLinkedObjectsVariables(); createCompilerFlagsVariables(); MakefileBuilder_Project_CUDA.createCudaLocationAndCompiler(m_file, m_projectInfoCuda); MakefileBuilder_Project_CUDA.createCudaIncludesAndLibaryPath(m_file, m_projectInfo, m_projectInfoCuda); // We create an 'all configurations' root target... createAllConfigurationsTarget(); // We create one target for each configuration... createConfigurationTargets(); // We create a target to create the intermediate and output folders... createCreateFoldersTarget(); // Creates the target that cleans intermediate files... createCleanTarget(); } finally { if (m_file != null) { m_file.Close(); m_file.Dispose(); } } }
/// <summary> /// Creates a target for each configuration. /// </summary> private void createConfigurationTargets() { foreach (ProjectConfigurationInfo_CPP configurationInfo in m_projectInfo.getConfigurationInfos()) { // We create the configuration target... createConfigurationTarget(configurationInfo); // We create the pre-build event target (if there is a pre-build event)... createPreBuildEventTarget(configurationInfo); // We create targets for any custom build rules... createCustomBuildRuleTargets(configurationInfo); // We compile all files for this target... createFileTargets(configurationInfo); MakefileBuilder_Project_CUDA.createCudaLinker(m_file, m_projectInfo, configurationInfo, m_projectInfoCuda); MakefileBuilder_Project_CUDA.createFileTargets(m_file, m_projectInfo, configurationInfo, m_projectInfoCuda); } }
/// <summary> /// Creates a configuration target. /// </summary> private void createConfigurationTarget(ProjectConfigurationInfo_CPP configurationInfo) { // For example: // // .PHONY: Debug // Debug: debug/main.o debug/math.o debug/utility.o // g++ debug/main.o debug/math.o debug/utility.o -o output/hello.exe // The target name... m_file.WriteLine("# Builds the {0} configuration...", configurationInfo.Name); m_file.WriteLine(".PHONY: {0}", configurationInfo.Name); // The targets that this target depends on... string dependencies = "create_folders "; // Is there a pre-build event for this configuration? if (configurationInfo.PreBuildEvent != "") { string preBuildTargetName = getPreBuildTargetName(configurationInfo); dependencies += (preBuildTargetName + " "); } // We add any custom build targets as dependencies... foreach (CustomBuildRuleInfo_CPP ruleInfo in configurationInfo.getCustomBuildRuleInfos()) { string ruleTargetName = getCustomRuleTargetName(configurationInfo, ruleInfo); dependencies += (ruleTargetName + " "); } var projectSettings = MakeItSoConfig.Instance.getProjectConfig(m_projectInfo.Name); // The object files the target depends on... string intermediateFolder = getIntermediateFolder(configurationInfo); string objectFiles = ""; foreach (string filename in m_projectInfo.getFiles()) { if (!projectSettings.filesOrDirectoriesShouldBeRemoved(filename)) { string path = String.Format("{0}/{1}", intermediateFolder, filename); if (filename.StartsWith("..")) { var tmp = filename.Replace("../", ""); path = String.Format("{0}/{1}", intermediateFolder, tmp); } string objectPath = Path.ChangeExtension(path, ".o"); objectFiles += (objectPath + " "); dependencies += (objectPath + " "); } } // To Link with gpu code. if (m_projectInfo.ProjectType != ProjectInfo_CPP.ProjectTypeEnum.CPP_EXECUTABLE) { // NOTE // https://stackoverflow.com/questions/26893588/creating-a-static-cuda-library-to-be-linked-with-a-c-program // dlinkするときは元になったobjファイルも含めること. // そうしないと、hostコードが含まれなくなる. objectFiles += MakefileBuilder_Project_CUDA.getObjectFiles(intermediateFolder, m_projectInfoCuda); dependencies += MakefileBuilder_Project_CUDA.getObjectFiles(intermediateFolder, m_projectInfoCuda); } // We write the dependencies... m_file.WriteLine("{0}: {1}", configurationInfo.Name, dependencies); // We find variables needed for the link step... string outputFolder = getOutputFolder(configurationInfo); string implicitlyLinkedObjectFiles = String.Format("$({0})", getImplicitlyLinkedObjectsVariableName(configurationInfo)); // The link step... #if false switch (m_projectInfo.ProjectType) { // Creates a C++ executable... case ProjectInfo_CPP.ProjectTypeEnum.CPP_EXECUTABLE: string libraryPath = getLibraryPathVariableName(configurationInfo); string libraries = getLibrariesVariableName(configurationInfo); m_file.WriteLine("\tg++ {0} $({1}) $({2}) -Wl,-rpath,./ -o {3}/{4}.exe", objectFiles, libraryPath, libraries, outputFolder, m_projectInfo.Name); break; // Creates a static library... case ProjectInfo_CPP.ProjectTypeEnum.CPP_STATIC_LIBRARY: // We use the Target Name as the output file name if it exists if (configurationInfo.TargetName != "") { m_file.WriteLine("\tar rcs {0}/lib{1}.a {2} {3}", outputFolder, configurationInfo.TargetName, objectFiles, implicitlyLinkedObjectFiles); } else { m_file.WriteLine("\tar rcs {0}/lib{1}.a {2} {3}", outputFolder, m_projectInfo.Name, objectFiles, implicitlyLinkedObjectFiles); } break; // Creates a DLL (shared-objects) library... case ProjectInfo_CPP.ProjectTypeEnum.CPP_DLL: string dllName, pic; if (MakeItSoConfig.Instance.IsCygwinBuild == true) { dllName = String.Format("lib{0}.dll", m_projectInfo.Name); pic = ""; } else { dllName = String.Format("lib{0}.so", m_projectInfo.Name); pic = "-fPIC"; } m_file.WriteLine("\tg++ {0} -shared -Wl,-soname,{1} -o {2}/{1} {3} {4}", pic, dllName, outputFolder, objectFiles, implicitlyLinkedObjectFiles); break; } #else switch (m_projectInfo.ProjectType) { // Creates a C++ executable... case ProjectInfo_CPP.ProjectTypeEnum.CPP_EXECUTABLE: string libraryPath = getLibraryPathVariableName(configurationInfo); string libraries = getLibrariesVariableName(configurationInfo); string exeName = getBuildExportName(configurationInfo); m_file.WriteLine("\tg++ {0} $({1}) $({2}) -Wl,-rpath,./ -o {3}/{4}", objectFiles, libraryPath, libraries, outputFolder, exeName); break; // Creates a static library... case ProjectInfo_CPP.ProjectTypeEnum.CPP_STATIC_LIBRARY: // We use the Target Name as the output file name if it exists var libName = getBuildExportName(configurationInfo); m_file.WriteLine("\tar rcs {0}/{1} {2} {3}", outputFolder, libName, objectFiles, implicitlyLinkedObjectFiles); break; // Creates a DLL (shared-objects) library... case ProjectInfo_CPP.ProjectTypeEnum.CPP_DLL: string dllName = getBuildExportName(configurationInfo); string pic; if (MakeItSoConfig.Instance.IsCygwinBuild == true) { pic = ""; } else { pic = "-fPIC"; } m_file.WriteLine("\tg++ {0} -shared -Wl,-soname,{1} -o {2}/{1} {3} {4}", pic, dllName, outputFolder, objectFiles, implicitlyLinkedObjectFiles); break; } #endif // The post-build step, if there is one... if (configurationInfo.PostBuildEvent != "") { m_file.WriteLine("\t" + configurationInfo.PostBuildEvent); } m_file.WriteLine(""); }