diff options
Diffstat (limited to 'plugins/org.yocto.cmake.managedbuilder/src/org/yocto/cmake/managedbuilder/YoctoCMakeMakefileGenerator.java')
-rw-r--r-- | plugins/org.yocto.cmake.managedbuilder/src/org/yocto/cmake/managedbuilder/YoctoCMakeMakefileGenerator.java | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/plugins/org.yocto.cmake.managedbuilder/src/org/yocto/cmake/managedbuilder/YoctoCMakeMakefileGenerator.java b/plugins/org.yocto.cmake.managedbuilder/src/org/yocto/cmake/managedbuilder/YoctoCMakeMakefileGenerator.java new file mode 100644 index 0000000..b77ae9e --- /dev/null +++ b/plugins/org.yocto.cmake.managedbuilder/src/org/yocto/cmake/managedbuilder/YoctoCMakeMakefileGenerator.java | |||
@@ -0,0 +1,281 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2013 BMW Car IT GmbH. | ||
3 | * All rights reserved. This program and the accompanying materials | ||
4 | * are made available under the terms of the Eclipse Public License v1.0 | ||
5 | * which accompanies this distribution, and is available at | ||
6 | * http://www.eclipse.org/legal/epl-v10.html | ||
7 | * | ||
8 | * Contributors: | ||
9 | * BMW Car IT - initial API and implementation | ||
10 | *******************************************************************************/ | ||
11 | package org.yocto.cmake.managedbuilder; | ||
12 | |||
13 | import java.io.ByteArrayInputStream; | ||
14 | import java.io.InputStream; | ||
15 | |||
16 | import org.eclipse.cdt.managedbuilder.core.IBuilder; | ||
17 | import org.eclipse.cdt.managedbuilder.core.IConfiguration; | ||
18 | import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; | ||
19 | import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; | ||
20 | import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; | ||
21 | import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator2; | ||
22 | import org.eclipse.core.resources.IFile; | ||
23 | import org.eclipse.core.resources.IProject; | ||
24 | import org.eclipse.core.resources.IResource; | ||
25 | import org.eclipse.core.resources.IResourceDelta; | ||
26 | import org.eclipse.core.runtime.CoreException; | ||
27 | import org.eclipse.core.runtime.IPath; | ||
28 | import org.eclipse.core.runtime.IProgressMonitor; | ||
29 | import org.eclipse.core.runtime.IStatus; | ||
30 | import org.eclipse.core.runtime.MultiStatus; | ||
31 | import org.eclipse.core.runtime.jobs.Job; | ||
32 | import org.yocto.cmake.managedbuilder.job.ExecuteConfigureJob; | ||
33 | import org.yocto.sdk.ide.utils.YoctoSDKUtils; | ||
34 | |||
35 | public class YoctoCMakeMakefileGenerator implements IManagedBuilderMakefileGenerator2 { | ||
36 | |||
37 | private static final String TOOLCHAINCMAKE_FILE_NAME = "toolchain.cmake"; //$NON-NLS-1$ | ||
38 | private static final String MAKEFILE_NAME = "Makefile"; //$NON-NLS-1$ | ||
39 | private static final String CMAKE_FILE_NAME = "CMakeLists.txt"; //$NON-NLS-1$ | ||
40 | private static final String CMAKECACHE_FILE_NAME = "CMakeCache.txt"; //$NON-NLS-1$ | ||
41 | |||
42 | private IProject project; | ||
43 | private int lastBuildInfoChecksum = 0; | ||
44 | private IConfiguration configuration; | ||
45 | private IProgressMonitor monitor; | ||
46 | private IPath buildDir = null; | ||
47 | |||
48 | @Override | ||
49 | public String getMakefileName() { | ||
50 | return MAKEFILE_NAME; | ||
51 | } | ||
52 | |||
53 | @Override | ||
54 | public IPath getBuildWorkingDir() { | ||
55 | IPath buildWorkingDir = null; | ||
56 | |||
57 | if (buildDir != null) { | ||
58 | buildWorkingDir = buildDir.removeFirstSegments(1); | ||
59 | } | ||
60 | |||
61 | return buildWorkingDir; | ||
62 | } | ||
63 | |||
64 | @Override | ||
65 | public boolean isGeneratedResource(IResource resource) { | ||
66 | return false; | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public void initialize(IProject project, IManagedBuildInfo info, | ||
71 | IProgressMonitor monitor) { | ||
72 | this.project = project; | ||
73 | this.configuration = info.getDefaultConfiguration(); | ||
74 | this.monitor = monitor; | ||
75 | |||
76 | if (info.getDefaultConfiguration() != null) { | ||
77 | buildDir = project.getFolder(info.getConfigurationName()).getFullPath(); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public void initialize(int buildKind, IConfiguration configuration, IBuilder builder, | ||
83 | IProgressMonitor monitor) { | ||
84 | this.project = configuration.getOwner().getProject(); | ||
85 | this.configuration = configuration; | ||
86 | this.monitor = monitor; | ||
87 | this.buildDir = project.getFolder(configuration.getName()).getFullPath(); | ||
88 | } | ||
89 | |||
90 | @Override | ||
91 | public void generateDependencies() throws CoreException { | ||
92 | // nothing to do here | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public void regenerateDependencies(boolean force) throws CoreException { | ||
97 | generateDependencies(); | ||
98 | } | ||
99 | |||
100 | @Override | ||
101 | public MultiStatus generateMakefiles(IResourceDelta delta) | ||
102 | throws CoreException { | ||
103 | int currentBuildInfoChecksum = ManagedBuildManager.getBuildInfo(project).hashCode(); | ||
104 | |||
105 | IFile cmakeFile = project.getFile(CMAKE_FILE_NAME); | ||
106 | IResourceDelta cmakeDelta = delta.findMember(cmakeFile.getProjectRelativePath()); | ||
107 | IResourceDelta[] deltas = delta | ||
108 | .getAffectedChildren(IResourceDelta.ADDED | IResourceDelta.REMOVED); | ||
109 | |||
110 | if (deltas.length > 0 || cmakeDelta != null || currentBuildInfoChecksum != lastBuildInfoChecksum) { | ||
111 | lastBuildInfoChecksum = currentBuildInfoChecksum; | ||
112 | return regenerateMakefiles(); | ||
113 | } else { | ||
114 | // CMake is not needed to run prior to building | ||
115 | // just return that makefile generation is completed | ||
116 | return new MultiStatus( | ||
117 | ManagedBuilderCorePlugin.getUniqueIdentifier(), IStatus.OK, | ||
118 | new String(YoctoCMakeMessages.getString("YoctoCMakeMakefileGenerator.ok.makefilesStillValid")), null); //$NON-NLS-1$ | ||
119 | } | ||
120 | } | ||
121 | |||
122 | @Override | ||
123 | public MultiStatus regenerateMakefiles() throws CoreException { | ||
124 | String taskName = | ||
125 | YoctoCMakeMessages.getString("YoctoCMakeMakefileGenerator.configure.creatingMakefiles"); //$NON-NLS-1$ | ||
126 | monitor.beginTask(taskName, 20); | ||
127 | |||
128 | IFile cmakeFile = project.getFile(CMAKE_FILE_NAME); | ||
129 | if (!cmakeFile.exists()) { | ||
130 | return new MultiStatus(ManagedBuilderCorePlugin.getUniqueIdentifier(), IStatus.CANCEL, | ||
131 | new String(YoctoCMakeMessages.getString("YoctoCMakeMakefileGenerator.cancel.missingCMakeList")), null); //$NON-NLS-1$ | ||
132 | } | ||
133 | |||
134 | // Retrieve Build directory | ||
135 | IPath workingDir = getBuildWorkingDir(); | ||
136 | IPath location = project.getLocation().append(workingDir); | ||
137 | monitor.worked(1); | ||
138 | |||
139 | // Create build directory if it doesn't exist | ||
140 | if (!location.toFile().exists()) { | ||
141 | monitor.subTask( | ||
142 | YoctoCMakeMessages.getString("YoctoCMakeMakefileGenerator.creatingBuildDirectory")); //$NON-NLS-1$ | ||
143 | location.toFile().mkdirs(); | ||
144 | } else { | ||
145 | monitor.subTask( | ||
146 | YoctoCMakeMessages.getString("YoctoCMakeMakefileGenerator.removingCacheFiles")); //$NON-NLS-1$ | ||
147 | IFile cmakeCache = project.getFile(workingDir.append(CMAKECACHE_FILE_NAME)); | ||
148 | cmakeCache.delete(true, monitor); | ||
149 | } | ||
150 | monitor.setTaskName(taskName); | ||
151 | |||
152 | createToolchainCMakeFile(workingDir); | ||
153 | |||
154 | // Create the Makefiles by executing cmake | ||
155 | ExecuteConfigureJob job = | ||
156 | new ExecuteConfigureJob( | ||
157 | YoctoCMakeMessages.getString("YoctoCMakeMakefileGenerator.configureJob.name"), //$NON-NLS-1$ | ||
158 | project, configuration, location); | ||
159 | job.setPriority(Job.BUILD); | ||
160 | job.setUser(false); | ||
161 | |||
162 | job.schedule(); | ||
163 | try { | ||
164 | job.join(); | ||
165 | monitor.done(); | ||
166 | return new MultiStatus( | ||
167 | Activator.PLUGIN_ID, job.getResult().getSeverity(), | ||
168 | job.getResult().getMessage(), null); | ||
169 | } catch (InterruptedException e) { | ||
170 | return new MultiStatus( | ||
171 | Activator.PLUGIN_ID, | ||
172 | IStatus.ERROR, new String( | ||
173 | YoctoCMakeMessages.getString("YoctoCMakeMakefileGenerator.error.makeFileGenerationFailed")), null); //$NON-NLS-1$ | ||
174 | } | ||
175 | } | ||
176 | |||
177 | private String createCMakeSetStatement(String variable, String value, String cacheOption) { | ||
178 | String setStatement = "set("; //$NON-NLS-1$ | ||
179 | setStatement += variable + " " + value; //$NON-NLS-1$ | ||
180 | if(cacheOption != null && !cacheOption.equals("")) { //$NON-NLS-1$ | ||
181 | setStatement += " " + cacheOption; //$NON-NLS-1$ | ||
182 | } | ||
183 | setStatement += ")\n"; //$NON-NLS-1$ | ||
184 | return setStatement; | ||
185 | } | ||
186 | |||
187 | // Considered poky's cmake.bbclass for this method | ||
188 | private void createToolchainCMakeFile(IPath workingDir) { | ||
189 | String toolchainCMakeFileContentAsString = "# CMake system name must be something like \"Linux\".\n" + //$NON-NLS-1$ | ||
190 | "# This is important for cross-compiling.\n"; //$NON-NLS-1$ | ||
191 | |||
192 | String targetArchValue = YoctoSDKUtils.getEnvValue(project, "TARGET_ARCH"); //$NON-NLS-1$ | ||
193 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_SYSTEM_PROCESSOR", targetArchValue, null); //$NON-NLS-1$ | ||
194 | |||
195 | String oeCMakeCCompilerValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_C_COMPILER"); //$NON-NLS-1$ | ||
196 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_C_COMPILER", oeCMakeCCompilerValue, null); //$NON-NLS-1$ | ||
197 | |||
198 | String oeCMakeCXXCompilerValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_CXX_COMPILER"); //$NON-NLS-1$ | ||
199 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_CXX_COMPILER", oeCMakeCXXCompilerValue, null); //$NON-NLS-1$ | ||
200 | |||
201 | String oeCMakeCFlagsValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_C_FLAGS"); //$NON-NLS-1$ | ||
202 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_C_FLAGS", //$NON-NLS-1$ | ||
203 | "\"" + oeCMakeCFlagsValue + "\"", "CACHE STRING \"CFLAGS\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
204 | |||
205 | String oeCMakeCXXFlagsValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_CXX_FLAGS"); //$NON-NLS-1$ | ||
206 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_CXX_FLAGS", //$NON-NLS-1$ | ||
207 | "\"" + oeCMakeCXXFlagsValue + "\"", "CACHE STRING \"CXXFLAGS\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
208 | |||
209 | String oeCMakeCFlagsReleaseValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_C_FLAGS_RELEASE"); //$NON-NLS-1$ | ||
210 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_C_FLAGS_RELEASE", //$NON-NLS-1$ | ||
211 | "\"" + oeCMakeCFlagsReleaseValue + "\"", "CACHE STRING \"CFLAGS for release\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
212 | |||
213 | String oeCMakeCXXFlagsReleaseValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_CXX_FLAGS_RELEASE"); //$NON-NLS-1$ | ||
214 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_CXX_FLAGS_RELEASE", //$NON-NLS-1$ | ||
215 | "\"" + oeCMakeCXXFlagsReleaseValue + "\"", "CACHE STRING \"CXXFLAGS for release\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
216 | |||
217 | String oeCMakeCLinkFlagsValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_C_LINK_FLAGS"); //$NON-NLS-1$ | ||
218 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_C_LINK_FLAGS", //$NON-NLS-1$ | ||
219 | "\"" + oeCMakeCLinkFlagsValue + "\"", "CACHE STRING \"LDFLAGS\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
220 | |||
221 | String oeCMakeCXXLinkFlagsValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_CXX_LINK_FLAGS"); //$NON-NLS-1$ | ||
222 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_CXX_LINK_FLAGS", //$NON-NLS-1$ | ||
223 | "\"" + oeCMakeCXXLinkFlagsValue + "\"", "CACHE STRING \"LDFLAGS\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | ||
224 | |||
225 | toolchainCMakeFileContentAsString += "\n"; //$NON-NLS-1$ | ||
226 | toolchainCMakeFileContentAsString += "# only search in the paths provided so cmake doesnt pick\n"; //$NON-NLS-1$ | ||
227 | toolchainCMakeFileContentAsString += "# up libraries and tools from the native build machine\n"; //$NON-NLS-1$ | ||
228 | |||
229 | String findRootPathValue = YoctoSDKUtils.getEnvValue(project, "STAGING_DIR_HOST"); //$NON-NLS-1$ | ||
230 | findRootPathValue += " "; //$NON-NLS-1$ | ||
231 | findRootPathValue += YoctoSDKUtils.getEnvValue(project, "STAGING_DIR_NATIVE"); //$NON-NLS-1$ | ||
232 | findRootPathValue += " "; //$NON-NLS-1$ | ||
233 | findRootPathValue += YoctoSDKUtils.getEnvValue(project, "CROSS_DIR"); //$NON-NLS-1$ | ||
234 | findRootPathValue += " "; //$NON-NLS-1$ | ||
235 | findRootPathValue += YoctoSDKUtils.getEnvValue(project, "OECMAKE_PERLNATIVE_DIR"); //$NON-NLS-1$ | ||
236 | findRootPathValue += " "; //$NON-NLS-1$ | ||
237 | findRootPathValue += YoctoSDKUtils.getEnvValue(project, "OECMAKE_EXTRA_ROOT_PATH"); //$NON-NLS-1$ | ||
238 | findRootPathValue += " "; //$NON-NLS-1$ | ||
239 | findRootPathValue += YoctoSDKUtils.getEnvValue(project, "EXTERNAL_TOOLCHAIN"); //$NON-NLS-1$ | ||
240 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_FIND_ROOT_PATH", findRootPathValue, null); //$NON-NLS-1$ | ||
241 | |||
242 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_FIND_ROOT_PATH_MODE_PROGRAM", "ONLY", null); //$NON-NLS-1$ //$NON-NLS-2$ | ||
243 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_FIND_ROOT_PATH_MODE_LIBRARY", "ONLY", null); //$NON-NLS-1$ //$NON-NLS-2$ | ||
244 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_FIND_ROOT_PATH_MODE_INCLUDE", "ONLY", null); //$NON-NLS-1$ //$NON-NLS-2$ | ||
245 | toolchainCMakeFileContentAsString += "\n"; //$NON-NLS-1$ | ||
246 | |||
247 | toolchainCMakeFileContentAsString += "# Use qt.conf settings\n"; //$NON-NLS-1$ | ||
248 | toolchainCMakeFileContentAsString += createCMakeSetStatement("ENV{QT_CONF_PATH}", "qt.conf", null); //$NON-NLS-1$ //$NON-NLS-2$ | ||
249 | toolchainCMakeFileContentAsString += "\n"; //$NON-NLS-1$ | ||
250 | |||
251 | toolchainCMakeFileContentAsString += "# We need to set the rpath to the correct directory as cmake does not provide any\n"; //$NON-NLS-1$ | ||
252 | toolchainCMakeFileContentAsString += "# directory as rpath by default\n"; //$NON-NLS-1$ | ||
253 | |||
254 | String oeCMakeRPathValue = YoctoSDKUtils.getEnvValue(project, "OECMAKE_RPATH"); //$NON-NLS-1$ | ||
255 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_INSTALL_RPATH", oeCMakeRPathValue, null); //$NON-NLS-1$ | ||
256 | |||
257 | toolchainCMakeFileContentAsString += "\n"; //$NON-NLS-1$ | ||
258 | toolchainCMakeFileContentAsString += "# Use native cmake modules\n"; //$NON-NLS-1$ | ||
259 | |||
260 | String stagingDatadirValue = YoctoSDKUtils.getEnvValue(project, "STAGING_DATADIR"); //$NON-NLS-1$ | ||
261 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_MODULE_PATH", //$NON-NLS-1$ | ||
262 | stagingDatadirValue + "/cmake/Modules/", null); //$NON-NLS-1$ | ||
263 | |||
264 | toolchainCMakeFileContentAsString += "\n"; //$NON-NLS-1$ | ||
265 | toolchainCMakeFileContentAsString += "# add for non /usr/lib libdir, e.g. /usr/lib64\n"; //$NON-NLS-1$ | ||
266 | toolchainCMakeFileContentAsString += createCMakeSetStatement("CMAKE_LIBRARY_PATH", //$NON-NLS-1$ | ||
267 | "${libdir} ${base_libdir}", null); //$NON-NLS-1$ | ||
268 | |||
269 | InputStream toolchainCMakeFileContent = new ByteArrayInputStream(toolchainCMakeFileContentAsString.getBytes()); | ||
270 | |||
271 | IFile toolchainCMakeFile = project.getFile(TOOLCHAINCMAKE_FILE_NAME); | ||
272 | try { | ||
273 | if (toolchainCMakeFile.exists()) { | ||
274 | toolchainCMakeFile.delete(true, monitor); | ||
275 | } | ||
276 | toolchainCMakeFile.create(toolchainCMakeFileContent, true, monitor); | ||
277 | } catch (CoreException e) { | ||
278 | e.printStackTrace(); | ||
279 | } | ||
280 | } | ||
281 | } | ||