PROJECT := openpose CONFIG_FILE := Makefile.config # Explicitly check for the config file, otherwise make -k will proceed anyway. ifeq ($(wildcard $(CONFIG_FILE)),) $(error $(CONFIG_FILE) not found. See $(CONFIG_FILE).example.) endif include $(CONFIG_FILE) BUILD_DIR_LINK := $(BUILD_DIR) ifeq ($(RELEASE_BUILD_DIR),) RELEASE_BUILD_DIR := .$(BUILD_DIR)_release endif ifeq ($(DEBUG_BUILD_DIR),) DEBUG_BUILD_DIR := .$(BUILD_DIR)_debug endif DEBUG ?= 0 ifeq ($(DEBUG), 1) BUILD_DIR := $(DEBUG_BUILD_DIR) OTHER_BUILD_DIR := $(RELEASE_BUILD_DIR) else BUILD_DIR := $(RELEASE_BUILD_DIR) OTHER_BUILD_DIR := $(DEBUG_BUILD_DIR) endif # All of the directories containing code. SRC_DIRS := $(shell find * -type d -exec bash -c "find {} -maxdepth 1 \ -name '*.cpp' | grep -q ." \; -print) # The target shared library name LIBRARY_NAME := $(PROJECT) LIB_BUILD_DIR := $(BUILD_DIR)/lib STATIC_NAME := $(LIB_BUILD_DIR)/lib$(LIBRARY_NAME).a DYNAMIC_VERSION_MAJOR := 1 DYNAMIC_VERSION_MINOR := 5 DYNAMIC_VERSION_REVISION := 1 DYNAMIC_NAME_SHORT := lib$(LIBRARY_NAME).so #DYNAMIC_SONAME_SHORT := $(DYNAMIC_NAME_SHORT).$(DYNAMIC_VERSION_MAJOR) DYNAMIC_VERSIONED_NAME_SHORT := $(DYNAMIC_NAME_SHORT).$(DYNAMIC_VERSION_MAJOR).$(DYNAMIC_VERSION_MINOR).$(DYNAMIC_VERSION_REVISION) DYNAMIC_NAME := $(LIB_BUILD_DIR)/$(DYNAMIC_VERSIONED_NAME_SHORT) COMMON_FLAGS += -DOPEN_POSE_VERSION=$(DYNAMIC_VERSION_MAJOR).$(DYNAMIC_VERSION_MINOR).$(DYNAMIC_VERSION_REVISION) ############################## # Enable profiler ############################## PROFILER_ENABLED ?= 0 ifneq ($(PROFILER_ENABLED), 0) COMMON_FLAGS += -DPROFILER_ENABLED=$(PROFILER_ENABLED) endif ############################## # Deep net selection ############################## DEEP_NET ?= caffe # TensorFlow ifeq ($(DEEP_NET), tensorflow) # COMMON_FLAGS += -DUSE_TENSOR_FLOW # Torch else ifeq ($(DEEP_NET), torch) # COMMON_FLAGS += -DUSE_TORCH # Caffe else COMMON_FLAGS += -DUSE_CAFFE LIBRARIES += caffe LDFLAGS += -Wl,-rpath=$(CAFFE_DIR)/lib INCLUDE_DIRS += $(CAFFE_DIR)/include LIBRARY_DIRS += $(CAFFE_DIR)/lib endif # Faster GUI display WITH_OPENCV_WITH_OPENGL ?= 0 ifneq ($(WITH_OPENCV_WITH_OPENGL), 0) COMMON_FLAGS += -DUSE_OPENCV_WITH_OPENGL # FreeGLUT LIBRARIES += glut # LIBRARIES += GLU GL glut endif # 3-D # 3-D renderer WITH_3D_RENDERER ?= 0 ifneq ($(WITH_3D_RENDERER), 0) COMMON_FLAGS += -DUSE_3D_RENDERER # FreeGLUT LIBRARIES += glut # LIBRARIES += GLU GL glut endif # Ceres support WITH_CERES ?= 0 ifneq ($(WITH_CERES), 0) COMMON_FLAGS += -DUSE_CERES # Ceres LIBRARIES += ceres INCLUDE_DIRS += $(EIGEN_DIR) # If Ceres was built with Suitesparse: LIBRARIES += lapack camd amd ccolamd colamd cholmod # If Ceres was built with CXSparse: LIBRARIES += cxsparse # If Ceres was built with OpenMP: LIBRARIES += pthread gomp m CXXFLAGS += -fopenmp LINKFLAGS += -fopenmp endif # Eigen support WITH_EIGEN ?= 0 ifneq ($(WITH_EIGEN), 0) COMMON_FLAGS += -DUSE_EIGEN INCLUDE_DIRS += $(EIGEN_DIR) endif # Spinnaker SDK WITH_FLIR_CAMERA ?= 0 ifneq ($(WITH_FLIR_CAMERA), 0) COMMON_FLAGS += -DUSE_FLIR_CAMERA # Spinnaker SDK LIBRARIES += Spinnaker # INCLUDE_DIRS += $(SPINNAKER_DIR) COMMON_FLAGS += -isystem $(SPINNAKER_DIR) # Remove warnings from this library endif ############################## # Get all source files ############################## # CXX_SRCS are the source files excluding the test ones. # CXX_SRCS := $(shell find src/$(PROJECT) ! -name "test_*.cpp" -name "*.cpp") CXX_SRCS := $(shell find src ! -name "test_*.cpp" -name "*.cpp") # CU_SRCS are the cuda source files # CU_SRCS := $(shell find src/$(PROJECT) ! -name "test_*.cu" -name "*.cu") CU_SRCS := $(shell find src ! -name "test_*.cu" -name "*.cu") # EXAMPLE_SRCS are the source files for the example binaries EXAMPLE_SRCS := $(shell find examples -name "*.cpp") # BUILD_INCLUDE_DIR contains any generated header files we want to include. BUILD_INCLUDE_DIR := $(BUILD_DIR)/src # NONGEN_CXX_SRCS includes all source/header files except those generated # automatically (e.g., by proto). NONGEN_CXX_SRCS := $(shell find \ src/$(PROJECT) \ include/$(PROJECT) \ examples \ -name "*.cpp" -or -name "*.hpp" -or -name "*.cu" -or -name "*.cuh") LINT_SCRIPT := scripts/cpp_lint.py LINT_OUTPUT_DIR := $(BUILD_DIR)/.lint LINT_EXT := lint.txt LINT_OUTPUTS := $(addsuffix .$(LINT_EXT), $(addprefix $(LINT_OUTPUT_DIR)/, $(NONGEN_CXX_SRCS))) EMPTY_LINT_REPORT := $(BUILD_DIR)/.$(LINT_EXT) NONEMPTY_LINT_REPORT := $(BUILD_DIR)/$(LINT_EXT) ############################## # Derive generated files ############################## # The objects corresponding to the source files # These objects will be linked into the final shared library, so we # exclude the example objects. CXX_OBJS := $(addprefix $(BUILD_DIR)/, ${CXX_SRCS:.cpp=.o}) CU_OBJS := $(addprefix $(BUILD_DIR)/cuda/, ${CU_SRCS:.cu=.o}) OBJS := $(CXX_OBJS) $(CU_OBJS) # example objects EXAMPLE_OBJS := $(addprefix $(BUILD_DIR)/, ${EXAMPLE_SRCS:.cpp=.o}) # Output files for automatic dependency generation DEPS := ${EXAMPLE_OBJS:.o=.d} ${CXX_OBJS:.o=.d} ${CU_OBJS:.o=.d} EXAMPLE_BINS := ${EXAMPLE_OBJS:.o=.bin} ############################## # Derive compiler warning dump locations ############################## WARNS_EXT := warnings.txt CXX_WARNS := $(addprefix $(BUILD_DIR)/, ${CXX_SRCS:.cpp=.o.$(WARNS_EXT)}) CU_WARNS := $(addprefix $(BUILD_DIR)/cuda/, ${CU_SRCS:.cu=.o.$(WARNS_EXT)}) EXAMPLE_WARNS := $(addprefix $(BUILD_DIR)/, ${EXAMPLE_SRCS:.cpp=.o.$(WARNS_EXT)}) ALL_CXX_WARNS := $(CXX_WARNS) $(EXAMPLE_WARNS) ALL_CU_WARNS := $(CU_WARNS) ALL_WARNS := $(ALL_CXX_WARNS) $(ALL_CU_WARNS) EMPTY_WARN_REPORT := $(BUILD_DIR)/.$(WARNS_EXT) NONEMPTY_WARN_REPORT := $(BUILD_DIR)/$(WARNS_EXT) ############################## # Derive include and lib directories ############################## CUDA_INCLUDE_DIR := $(CUDA_DIR)/include CUDA_LIB_DIR := # add /lib64 only if it exists ifneq ("$(wildcard $(CUDA_DIR)/lib64)","") CUDA_LIB_DIR += $(CUDA_DIR)/lib64 endif CUDA_LIB_DIR += $(CUDA_DIR)/lib INCLUDE_DIRS += $(BUILD_INCLUDE_DIR) ./src ./include ifeq ($(USE_CUDA), 1) INCLUDE_DIRS += $(CUDA_INCLUDE_DIR) LIBRARY_DIRS += $(CUDA_LIB_DIR) LIBRARIES += cudart cublas curand endif LIBRARIES += glog gflags m hdf5_hl hdf5 # handle IO dependencies USE_LEVELDB ?= 1 USE_LMDB ?= 1 USE_OPENCV ?= 1 ifeq ($(USE_LEVELDB), 1) LIBRARIES += leveldb snappy endif ifeq ($(USE_LMDB), 1) LIBRARIES += lmdb endif ifeq ($(USE_OPENCV), 1) LIBRARIES += opencv_core opencv_highgui opencv_imgproc opencv_objdetect opencv_video opencv_calib3d ifeq ($(OPENCV_VERSION), 3) LIBRARIES += opencv_imgcodecs opencv_videoio # Cuda warping removed for TX2 compatibility (PR #989) # LIBRARIES += opencv_imgcodecs opencv_videoio opencv_cudawarping else LIBRARIES += opencv_contrib opencv_gpu endif endif ############################## # OpenPose extra code: commented ############################## # WARNINGS := -Wall -Wno-sign-compare ############################## # Set build directories ############################## DISTRIBUTE_DIR ?= distribute DISTRIBUTE_SUBDIRS := $(DISTRIBUTE_DIR)/bin $(DISTRIBUTE_DIR)/lib DIST_ALIASES := dist ifneq ($(strip $(DISTRIBUTE_DIR)),distribute) DIST_ALIASES += distribute endif ALL_BUILD_DIRS := $(sort $(BUILD_DIR) $(addprefix $(BUILD_DIR)/, $(SRC_DIRS)) \ $(addprefix $(BUILD_DIR)/cuda/, $(SRC_DIRS)) \ $(LIB_BUILD_DIR) $(LINT_OUTPUT_DIR)) ############################## # Set directory for Doxygen-generated documentation ############################## DOXYGEN_CONFIG_FILE ?= ./.Doxyfile # should be the same as OUTPUT_DIRECTORY in the .Doxyfile DOXYGEN_OUTPUT_DIR ?= ./doxygen DOXYGEN_COMMAND ?= doxygen # All the files that might have Doxygen documentation. DOXYGEN_SOURCES := $(shell find \ src/$(PROJECT) \ include/$(PROJECT) \ examples \ -name "*.cpp" -or -name "*.hpp" -or -name "*.cu" -or -name "*.cuh") DOXYGEN_SOURCES += $(DOXYGEN_CONFIG_FILE) ############################## # OpenPose extra code: added flags ############################## # Automatic dependency generation (nvcc is handled separately) CXXFLAGS += -march=native # Complete build flags. CXXFLAGS += -fopenmp -Wpedantic -Wall -Wextra CXXFLAGS += -Wfatal-errors COMMON_FLAGS += -std=c++11 LINKFLAGS += -fopenmp ############################## # Configure build ############################## # Determine platform UNAME := $(shell uname -s) ifeq ($(UNAME), Linux) LINUX := 1 else ifeq ($(UNAME), Darwin) OSX := 1 OSX_MAJOR_VERSION := $(shell sw_vers -productVersion | cut -f 1 -d .) OSX_MINOR_VERSION := $(shell sw_vers -productVersion | cut -f 2 -d .) endif # Linux ifeq ($(LINUX), 1) CXX ?= /usr/bin/g++ GCCVERSION := $(shell $(CXX) -dumpversion | cut -f1,2 -d.) # We will also explicitly add stdc++ to the link target. LIBRARIES += stdc++ VERSIONFLAGS += -Wl,-soname,$(DYNAMIC_VERSIONED_NAME_SHORT) -Wl,-rpath,$(ORIGIN)/../lib endif # OS X: # clang++ instead of g++ # libstdc++ for NVCC compatibility on OS X >= 10.9 with CUDA < 7.0 ifeq ($(OSX), 1) CXX := /usr/bin/clang++ ifeq ($(USE_CUDA), 1) CUDA_VERSION := $(shell $(CUDA_DIR)/bin/nvcc -V | grep -o 'release [0-9.]*' | tr -d '[a-z ]') ifeq ($(shell echo | awk '{exit $(CUDA_VERSION) < 7.0;}'), 1) CXXFLAGS += -stdlib=libstdc++ LINKFLAGS += -stdlib=libstdc++ endif # clang throws this warning for cuda headers WARNINGS += -Wno-unneeded-internal-declaration # 10.11 strips DYLD_* env vars so link CUDA (rpath is available on 10.5+) OSX_10_OR_LATER := $(shell [ $(OSX_MAJOR_VERSION) -ge 10 ] && echo true) OSX_10_5_OR_LATER := $(shell [ $(OSX_MINOR_VERSION) -ge 5 ] && echo true) ifeq ($(OSX_10_OR_LATER),true) ifeq ($(OSX_10_5_OR_LATER),true) LDFLAGS += -Wl,-rpath,$(CUDA_LIB_DIR) endif endif endif # we need to explicitly ask for the rpath to be obeyed ORIGIN := @loader_path VERSIONFLAGS += -Wl,-install_name,@rpath/$(DYNAMIC_VERSIONED_NAME_SHORT) -Wl,-rpath,$(ORIGIN)/../../build/lib else ORIGIN := \$$ORIGIN endif # Custom compiler ifdef CUSTOM_CXX CXX := $(CUSTOM_CXX) endif # Static linking ifneq (,$(findstring clang++,$(CXX))) STATIC_LINK_COMMAND := -Wl,-force_load $(STATIC_NAME) else ifneq (,$(findstring g++,$(CXX))) STATIC_LINK_COMMAND := -Wl,--whole-archive $(STATIC_NAME) -Wl,--no-whole-archive else # The following line must not be indented with a tab, since we are not inside a target $(error Cannot static link with the $(CXX) compiler) endif # Debugging ifeq ($(DEBUG), 1) COMMON_FLAGS += -DDEBUG -g -O0 NVCCFLAGS += -G else COMMON_FLAGS += -DNDEBUG -O3 endif # configure IO libraries ifeq ($(USE_OPENCV), 1) COMMON_FLAGS += -DUSE_OPENCV endif ifeq ($(USE_LEVELDB), 1) COMMON_FLAGS += -DUSE_LEVELDB endif ifeq ($(USE_LMDB), 1) COMMON_FLAGS += -DUSE_LMDB ifeq ($(ALLOW_LMDB_NOLOCK), 1) COMMON_FLAGS += -DALLOW_LMDB_NOLOCK endif endif # CPU-only configuration ifeq ($(USE_CUDA), 1) COMMON_FLAGS += -DUSE_CUDA else COMMON_FLAGS += -DCPU_ONLY # For Caffe COMMON_FLAGS += -DUSE_CPU_ONLY endif LIBRARY_DIRS += $(LIB_BUILD_DIR) # Automatic dependency generation (nvcc is handled separately) CXXFLAGS += -MMD -MP # Complete build flags. COMMON_FLAGS += $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir)) CXXFLAGS += -pthread -fPIC $(COMMON_FLAGS) $(WARNINGS) NVCCFLAGS += -ccbin=$(CXX) -Xcompiler -fPIC $(COMMON_FLAGS) LINKFLAGS += -pthread -fPIC $(COMMON_FLAGS) $(WARNINGS) USE_PKG_CONFIG ?= 0 ifeq ($(USE_PKG_CONFIG), 1) PKG_CONFIG := $(shell pkg-config opencv --libs) else PKG_CONFIG := endif LDFLAGS += $(foreach librarydir,$(LIBRARY_DIRS),-L$(librarydir)) $(PKG_CONFIG) \ $(foreach library,$(LIBRARIES),-l$(library)) ############################## # Define build targets ############################## .PHONY: all lib clean docs linecount lint lintclean examples $(DIST_ALIASES) \ warn everything all: lib examples lib: $(STATIC_NAME) $(DYNAMIC_NAME) everything: $(EVERYTHING_TARGETS) linecount: cloc --read-lang-def=$(PROJECT).cloc \ src/$(PROJECT) include/$(PROJECT) examples lint: $(EMPTY_LINT_REPORT) lintclean: @ $(RM) -r $(LINT_OUTPUT_DIR) $(EMPTY_LINT_REPORT) $(NONEMPTY_LINT_REPORT) docs: $(DOXYGEN_OUTPUT_DIR) @ cd ./docs ; ln -sfn ../$(DOXYGEN_OUTPUT_DIR)/html doxygen $(DOXYGEN_OUTPUT_DIR): $(DOXYGEN_CONFIG_FILE) $(DOXYGEN_SOURCES) $(DOXYGEN_COMMAND) $(DOXYGEN_CONFIG_FILE) $(EMPTY_LINT_REPORT): $(LINT_OUTPUTS) | $(BUILD_DIR) @ cat $(LINT_OUTPUTS) > $@ @ if [ -s "$@" ]; then \ cat $@; \ mv $@ $(NONEMPTY_LINT_REPORT); \ echo "Found one or more lint errors."; \ exit 1; \ fi; \ $(RM) $(NONEMPTY_LINT_REPORT); \ echo "No lint errors!"; $(LINT_OUTPUTS): $(LINT_OUTPUT_DIR)/%.lint.txt : % $(LINT_SCRIPT) | $(LINT_OUTPUT_DIR) @ mkdir -p $(dir $@) @ python $(LINT_SCRIPT) $< 2>&1 \ | grep -v "^Done processing " \ | grep -v "^Total errors found: 0" \ > $@ \ || true examples: $(EXAMPLE_BINS) warn: $(EMPTY_WARN_REPORT) $(EMPTY_WARN_REPORT): $(ALL_WARNS) | $(BUILD_DIR) @ cat $(ALL_WARNS) > $@ @ if [ -s "$@" ]; then \ cat $@; \ mv $@ $(NONEMPTY_WARN_REPORT); \ echo "Compiler produced one or more warnings."; \ exit 1; \ fi; \ $(RM) $(NONEMPTY_WARN_REPORT); \ echo "No compiler warnings!"; $(ALL_WARNS): %.o.$(WARNS_EXT) : %.o $(BUILD_DIR_LINK): $(BUILD_DIR)/.linked # Create a target ".linked" in this BUILD_DIR to tell Make that the "build" link # is currently correct, then delete the one in the OTHER_BUILD_DIR in case it # exists and $(DEBUG) is toggled later. $(BUILD_DIR)/.linked: @ mkdir -p $(BUILD_DIR) @ $(RM) $(OTHER_BUILD_DIR)/.linked @ $(RM) -r $(BUILD_DIR_LINK) @ ln -s $(BUILD_DIR) $(BUILD_DIR_LINK) @ touch $@ $(ALL_BUILD_DIRS): | $(BUILD_DIR_LINK) @ mkdir -p $@ $(DYNAMIC_NAME): $(OBJS) | $(LIB_BUILD_DIR) @ echo LD -o $@ $(Q)$(CXX) -shared -o $@ $(OBJS) $(VERSIONFLAGS) $(LINKFLAGS) $(LDFLAGS) @ cd $(LIB_BUILD_DIR); rm -f $(DYNAMIC_NAME_SHORT); ln -s $(DYNAMIC_VERSIONED_NAME_SHORT) $(DYNAMIC_NAME_SHORT) $(STATIC_NAME): $(OBJS) | $(LIB_BUILD_DIR) @ echo AR -o $@ $(Q)ar rcs $@ $(OBJS) $(BUILD_DIR)/%.o: %.cpp | $(ALL_BUILD_DIRS) @ echo CXX $< $(Q)$(CXX) $< $(CXXFLAGS) -c -o $@ 2> $@.$(WARNS_EXT) \ || (cat $@.$(WARNS_EXT); exit 1) @ cat $@.$(WARNS_EXT) $(BUILD_DIR)/cuda/%.o: %.cu | $(ALL_BUILD_DIRS) @ echo NVCC $< $(Q)$(CUDA_DIR)/bin/nvcc $(NVCCFLAGS) $(CUDA_ARCH) -M $< -o ${@:.o=.d} \ -odir $(@D) $(Q)$(CUDA_DIR)/bin/nvcc $(NVCCFLAGS) $(CUDA_ARCH) -c $< -o $@ 2> $@.$(WARNS_EXT) \ || (cat $@.$(WARNS_EXT); exit 1) @ cat $@.$(WARNS_EXT) $(EXAMPLE_BINS): %.bin : %.o | $(DYNAMIC_NAME) @ echo CXX/LD -o $@ $(Q)$(CXX) $< -o $@ $(LINKFLAGS) -l$(LIBRARY_NAME) $(LDFLAGS) \ -Wl,-rpath,$(ORIGIN)/../../lib clean: @- $(RM) -rf $(ALL_BUILD_DIRS) @- $(RM) -rf $(OTHER_BUILD_DIR) @- $(RM) -rf $(BUILD_DIR_LINK) @- $(RM) -rf $(DISTRIBUTE_DIR) $(DIST_ALIASES): $(DISTRIBUTE_DIR) $(DISTRIBUTE_DIR): all @ mkdir -p $(DISTRIBUTE_SUBDIRS) # add include cp -r include $(DISTRIBUTE_DIR)/ # add example binaries cp $(EXAMPLE_BINS) $(DISTRIBUTE_DIR)/bin # add libraries cp $(STATIC_NAME) $(DISTRIBUTE_DIR)/lib install -m 644 $(DYNAMIC_NAME) $(DISTRIBUTE_DIR)/lib cd $(DISTRIBUTE_DIR)/lib; rm -f $(DYNAMIC_NAME_SHORT); ln -s $(DYNAMIC_VERSIONED_NAME_SHORT) $(DYNAMIC_NAME_SHORT) -include $(DEPS)