/* * Copyright 2015-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.lua; import com.facebook.buck.cxx.CxxPlatform; import com.facebook.buck.rules.BuildRule; import com.facebook.buck.rules.RuleKeyAppendable; import com.facebook.buck.rules.RuleKeyObjectSink; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.SourcePathRuleFinder; import com.facebook.buck.util.HumanReadableException; import com.facebook.buck.util.immutables.BuckStyleTuple; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.ImmutableSortedSet; import java.util.LinkedHashMap; import java.util.Map; import org.immutables.value.Value; /** Components that contribute to a Lua package. */ @Value.Immutable @BuckStyleTuple abstract class AbstractLuaPackageComponents implements RuleKeyAppendable { /** @return mapping of module names to their respective {@link SourcePath}s. */ @Value.NaturalOrder public abstract ImmutableSortedMap<String, SourcePath> getModules(); /** @return mapping of python module names to their respective {@link SourcePath}s. */ @Value.NaturalOrder public abstract ImmutableSortedMap<String, SourcePath> getPythonModules(); /** @return a mapping of shared native library names to their respective {@link SourcePath}s. */ @Value.NaturalOrder public abstract ImmutableSortedMap<String, SourcePath> getNativeLibraries(); public static void addComponents( LuaPackageComponents.Builder builder, LuaPackageComponents components) { builder.putAllModules(components.getModules()); builder.putAllPythonModules(components.getPythonModules()); builder.putAllNativeLibraries(components.getNativeLibraries()); } @Override public void appendToRuleKey(RuleKeyObjectSink sink) { sink.setReflectively("modules", getModules()); sink.setReflectively("pythonModules", getPythonModules()); sink.setReflectively("nativeLibraries", getNativeLibraries()); } public ImmutableSortedSet<BuildRule> getDeps(SourcePathRuleFinder ruleFinder) { return ImmutableSortedSet.<BuildRule>naturalOrder() .addAll(ruleFinder.filterBuildRuleInputs(getModules().values())) .addAll(ruleFinder.filterBuildRuleInputs(getPythonModules().values())) .addAll(ruleFinder.filterBuildRuleInputs(getNativeLibraries().values())) .build(); } public ImmutableSortedSet<SourcePath> getInputs() { return ImmutableSortedSet.<SourcePath>naturalOrder() .addAll(getModules().values()) .addAll(getPythonModules().values()) .addAll(getNativeLibraries().values()) .build(); } /** @return whether any components may be prebuilt native libraries. */ public boolean hasNativeCode(CxxPlatform cxxPlatform) { for (String module : getModules().keySet()) { if (module.endsWith(cxxPlatform.getSharedLibraryExtension())) { return true; } } for (String module : getPythonModules().keySet()) { if (module.endsWith(cxxPlatform.getSharedLibraryExtension())) { return true; } } return false; } public static Builder builder() { return new Builder(); } public static class Builder { private final Map<String, SourcePath> modules = new LinkedHashMap<>(); private final Map<String, SourcePath> pythonModules = new LinkedHashMap<>(); private final Map<String, SourcePath> nativeLibraries = new LinkedHashMap<>(); public Builder putModules(String name, SourcePath path) { SourcePath existing = modules.get(name); if (existing != null && !existing.equals(path)) { throw new HumanReadableException( "conflicting modules for %s: %s != %s", name, path, existing); } modules.put(name, path); return this; } public Builder putAllModules(Map<String, SourcePath> modules) { for (Map.Entry<String, SourcePath> entry : modules.entrySet()) { putModules(entry.getKey(), entry.getValue()); } return this; } public Builder putPythonModules(String name, SourcePath path) { SourcePath existing = pythonModules.get(name); if (existing != null && !existing.equals(path)) { throw new HumanReadableException( "conflicting python modules for %s: %s != %s", name, path, existing); } pythonModules.put(name, path); return this; } public Builder putAllPythonModules(Map<String, SourcePath> modules) { for (Map.Entry<String, SourcePath> entry : modules.entrySet()) { putPythonModules(entry.getKey(), entry.getValue()); } return this; } public Builder putNativeLibraries(String name, SourcePath path) { SourcePath existing = nativeLibraries.get(name); if (existing != null && !existing.equals(path)) { throw new HumanReadableException( "conflicting native libraries for %s: %s != %s", name, path, existing); } nativeLibraries.put(name, path); return this; } public Builder putAllNativeLibraries(Map<String, SourcePath> nativeLibraries) { for (Map.Entry<String, SourcePath> entry : nativeLibraries.entrySet()) { putNativeLibraries(entry.getKey(), entry.getValue()); } return this; } public LuaPackageComponents build() { return LuaPackageComponents.of(modules, pythonModules, nativeLibraries); } } }