/** * Computes, for each C++ source file in {@link #getLinkstamps}, the command necessary to compile * that file such that the output is correctly fed into the link command. * * <p>As these options (as well as all others) are taken into account when computing the action * key, they do not directly contain volatile build information to avoid unnecessary relinking. * Instead this information is passed as an additional header generated by {@link * com.google.devtools.build.lib.rules.cpp.WriteBuildInfoHeaderAction}. * * @param outputPrefix prefix to add before the linkstamp outputs' exec paths * @return a list of shell-escaped compiler commmands, one for each entry in {@link * #getLinkstamps} */ public List<String> getLinkstampCompileCommands(String outputPrefix) { if (linkstamps.isEmpty()) { return ImmutableList.of(); } String compilerCommand = cppConfiguration.getCppExecutable().getPathString(); List<String> commands = Lists.newArrayListWithCapacity(linkstamps.size()); for (Map.Entry<Artifact, Artifact> linkstamp : linkstamps.entrySet()) { List<String> optionList = new ArrayList<>(); // Defines related to the build info are read from generated headers. for (Artifact header : buildInfoHeaderArtifacts) { optionList.add("-include"); optionList.add(header.getExecPathString()); } String labelReplacement = Matcher.quoteReplacement( isSharedNativeLibrary() ? output.getExecPathString() : Label.print(owner.getLabel())); String outputPathReplacement = Matcher.quoteReplacement(output.getExecPathString()); for (String option : linkstampCompileOptions) { optionList.add( option .replaceAll(Pattern.quote("${LABEL}"), labelReplacement) .replaceAll(Pattern.quote("${OUTPUT_PATH}"), outputPathReplacement)); } optionList.add("-DGPLATFORM=\"" + cppConfiguration + "\""); // Needed to find headers included from linkstamps. optionList.add("-I."); // Add sysroot. PathFragment sysroot = cppConfiguration.getSysroot(); if (sysroot != null) { optionList.add("--sysroot=" + sysroot.getPathString()); } // Add toolchain compiler options. optionList.addAll(cppConfiguration.getCompilerOptions(features)); optionList.addAll(cppConfiguration.getCOptions()); optionList.addAll(cppConfiguration.getUnfilteredCompilerOptions(features)); if (CppFileTypes.CPP_SOURCE.matches(linkstamp.getKey().getExecPath())) { optionList.addAll(cppConfiguration.getCxxOptions(features)); } // For dynamic libraries, produce position independent code. if (linkTargetType == LinkTargetType.DYNAMIC_LIBRARY && cppConfiguration.toolchainNeedsPic()) { optionList.add("-fPIC"); } // Stamp FDO builds with FDO subtype string if (fdoBuildStamp != null) { optionList.add("-D" + CppConfiguration.FDO_STAMP_MACRO + "=\"" + fdoBuildStamp + "\""); } // Add the compilation target. optionList.add("-c"); optionList.add(linkstamp.getKey().getExecPathString()); // Assemble the final command, exempting outputPrefix from shell escaping. commands.add( compilerCommand + " " + ShellEscaper.escapeJoinAll(optionList) + " -o " + outputPrefix + ShellEscaper.escapeString(linkstamp.getValue().getExecPathString())); } return commands; }