You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by zh...@apache.org on 2018/06/27 17:33:02 UTC
[incubator-mxnet] branch master updated: Define build target for
mkldnn lib build to fix 'make clean USE_MKMLDNN=1' issue (#11090)
This is an automated email from the ASF dual-hosted git repository.
zhasheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/master by this push:
new a4f4e76 Define build target for mkldnn lib build to fix 'make clean USE_MKMLDNN=1' issue (#11090)
a4f4e76 is described below
commit a4f4e765e8fa4f5aed32283c3eb21059b7d643ce
Author: Jin Huang <34...@users.noreply.github.com>
AuthorDate: Thu Jun 28 01:32:53 2018 +0800
Define build target for mkldnn lib build to fix 'make clean USE_MKMLDNN=1' issue (#11090)
* Define build target for mkldnn lib build to fix 'make clean USE_MKMLDNN=1' issue
* fix create install dir and other minor issues
* Fix GPU MKLDNN and cpp-package build failure
* Fix issue to only link with full MKL when BLAS is mkl
* simplify logic by removing MKLDNN_ROOT support and some renaming
* retrigger Jenkins
* retrigger Jenkins
* retrigger Jenkins
* retrigger Jenkins
* retrigger Jenkins
---
Makefile | 19 ++++---
mkldnn.mk | 56 +++++++++++++++++++++
prepare_mkl.sh | 108 ----------------------------------------
prepare_mkldnn.sh | 135 --------------------------------------------------
tests/cpp/unittest.mk | 8 +--
5 files changed, 69 insertions(+), 257 deletions(-)
diff --git a/Makefile b/Makefile
index 67aaa7c..df94e44 100644
--- a/Makefile
+++ b/Makefile
@@ -66,13 +66,12 @@ $(warning "USE_MKL2017 is deprecated. We will switch to USE_MKLDNN.")
endif
ifeq ($(USE_MKLDNN), 1)
- RETURN_STRING := $(shell ./prepare_mkldnn.sh $(MKLDNN_ROOT))
- LAST_WORD_INDEX := $(words $(RETURN_STRING))
- # fetch the 2nd last word as MKLDNNROOT
- MKLDNNROOT := $(word $(shell echo $$(($(LAST_WORD_INDEX) - 1))),$(RETURN_STRING))
- MKLROOT := $(lastword $(RETURN_STRING))
+ MKLDNNROOT = $(ROOTDIR)/3rdparty/mkldnn/install
+ MKLROOT = $(ROOTDIR)/3rdparty/mkldnn/install
+ifneq ($(USE_BLAS), mkl)
export USE_MKLML = 1
endif
+endif
include $(TPARTYDIR)/mshadow/make/mshadow.mk
include $(DMLC_CORE)/make/dmlc.mk
@@ -434,11 +433,11 @@ endif
# For quick compile test, used smaller subset
ALLX_DEP= $(ALL_DEP)
-build/src/%.o: src/%.cc
+build/src/%.o: src/%.cc | mkldnn
@mkdir -p $(@D)
$(CXX) -std=c++11 -c $(CFLAGS) -MMD -c $< -o $@
-build/src/%_gpu.o: src/%.cu
+build/src/%_gpu.o: src/%.cu | mkldnn
@mkdir -p $(@D)
$(NVCC) $(NVCCFLAGS) $(CUDA_ARCH) -Xcompiler "$(CFLAGS)" -M -MT build/src/$*_gpu.o $< >build/src/$*_gpu.d
$(NVCC) -c -o $@ $(NVCCFLAGS) $(CUDA_ARCH) -Xcompiler "$(CFLAGS)" $<
@@ -507,6 +506,7 @@ ifeq ($(USE_CPP_PACKAGE), 1)
include cpp-package/cpp-package.mk
endif
+include mkldnn.mk
include tests/cpp/unittest.mk
extra-packages: $(EXTRA_PACKAGES)
@@ -619,10 +619,9 @@ clean: cyclean $(EXTRA_PACKAGES_CLEAN)
$(RM) -r $(patsubst %, %/*.d, $(EXTRA_OPERATORS)) $(patsubst %, %/*/*.d, $(EXTRA_OPERATORS))
$(RM) -r $(patsubst %, %/*.o, $(EXTRA_OPERATORS)) $(patsubst %, %/*/*.o, $(EXTRA_OPERATORS))
else
-clean: cyclean testclean $(EXTRA_PACKAGES_CLEAN)
+clean: mkldnn_clean cyclean testclean $(EXTRA_PACKAGES_CLEAN)
$(RM) -r build lib bin *~ */*~ */*/*~ */*/*/*~ R-package/NAMESPACE R-package/man R-package/R/mxnet_generated.R \
- R-package/inst R-package/src/image_recordio.h R-package/src/*.o R-package/src/*.so mxnet_*.tar.gz \
- 3rdparty/mkldnn/install/*
+ R-package/inst R-package/src/image_recordio.h R-package/src/*.o R-package/src/*.so mxnet_*.tar.gz
cd $(DMLC_CORE); $(MAKE) clean; cd -
cd $(PS_PATH); $(MAKE) clean; cd -
cd $(NNVM_PATH); $(MAKE) clean; cd -
diff --git a/mkldnn.mk b/mkldnn.mk
new file mode 100644
index 0000000..f17fdbc
--- /dev/null
+++ b/mkldnn.mk
@@ -0,0 +1,56 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+ifeq ($(USE_MKLDNN), 1)
+ MKLDNN_SUBMODDIR = $(ROOTDIR)/3rdparty/mkldnn
+ MKLDNN_BUILDDIR = $(MKLDNN_SUBMODDIR)/build
+ MXNET_LIBDIR = $(ROOTDIR)/lib
+ifeq ($(UNAME_S), Darwin)
+ OMP_LIBFILE = $(MKLDNNROOT)/lib/libiomp5.dylib
+ MKLML_LIBFILE = $(MKLDNNROOT)/lib/libmklml.dylib
+ MKLDNN_LIBFILE = $(MKLDNNROOT)/lib/libmkldnn.0.dylib
+else
+ OMP_LIBFILE = $(MKLDNNROOT)/lib/libiomp5.so
+ MKLML_LIBFILE = $(MKLDNNROOT)/lib/libmklml_intel.so
+ MKLDNN_LIBFILE = $(MKLDNNROOT)/lib/libmkldnn.so.0
+endif
+endif
+
+.PHONY: mkldnn mkldnn_clean
+
+mkldnn_build: $(MKLDNNROOT)/lib/libmkldnn.so
+
+$(MKLDNNROOT)/lib/libmkldnn.so:
+ mkdir -p $(MKLDNNROOT)
+ cd $(MKLDNN_SUBMODDIR) && rm -rf external && cd scripts && ./prepare_mkl.sh && cd .. && cp -a external/*/* $(MKLDNNROOT)/.
+ cmake $(MKLDNN_SUBMODDIR) -DCMAKE_INSTALL_PREFIX=$(MKLDNNROOT) -B$(MKLDNN_BUILDDIR) -DARCH_OPT_FLAGS="-mtune=generic" -DWITH_TEST=OFF -DWITH_EXAMPLE=OFF
+ $(MAKE) -C $(MKLDNN_BUILDDIR) VERBOSE=1
+ $(MAKE) -C $(MKLDNN_BUILDDIR) install
+ mkdir -p $(MXNET_LIBDIR)
+ cp $(OMP_LIBFILE) $(MXNET_LIBDIR)
+ cp $(MKLML_LIBFILE) $(MXNET_LIBDIR)
+ cp $(MKLDNN_LIBFILE) $(MXNET_LIBDIR)
+
+mkldnn_clean:
+ $(RM) -r 3rdparty/mkldnn/build
+ $(RM) -r 3rdparty/mkldnn/install/*
+
+ifeq ($(USE_MKLDNN), 1)
+mkldnn: mkldnn_build
+else
+mkldnn:
+endif
diff --git a/prepare_mkl.sh b/prepare_mkl.sh
deleted file mode 100755
index b702b06..0000000
--- a/prepare_mkl.sh
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/bin/bash
-
-# set -ex
-#
-# All modification made by Intel Corporation: © 2016 Intel Corporation
-#
-# All contributions by the University of California:
-# Copyright (c) 2014, 2015, The Regents of the University of California (Regents)
-# All rights reserved.
-#
-# All other contributions:
-# Copyright (c) 2014, 2015, the respective contributors
-# All rights reserved.
-# For the list of contributors go to https://github.com/BVLC/caffe/blob/master/CONTRIBUTORS.md
-#
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of Intel Corporation nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-GetVersionName()
-{
-VERSION_LINE=0
-if [ $1 ]; then
- VERSION_LINE=`grep __INTEL_MKL_BUILD_DATE $1/include/mkl_version.h 2>/dev/null | sed -e 's/.* //'`
-fi
-if [ -z $VERSION_LINE ]; then
- VERSION_LINE=0
-fi
-echo $VERSION_LINE # Return Version Line
-}
-
-# MKL
-HOME_MKL=$1
-if [ ! -d "$HOME_MKL" ]; then
- mkdir $HOME_MKL
-fi
-MXNET_ROOT=`dirname $0`
-USE_MKLML=0
-# NOTE: if you update the following line, please also update the dockerfile at
-# tests/ci_build/Dockerfile.mkl
-VERSION_MATCH=20180406
-PLATFORM=$(uname)
-if [ $PLATFORM == "Darwin" ]; then
- INFIX=mac
-elif [ $PLATFORM == "Linux" ]; then
- INFIX=lnx
-fi
-ARCHIVE_BASENAME=mklml_${INFIX}_2018.0.3.${VERSION_MATCH}.tgz
-MKL_CONTENT_DIR=`echo $ARCHIVE_BASENAME | rev | cut -d "." -f 2- | rev`
-MKLURL="https://github.com/intel/mkl-dnn/releases/download/v0.14/$ARCHIVE_BASENAME"
-# there are diffrent MKL lib to be used for GCC and for ICC
-reg='^[0-9]+$'
-VERSION_LINE=`GetVersionName $MKLROOT`
-#echo $VERSION_LINE
-# Check if MKLROOT is set if positive then set one will be used..
-if [ -z $MKLROOT ]; then
- # ..if MKLROOT is not set then check if we have MKL downloaded in proper version
- VERSION_LINE=`GetVersionName $HOME_MKL`
- #echo $VERSION_LINE
- if [ $VERSION_LINE -lt $VERSION_MATCH ] ; then
- #...If it is not then downloaded and unpacked
- if [ $PLATFORM == "Darwin" ]; then
- curl -L -o $MXNET_ROOT/$ARCHIVE_BASENAME $MKLURL
- elif [ $PLATFORM == "Linux" ]; then
- wget --quiet --no-check-certificate -P $MXNET_ROOT $MKLURL -O $MXNET_ROOT/$ARCHIVE_BASENAME
- fi
- tar -xzf $MXNET_ROOT/$ARCHIVE_BASENAME -C $MXNET_ROOT
- #echo $HOME_MKL
- yes | cp -rf $MXNET_ROOT/$MKL_CONTENT_DIR/* $HOME_MKL
- rm -rf $MXNET_ROOT/$MKL_CONTENT_DIR
- fi
- if [ $PLATFORM == "Darwin" ]; then
- MKLLIB=`find $HOME_MKL -name libmklml.dylib`
- elif [ $PLATFORM == "Linux" ]; then
- MKLLIB=`find $HOME_MKL -name libmklml_gnu.so`
- fi
- MKLROOT=`echo $MKLLIB | sed -e 's/lib.*$//'`
-fi
-
-# Check what MKL lib we have in MKLROOT
-if [ -z `find $MKLROOT \( -name libmklml_gnu.so -o -name libmklml.dylib \) -print -quit` ]; then
- USE_MKLML=0
-elif [ -z `find $MKLROOT -name libmkl_core.so -print -quit` ]; then
- USE_MKLML=1
-fi
-
-# return value to calling script (Makefile,cmake)
-echo $MKLROOT $USE_MKLML
diff --git a/prepare_mkldnn.sh b/prepare_mkldnn.sh
deleted file mode 100755
index b8d5c7e..0000000
--- a/prepare_mkldnn.sh
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/bin/bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you 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.
-
-# set -ex
-#
-# All modification made by Intel Corporation: © 2016 Intel Corporation
-#
-# All contributions by the University of California:
-# Copyright (c) 2014, 2015, The Regents of the University of California (Regents)
-# All rights reserved.
-#
-# All other contributions:
-# Copyright (c) 2014, 2015, the respective contributors
-# All rights reserved.
-# For the list of contributors go to https://github.com/BVLC/caffe/blob/master/CONTRIBUTORS.md
-#
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# * Neither the name of Intel Corporation nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-MXNET_ROOTDIR="$(pwd)"
-MKLDNN_ROOTDIR="$MXNET_ROOTDIR/3rdparty/mkldnn/"
-MKLDNN_SRCDIR="$MKLDNN_ROOTDIR/src"
-MKLDNN_BUILDDIR="$MKLDNN_ROOTDIR/build"
-MKLDNN_INSTALLDIR="$MKLDNN_ROOTDIR/install"
-MKLDNN_LIBDIR="$MXNET_ROOTDIR/lib"
-
-# MKLDNN install destination
-HOME_MKLDNN=$1
-if [ ! -z "$HOME_MKLDNN" ]; then
- mkdir -p $HOME_MKLDNN
- if [ ! -w $HOME_MKLDNN ]; then
- echo "MKLDNN install to $HOME_MKLDNN failed, please try with sudo" >&2
- exit 1
- fi
-fi
-
-if [ $(uname) == "Darwin" ]; then
- OMP_LIBFILE="$MKLDNN_INSTALLDIR/lib/libiomp5.dylib"
- MKLML_LIBFILE="$MKLDNN_INSTALLDIR/lib/libmklml.dylib"
- MKLDNN_LIBFILE="$MKLDNN_INSTALLDIR/lib/libmkldnn.0.dylib"
-else
- OMP_LIBFILE="$MKLDNN_INSTALLDIR/lib/libiomp5.so"
- MKLML_LIBFILE="$MKLDNN_INSTALLDIR/lib/libmklml_intel.so"
- MKLDNN_LIBFILE="$MKLDNN_INSTALLDIR/lib/libmkldnn.so.0"
-fi
-
-if [ -z $MKLDNNROOT ]; then
-if [ ! -f $MKLDNN_LIBFILE ]; then
- mkdir -p $MKLDNN_INSTALLDIR
- cd $MKLDNN_ROOTDIR
- if [ -z $MKLROOT ] && [ ! -f $MKLDNN_INSTALLDIR/include/mkl_cblas.h ]; then
- rm -rf external && cd scripts && ./prepare_mkl.sh >&2 && cd ..
- cp -a external/*/* $MKLDNN_INSTALLDIR/.
- fi
- echo "Building MKLDNN ..." >&2
- cd $MXNET_ROOTDIR
- g++ --version >&2
- cmake $MKLDNN_ROOTDIR -DCMAKE_INSTALL_PREFIX=$MKLDNN_INSTALLDIR -B$MKLDNN_BUILDDIR -DARCH_OPT_FLAGS="-mtune=generic" -DWITH_TEST=OFF -DWITH_EXAMPLE=OFF >&2
- NUM_PROC=1
- if [[ ! -z $(command -v nproc) ]]; then
- NUM_PROC=$(nproc)
- elif [[ ! -z $(command -v sysctl) ]]; then
- NUM_PROC=$(sysctl -n hw.ncpu)
- else
- >&2 echo "Can't discover number of cores."
- fi
- make -C $MKLDNN_BUILDDIR -j${NUM_PROC} VERBOSE=1 >&2
-
- make -C $MKLDNN_BUILDDIR install >&2
- rm -rf $MKLDNN_BUILDDIR
- mkdir -p $MKLDNN_LIBDIR
- cp $OMP_LIBFILE $MKLDNN_LIBDIR
- cp $MKLML_LIBFILE $MKLDNN_LIBDIR
- cp $MKLDNN_LIBFILE $MKLDNN_LIBDIR
-fi
-MKLDNNROOT=$MKLDNN_INSTALLDIR
-fi
-
-if [ -z $MKLROOT ] && [ -f $MKLDNNROOT/include/mkl_cblas.h ]; then
- MKLROOT=$MKLDNNROOT;
-fi
-
-# user specified MKLDNN install folder
-if [ -d "$HOME_MKLDNN" ]; then
- # skip if user specificed MKLDNNROOT
- [ "$MKLDNNROOT" != "$HOME_MKLDNN" ] && rsync -a $MKLDNNROOT/include $MKLDNNROOT/lib $HOME_MKLDNN/.
- [ "$MKLROOT" != "$HOME_MKLDNN" ] && rsync -a $MKLROOT/include $MKLROOT/lib $HOME_MKLDNN/.
- # update ldconfig if possible
- if [ -w /etc/ld.so.conf.d ]; then
- echo "$HOME_MKLDNN/lib" > /etc/ld.so.conf.d/mxnmkldnn.conf && ldconfig
- fi
-# return value to calling script (Makefile,cmake)
- echo $HOME_MKLDNN $HOME_MKLDNN
-else
- echo $MKLDNNROOT $MKLROOT
-fi
-
diff --git a/tests/cpp/unittest.mk b/tests/cpp/unittest.mk
index 665ce69..746ee2f 100644
--- a/tests/cpp/unittest.mk
+++ b/tests/cpp/unittest.mk
@@ -41,22 +41,22 @@ gtest-all.o : $(GTEST_SRCS_)
gtest.a : gtest-all.o
$(AR) $(ARFLAGS) $@ $^
-build/tests/cpp/%.o : tests/cpp/%.cc
+build/tests/cpp/%.o : tests/cpp/%.cc | mkldnn
@mkdir -p $(@D)
$(CXX) -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -MM -MT tests/cpp/$* $< > build/tests/cpp/$*.d
$(CXX) -c -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -o build/tests/cpp/$*.o $(filter %.cc %.a, $^)
-build/tests/cpp/operator/%.o : tests/cpp/operator/%.cc
+build/tests/cpp/operator/%.o : tests/cpp/operator/%.cc | mkldnn
@mkdir -p $(@D)
$(CXX) -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -MM -MT tests/cpp/operator/$* $< > build/tests/cpp/operator/$*.d
$(CXX) -c -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -o build/tests/cpp/operator/$*.o $(filter %.cc %.a, $^)
-build/tests/cpp/storage/%.o : tests/cpp/storage/%.cc
+build/tests/cpp/storage/%.o : tests/cpp/storage/%.cc | mkldnn
@mkdir -p $(@D)
$(CXX) -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -MM -MT tests/cpp/storage/$* $< > build/tests/cpp/storage/$*.d
$(CXX) -c -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -o build/tests/cpp/storage/$*.o $(filter %.cc %.a, $^)
-build/tests/cpp/engine/%.o : tests/cpp/engine/%.cc
+build/tests/cpp/engine/%.o : tests/cpp/engine/%.cc | mkldnn
@mkdir -p $(@D)
$(CXX) -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -MM -MT tests/cpp/engine/$* $< > build/tests/cpp/engine/$*.d
$(CXX) -c -std=c++11 $(TEST_CFLAGS) -I$(GTEST_INC) -o build/tests/cpp/engine/$*.o $(filter %.cc %.a, $^)