// Copyright 2014 The Bazel Authors. All rights reserved. // // 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.google.devtools.build.lib.rules.cpp; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization; /** * A cache of C link parameters. * *

The cache holds instances of {@link com.google.devtools.build.lib.rules.cpp.CcLinkParams} for * combinations of linkingStatically and linkShared. If a requested value is not available in the * cache, it is computed and then stored. * *

Typically this class is used on targets that may be linked in as C libraries as in the * following example: * *

 * class SomeTarget implements CcLinkParamsStore {
 *   private final AbstractCcLinkParamsStore ccLinkParamsStore = new AbstractCcLinkParamsStore() {
 *     @Override
 *     protected void collect(CcLinkParams.Builder builder, boolean linkingStatically,
 *                            boolean linkShared) {
 *       builder.add[...]
 *     }
 *   };
 *
 *   @Override
 *   public CcLinkParams getCcLinkParams(boolean linkingStatically, boolean linkShared) {
 *     return ccLinkParamsStore.get(linkingStatically, linkShared);
 *   }
 * }
 * 
*/ public abstract class AbstractCcLinkParamsStore { protected CcLinkParams staticModeParamsForDynamicLibrary; protected CcLinkParams staticModeParamsForExecutable; protected CcLinkParams dynamicModeParamsForDynamicLibrary; protected CcLinkParams dynamicModeParamsForExecutable; private CcLinkParams compute(boolean linkingStatically, boolean linkShared) { CcLinkParams.Builder builder = CcLinkParams.builder(linkingStatically, linkShared); collect(builder, linkingStatically, linkShared); return builder.build(); } /** * Returns {@link com.google.devtools.build.lib.rules.cpp.CcLinkParams} for a combination of * parameters. * *

The {@link com.google.devtools.build.lib.rules.cpp.CcLinkParams} instance is computed lazily * and cached. */ public synchronized CcLinkParams get(boolean linkingStatically, boolean linkShared) { CcLinkParams result = lookup(linkingStatically, linkShared); if (result == null) { result = compute(linkingStatically, linkShared); put(linkingStatically, linkShared, result); } return result; } private CcLinkParams lookup(boolean linkingStatically, boolean linkShared) { if (linkingStatically) { return linkShared ? staticModeParamsForDynamicLibrary : staticModeParamsForExecutable; } else { return linkShared ? dynamicModeParamsForDynamicLibrary : dynamicModeParamsForExecutable; } } private void put(boolean linkingStatically, boolean linkShared, CcLinkParams params) { Preconditions.checkNotNull(params); if (linkingStatically) { if (linkShared) { staticModeParamsForDynamicLibrary = params; } else { staticModeParamsForExecutable = params; } } else { if (linkShared) { dynamicModeParamsForDynamicLibrary = params; } else { dynamicModeParamsForExecutable = params; } } } /** * Hook for building the actual link params. * *

Users should override this method and call methods of the builder to * set up the actual CcLinkParams objects. * *

Implementations of this method must not fail or try to report errors on the * configured target. */ protected abstract void collect(CcLinkParams.Builder builder, boolean linkingStatically, boolean linkShared); @AutoCodec @VisibleForSerialization static class EmptyCcLinkParamsStore extends AbstractCcLinkParamsStore { public static final ObjectCodec CODEC = new AbstractCcLinkParamsStore_EmptyCcLinkParamsStore_AutoCodec(); @Override protected void collect( CcLinkParams.Builder builder, boolean linkingStatically, boolean linkShared) {} } /** An empty CcLinkParamStore. */ public static final AbstractCcLinkParamsStore EMPTY = new EmptyCcLinkParamsStore(); }