Add TAL-Reverb-II plugin to test
[juce-lv2.git] / juce / source / extras / Introjucer / Source / Project / jucer_ProjectExport_Make.h
blob790b43bf09c84656b8fa8eadba125813935a08fa
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-10 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_PROJECTEXPORT_MAKE_JUCEHEADER__
27 #define __JUCER_PROJECTEXPORT_MAKE_JUCEHEADER__
29 #include "jucer_ProjectExporter.h"
32 //==============================================================================
33 class MakefileProjectExporter : public ProjectExporter
35 public:
36 //==============================================================================
37 static const char* getNameLinux() { return "Linux Makefile"; }
38 static const char* getValueTreeTypeName() { return "LINUX_MAKE"; }
40 static MakefileProjectExporter* createForSettings (Project& project, const ValueTree& settings)
42 if (settings.hasType (getValueTreeTypeName()))
43 return new MakefileProjectExporter (project, settings);
45 return 0;
49 //==============================================================================
50 MakefileProjectExporter (Project& project_, const ValueTree& settings_)
51 : ProjectExporter (project_, settings_)
53 name = getNameLinux();
55 if (getTargetLocation().toString().isEmpty())
56 getTargetLocation() = getDefaultBuildsRootFolder() + "Linux";
58 if (getVSTFolder().toString().isEmpty())
59 getVSTFolder() = "~/SDKs/vstsdk2.4";
62 //==============================================================================
63 bool isDefaultFormatForCurrentOS()
65 #if JUCE_LINUX
66 return true;
67 #else
68 return false;
69 #endif
72 bool isPossibleForCurrentProject() { return true; }
73 bool usesMMFiles() const { return false; }
75 void launchProject()
77 // what to do on linux?
80 void createPropertyEditors (Array <PropertyComponent*>& props)
82 ProjectExporter::createPropertyEditors (props);
85 //==============================================================================
86 void create()
88 Array<RelativePath> files;
89 findAllFilesToCompile (project.getMainGroup(), files);
91 for (int i = 0; i < juceWrapperFiles.size(); ++i)
92 if (shouldFileBeCompiledByDefault (juceWrapperFiles.getReference(i)))
93 files.add (juceWrapperFiles.getReference(i));
95 const Array<RelativePath> vstFiles (getVSTFilesRequired());
96 for (int i = 0; i < vstFiles.size(); i++)
97 files.add (vstFiles.getReference(i));
99 MemoryOutputStream mo;
100 writeMakefile (mo, files);
102 overwriteFileIfDifferentOrThrow (getTargetFolder().getChildFile ("Makefile"), mo);
105 private:
106 //==============================================================================
107 void findAllFilesToCompile (const Project::Item& projectItem, Array<RelativePath>& results)
109 if (projectItem.isGroup())
111 for (int i = 0; i < projectItem.getNumChildren(); ++i)
112 findAllFilesToCompile (projectItem.getChild(i), results);
114 else
116 if (projectItem.shouldBeCompiled())
117 results.add (RelativePath (projectItem.getFile(), getTargetFolder(), RelativePath::buildTargetFolder));
121 void writeDefineFlags (OutputStream& out, const Project::BuildConfiguration& config)
123 StringPairArray defines;
124 defines.set ("LINUX", "1");
126 if (config.isDebug().getValue())
128 defines.set ("DEBUG", "1");
129 defines.set ("_DEBUG", "1");
131 else
133 defines.set ("NDEBUG", "1");
136 out << createGCCPreprocessorFlags (mergePreprocessorDefs (defines, getAllPreprocessorDefs (config)));
139 void writeHeaderPathFlags (OutputStream& out, const Project::BuildConfiguration& config)
141 StringArray headerPaths (config.getHeaderSearchPaths());
142 headerPaths.insert (0, "/usr/include/freetype2");
143 headerPaths.insert (0, "/usr/include");
145 if (project.shouldAddVSTFolderToPath() && getVSTFolder().toString().isNotEmpty())
146 headerPaths.insert (0, rebaseFromProjectFolderToBuildTarget (RelativePath (getVSTFolder().toString(), RelativePath::projectFolder)).toUnixStyle());
148 if (isVST())
149 headerPaths.insert (0, juceWrapperFolder.toUnixStyle());
151 for (int i = 0; i < headerPaths.size(); ++i)
152 out << " -I " << FileHelpers::unixStylePath (replacePreprocessorTokens (config, headerPaths[i])).quoted();
155 void writeCppFlags (OutputStream& out, const Project::BuildConfiguration& config)
157 out << " CPPFLAGS := $(DEPFLAGS)";
158 writeDefineFlags (out, config);
159 writeHeaderPathFlags (out, config);
160 out << newLine;
163 void writeLinkerFlags (OutputStream& out, const Project::BuildConfiguration& config)
165 out << " LDFLAGS += -L$(BINDIR) -L$(LIBDIR)";
167 if (project.isAudioPlugin())
168 out << " -shared";
171 Array<RelativePath> libraryPaths;
172 libraryPaths.add (RelativePath ("/usr/X11R6/lib/", RelativePath::unknown));
173 libraryPaths.add (getJucePathFromTargetFolder().getChildFile ("bin"));
175 for (int i = 0; i < libraryPaths.size(); ++i)
176 out << " -L" << libraryPaths.getReference(i).toUnixStyle().quoted();
179 const char* defaultLibs[] = { "freetype", "pthread", "rt", "X11", "GL", "GLU", "Xinerama", "asound", 0 };
180 StringArray libs (defaultLibs);
182 if (project.getJuceLinkageMode() == Project::useLinkedJuce)
183 libs.add ("juce");
185 for (int i = 0; i < libs.size(); ++i)
186 out << " -l" << libs[i];
188 out << " " << replacePreprocessorTokens (config, getExtraLinkerFlags().toString()).trim()
189 << newLine;
192 void writeConfig (OutputStream& out, const Project::BuildConfiguration& config)
194 const String buildDirName ("build");
195 const String intermediatesDirName (buildDirName + "/intermediate/" + config.getName().toString());
196 String outputDir (buildDirName);
198 if (config.getTargetBinaryRelativePath().toString().isNotEmpty())
200 RelativePath binaryPath (config.getTargetBinaryRelativePath().toString(), RelativePath::projectFolder);
201 outputDir = binaryPath.rebased (project.getFile().getParentDirectory(), getTargetFolder(), RelativePath::buildTargetFolder).toUnixStyle();
204 out << "ifeq ($(CONFIG)," << escapeSpaces (config.getName().toString()) << ")" << newLine;
205 out << " BINDIR := " << escapeSpaces (buildDirName) << newLine
206 << " LIBDIR := " << escapeSpaces (buildDirName) << newLine
207 << " OBJDIR := " << escapeSpaces (intermediatesDirName) << newLine
208 << " OUTDIR := " << escapeSpaces (outputDir) << newLine;
210 writeCppFlags (out, config);
212 out << " CFLAGS += $(CPPFLAGS) $(TARGET_ARCH)";
214 if (config.isDebug().getValue())
215 out << " -g -ggdb";
217 if (project.isAudioPlugin())
218 out << " -fPIC";
220 out << " -O" << config.getGCCOptimisationFlag() << newLine;
222 out << " CXXFLAGS += $(CFLAGS) " << replacePreprocessorTokens (config, getExtraCompilerFlags().toString()).trim() << newLine;
224 writeLinkerFlags (out, config);
226 out << " LDDEPS :=" << newLine
227 << " RESFLAGS := ";
228 writeDefineFlags (out, config);
229 writeHeaderPathFlags (out, config);
230 out << newLine;
232 String targetName (config.getTargetBinaryName().getValue().toString());
234 if (project.isLibrary())
235 targetName = getLibbedFilename (targetName);
236 else if (isVST())
237 targetName = targetName.upToLastOccurrenceOf (".", false, false) + ".so";
239 out << " TARGET := " << escapeSpaces (targetName) << newLine;
241 if (project.isLibrary())
242 out << " BLDCMD = ar -rcs $(OUTDIR)/$(TARGET) $(OBJECTS) $(TARGET_ARCH)" << newLine;
243 else
244 out << " BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH)" << newLine;
246 out << "endif" << newLine << newLine;
249 void writeObjects (OutputStream& out, const Array<RelativePath>& files)
251 out << "OBJECTS := \\" << newLine;
253 for (int i = 0; i < files.size(); ++i)
254 if (shouldFileBeCompiledByDefault (files.getReference(i)))
255 out << " $(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i))) << " \\" << newLine;
257 out << newLine;
260 void writeMakefile (OutputStream& out, const Array<RelativePath>& files)
262 out << "# Automatically generated makefile, created by the Jucer" << newLine
263 << "# Don't edit this file! Your changes will be overwritten when you re-save the Jucer project!" << newLine
264 << newLine;
266 out << "ifndef CONFIG" << newLine
267 << " CONFIG=" << escapeSpaces (project.getConfiguration(0).getName().toString()) << newLine
268 << "endif" << newLine
269 << newLine;
271 if (! project.isLibrary())
272 out << "ifeq ($(TARGET_ARCH),)" << newLine
273 << " TARGET_ARCH := -march=native" << newLine
274 << "endif" << newLine << newLine;
276 out << "# (this disables dependency generation if multiple architectures are set)" << newLine
277 << "DEPFLAGS := $(if $(word 2, $(TARGET_ARCH)), , -MMD)" << newLine
278 << newLine;
280 int i;
281 for (i = 0; i < project.getNumConfigurations(); ++i)
282 writeConfig (out, project.getConfiguration(i));
284 writeObjects (out, files);
286 out << ".PHONY: clean" << newLine
287 << newLine;
289 out << "$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES)" << newLine
290 << "\t@echo Linking " << project.getProjectName() << newLine
291 << "\t-@mkdir -p $(BINDIR)" << newLine
292 << "\t-@mkdir -p $(LIBDIR)" << newLine
293 << "\t-@mkdir -p $(OUTDIR)" << newLine
294 << "\t@$(BLDCMD)" << newLine
295 << newLine;
297 out << "clean:" << newLine
298 << "\t@echo Cleaning " << project.getProjectName() << newLine
299 << "\t-@rm -f $(OUTDIR)/$(TARGET)" << newLine
300 << "\t-@rm -rf $(OBJDIR)/*" << newLine
301 << "\t-@rm -rf $(OBJDIR)" << newLine
302 << newLine;
304 for (i = 0; i < files.size(); ++i)
306 if (shouldFileBeCompiledByDefault (files.getReference(i)))
308 jassert (files.getReference(i).getRoot() == RelativePath::buildTargetFolder);
310 out << "$(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i)))
311 << ": " << escapeSpaces (files.getReference(i).toUnixStyle()) << newLine
312 << "\t-@mkdir -p $(OBJDIR)" << newLine
313 << "\t@echo \"Compiling " << files.getReference(i).getFileName() << "\"" << newLine
314 << (files.getReference(i).hasFileExtension (".c") ? "\t@$(CC) $(CFLAGS) -o \"$@\" -c \"$<\""
315 : "\t@$(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"")
316 << newLine << newLine;
320 out << "-include $(OBJECTS:%.o=%.d)" << newLine;
323 const String getObjectFileFor (const RelativePath& file) const
325 return file.getFileNameWithoutExtension()
326 + "_" + String::toHexString (file.toUnixStyle().hashCode()) + ".o";
329 JUCE_DECLARE_NON_COPYABLE (MakefileProjectExporter);
333 #endif // __JUCER_PROJECTEXPORT_MAKE_JUCEHEADER__