【问题标题】:Adding c++ to complex C makefile将 c++ 添加到复杂的 C makefile
【发布时间】:2018-01-17 08:39:04
【问题描述】:

我想添加一个 cpp 文件来使用 c 函数。我制作了文件,但问题变成了如何将文件包含在makefile中。我所知道的是我应该在C之后用c++编译,然后将它链接在一起。

愿有人指出我正确的方向。

这是testcpp.cpp的sn-p

    extern "C" {
  #include "darknet.h"
}

下面是生成文件,但我不断收到“darknet”需要的没有规则来制作目标“obj/test.cpp”。

    GPU=0
CUDNN=0
OPENCV=0
NNPACK=1
NNPACK_FAST=1
ARM_NEON=1
OPENMP=0
DEBUG=0
QPU_GEMM=1

ARCH= -gencode arch=compute_30,code=sm_30 \
      -gencode arch=compute_35,code=sm_35 \
      -gencode arch=compute_50,code=[sm_50,compute_50] \
      -gencode arch=compute_52,code=[sm_52,compute_52]
#      -gencode arch=compute_20,code=[sm_20,sm_21] \ This one is deprecated?

# This is what I use, uncomment if you know your arch and want to specify
# ARCH= -gencode arch=compute_52,code=compute_52

VPATH=./src/:./examples
SLIB=libdarknet.so
ALIB=libdarknet.a
EXEC=darknet
OBJDIR=./obj/

CC=gcc
NVCC=nvcc 
AR=ar
ARFLAGS=rcs
OPTS=-Ofast
LDFLAGS= -lm -pthread 
COMMON= -Iinclude/ -Isrc/
#CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC
#CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC -march=native -mfpmath=sse
CFLAGS=-Wall -Wno-unknown-pragmas -Wfatal-errors -fPIC -mcpu=cortex-a53


ifeq ($(OPENMP), 1) 
CFLAGS+= -fopenmp
endif

ifeq ($(DEBUG), 1) 
OPTS=-O0 -g
endif

CFLAGS+=$(OPTS)

ifeq ($(OPENCV), 1) 
COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv` 
COMMON+= `pkg-config --cflags opencv` 
endif

ifeq ($(GPU), 1) 
COMMON+= -DGPU -I/usr/local/cuda/include/
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
endif

ifeq ($(CUDNN), 1) 
COMMON+= -DCUDNN 
CFLAGS+= -DCUDNN
LDFLAGS+= -lcudnn
endif

ifeq ($(QPU_GEMM), 1) 
COMMON+= -DQPU_GEMM
CFLAGS+= -DQPU_GEMM
LDFLAGS+= -lqmkl
endif

ifeq ($(NNPACK), 1)
COMMON+= -DNNPACK
CFLAGS+= -DNNPACK
LDFLAGS+= -lnnpack -lpthreadpool
endif

ifeq ($(NNPACK_FAST), 1)
COMMON+= -DNNPACK_FAST
CFLAGS+= -DNNPACK_FAST
endif

ifeq ($(ARM_NEON), 1)
COMMON+= -DARM_NEON
CFLAGS+= -DARM_NEON -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize
endif

OBJ=gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o  lstm_layer.o
EXECOBJA=captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o attention.o darknet.o
EXECOBJA1=testcpp.cpp
ifeq ($(GPU), 1) 
LDFLAGS+= -lstdc++ 
OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o avgpool_layer_kernels.o
endif

EXECOBJ = $(addprefix $(OBJDIR), $(EXECOBJA))
EXECOBJ1 = $(addprefix $(OBJDIR), $(EXECOBJA1))
OBJS = $(addprefix $(OBJDIR), $(OBJ))
DEPS = $(wildcard src/*.h) Makefile include/darknet.h
CPP=g++
#all: obj backup results $(SLIB) $(ALIB) $(EXEC)
all: obj  results $(SLIB) $(ALIB) $(EXEC)


$(EXEC): $(EXECOBJ) $(ALIB)
    $(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(ALIB)

$(EXEC): $(EXECOBJ1)
    $(CPP) -Wall $^ -o $@ $(LDFLAGS)

$(ALIB): $(OBJS)
    $(AR) $(ARFLAGS) $@ $^

$(SLIB): $(OBJS)
    $(CPP) $(CFLAGS) -shared $^ -o $@

$(OBJDIR)%.o: %.c $(DEPS)
    $(CC) $(COMMON) $(CFLAGS) -c $< -o $@

$(OBJDIR)%.o: %.cu $(DEPS)
    $(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@

obj:
    mkdir -p obj
backup:
    mkdir -p backup
results:
    mkdir -p results

.PHONY: clean

clean:
    rm -rf $(OBJS) $(SLIB) $(ALIB) $(EXEC) $(EXECOBJ)

我以为 $(EXEC): $(EXECOBJ1) $(CPP) -Wall $^ -o $@ $(LDFLAGS) 将编译 cpp 文件并

$(OBJDIR)%.o: %.c $(DEPS)
$(CC) $(COMMON) $(CFLAGS) -c $< -o $@

链接一下

【问题讨论】:

  • “它不起作用”不是描述问题的正确方式
  • 为此道歉。我做错了什么,我不知道是什么。有什么帮助吗?
  • 谢谢。刚刚更新。
  • 你的 makefile 显示了很多不相关的东西。但最奇怪的是您如何定义目标文件! :您对它们进行硬编码,而不是从源文件中自动生成它们。查看patsubst make 函数。
  • 您需要了解Makefile。也许将remake-x 一起使用会有所帮助。或者至少make --trace。花点时间阅读documentation of GNU make。而makefile 并没有那么复杂。如果您愿意,可以从头开始重写(或切换到其他一些 build automation 工具,也许是 ninja...)。一定要了解invoke GCC

标签: c++ c makefile


【解决方案1】:

我认为您需要一个配方来从 .cpp 文件编译目标文件:

$(OBJDIR)%.o: %.cpp $(DEPS)
    $(CXX) $(COMMON) $(CFLAGS) -c $< -o $@

您描述的错误可能来自vpath的错误使用:我认为这里没有必要使用它。

但基本上我同意@Basile Starynkevitch 的观点:从头开始重写可能会更好。我有几个建议:

1 - programs(包含 main() 函数的 C 或 C++ 文件)和 library 文件(包含函数的 C 或 C++ 文件)清楚地分开.这对于链接很有用。

例如:

|
+--lib   // holds "library" code
+--app   // holds programs
+--headers
+--BUILD
    |
    +-- obj
    |    |
    |    +-- app
    |    +-- lib
    |
    +-- bin

2 - 从源文件自动生成目标文件和程序:

SRC_FILES_LIB = $(wildcard lib/*.cpp)
SRC_FILES_APP = $(wildcard app/*.cpp)
OBJ_FILES_LIB = $(patsubst lib/%.cpp,BUILD/obj/lib/%.o,$(SRC_FILES_LIB))
OBJ_FILES_APP = $(patsubst app/%.cpp,BUILD/obj/app/%.o,$(SRC_FILES_APP))
EXEC_FILES    = $(patsubst app/%.cpp,BUILD/bin/%,$(SRC_FILES_APP))

3 - 添加构建程序的目标:

all:  $(EXEC_FILES)
    @echo "done"

之后,只需提供足够的模式规则即可。 (抱歉,没时间了)

【讨论】:

  • 仍然没有给我任何规则来定位 obj/test.cpp。没有意义,因为 test.cpp 在 examples/.
猜你喜欢
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 2011-08-15
相关资源
最近更新 更多