- 主题:g++编译 multiple definition 问题
在msvc下编码没问题,gcc make 一直编译不过,巡大佬指点迷津。
===============================================================
redishelper.h 如下:
#ifndef REDISHELPER_H
#define REDISHELPER_H
#include <string>
#include "hiredis/hiredis.h"
class RedisHelper
{
private:
RedisHelper(std::string ip = "127.0.0.1", int port = 6379);
public:
~RedisHelper() {
redisFree(this->context);
};
public:
bool setCommand(const char *key, const char *value);
private:
std::string ip;
int port;
redisContext* context;
public:
static RedisHelper* instance(){
return p;
}
private:
static RedisHelper* p;
};
#endif // REDISADAPTER_H
===============================================================
redishelper.cpp 如下:
#include <strings.h>
#include <iostream>
#include "redishelper.h"
RedisHelper* RedisHelper::p = new RedisHelper();
RedisHelper::RedisHelper(std::string ip, int port) {
this->ip = ip;
this->port = port;
this->context = redisConnect(ip.c_str(), port);
if (this->context == NULL) {
printf("Connection error: can't allocate redis context !\n");
}
if (this->context->err){
std::cerr << "Error: " << this->context->errstr << std::endl;
redisFree(this->context);
this->context = NULL;
}
}
bool RedisHelper::setCommand(const char *key, const char *value){
if (this->context == NULL) {
printf("Error: context is NULL, cann't set !\n");
return false;
}
redisReply *reply = (redisReply *)redisCommand(this->context, "SET %s %s", key, value);
if (reply == NULL) {
printf("Error: execut command failure!\n");
return false;
}
if (reply->type != REDIS_REPLY_STATUS || strcasecmp(reply->str, "OK")) {
printf("Error: execut command failure! (%s)\n", reply->str);
freeReplyObject(reply);
return false;
}
printf("Set command(%s=%s) success.\n", key, value);
freeReplyObject(reply);
return true;
}
===============================================================
Makefile 如下:
APP:= deepstream-app
CXX=g++
TARGET_DEVICE = $(shell gcc -dumpmachine | cut -f1 -d -)
NVDS_VERSION:=5.0
LIB_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/lib/
APP_INSTALL_DIR?=/opt/nvidia/deepstream/deepstream-$(NVDS_VERSION)/bin/
ifeq ($(TARGET_DEVICE),aarch64)
CFLAGS:= -DPLATFORM_TEGRA
endif
SRCS:= $(wildcard *.c)
#SRCS+= $(wildcard *.cpp)
SRCS+= $(wildcard ../../apps-common/src/*.c)
SRCS+= redishelper.cpp
INCS:= $(wildcard *.h)
INCS+= $(wildcard ./hiredis/*.h)
#INCS+= $(wildcard ../../apps-common/includes/*.h)
#INCS+= $(wildcard ../../../includes/*.h)
ifeq ($(TARGET_DEVICE),aarch64)
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11 json-glib-1.0 opencv4
else
PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11 json-glib-1.0 opencv
endif
OBJS:= $(SRCS:.c=.o)
#OBJS+= $(SRCS:.cpp=.o)
OBJS+= deepstream_nvdsanalytics_meta.o
OBJS+= redishelper.o
CFLAGS+= -I./ -I../../apps-common/includes -I../../../includes -DDS_VERSION_MINOR=0 -DDS_VERSION_MAJOR=5
CFLAGS+= -I/usr/include/gstreamer-1.0
LIBS+= -L$(LIB_INSTALL_DIR) -lnvdsgst_meta -lnvds_meta -lnvdsgst_helper -lnvdsgst_smartrecord -lnvds_utils -lnvds_msgbroker -lm \
-lgstrtspserver-1.0 -lnvbufsurface -lhiredis -ldl -Wl,-rpath,$(LIB_INSTALL_DIR)
CFLAGS+= `pkg-config --cflags $(PKGS)`
LIBS+= `pkg-config --libs $(PKGS)`
all: $(APP)
%.o: %.c $(INCS) Makefile
$(CC) -c -o $@ $(CFLAGS) $<
deepstream_nvdsanalytics_meta.o: deepstream_nvdsanalytics_meta.cpp $(INCS) Makefile
$(CXX) -c -o $@ -Wall -Werror $(CFLAGS) $<
redishelper.o: redishelper.cpp $(INCS) Makefile
$(CXX) -c -o $@ -Wall -Werror $(CFLAGS) $<
$(APP): $(OBJS) Makefile
$(CXX) -o $(APP) $(OBJS) $(LIBS)
install: $(APP)
cp -rv $(APP) $(APP_INSTALL_DIR)
clean:
rm -rf $(OBJS) $(APP)
--
FROM 223.88.88.*
make -n
g++ -o deepstream-app deepstream_app.o deepstream_app_main.o deepstream_app_config_parser.o ../../apps-common/src/deepstream_tracker_bin.o ../../apps-common/src/deepstream_primary_gie_bin.o ../../apps-common/src/deepstream_source_bin.o ../../apps-common/src/deepstream_c2d_msg.o ../../apps-common/src/deepstream_config_file_parser.o ../../apps-common/src/deepstream_common.o ../../apps-common/src/deepstream_sink_bin.o ../../apps-common/src/deepstream_perf.o ../../apps-common/src/deepstream_dewarper_bin.o ../../apps-common/src/deepstream_dsexample.o ../../apps-common/src/deepstream_secondary_gie_bin.o ../../apps-common/src/deepstream_dsanalytics.o ../../apps-common/src/deepstream_tiled_display_bin.o ../../apps-common/src/deepstream_c2d_msg_util.o ../../apps-common/src/deepstream_osd_bin.o ../../apps-common/src/deepstream_streammux.o redishelper.cpp deepstream_nvdsanalytics_meta.o redishelper.o -L/opt/nvidia/deepstream/deepstream-5.0/lib/ -lnvdsgst_meta -lnvds_meta -lnvdsgst_helper -lnvdsgst_smartrecord -lnvds_utils -lnvds_msgbroker -lm -lgstrtspserver-1.0 -lnvbufsurface -lhiredis -ldl -Wl,-rpath,/opt/nvidia/deepstream/deepstream-5.0/lib/ `pkg-config --libs gstreamer-1.0 gstreamer-video-1.0 x11 json-glib-1.0 opencv4`
【 在 libgcc 的大作中提到: 】
: 感觉你makefile写的有问题,链了这个redishhelper.o两次
: 你make -n看一下?
:
: ...................
--
FROM 223.88.88.*
搞定了,果然是这个原因,多谢大佬。另外还有几个问题想请教下:
1)什么时候需要在INCS中添加依赖的头文件?
我把“INCS+= $(wildcard ./hiredis/*.h)”这一行也给屏蔽了,但依然能争取编译。redishelper.cpp中依赖./hiredis/hiredis.h这个头文件,已经在redishelper.cpp中include的了。因此就不太明白,Makefile中的INCS,是需要加入哪些头文件的?按说这些被依赖的头文件都会在.cpp中被显示的include,所以不明白这里的INCS是起什么作用的?
2)“PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11 json-glib-1.0 opencv”这一句话中的包名应该是在某个系统配置文件中定义好的吧?应该是定义了这个包名对应的文件路径是什么,相当于是一个全局宏定义?所以才能在Makefile文件中直接饮用。不知理解是否正确。如果是的话这个定义是在什么位置?
3)“deepstream_nvdsanalytics_meta.o: deepstream_nvdsanalytics_meta.cpp $(INCS) Makefile”这句话中最后的那个Makefile是干什么的,起什么作用?
【 在 ArchLinux 的大作中提到: 】
: 你的链接命令行出现了一次redishelper.cpp,之后又出现了redishelper.o.
:
--
FROM 223.88.88.*
搞定了,果然是这个原因,多谢大佬。另外还有几个问题想请教下:
1)什么时候需要在INCS中添加依赖的头文件?
我把“INCS+= $(wildcard ./hiredis/*.h)”这一行也给屏蔽了,但依然能争取编译。redishelper.cpp中依赖./hiredis/hiredis.h这个头文件,已经在redishelper.cpp中include的了。因此就不太明白,Makefile中的INCS,是需要加入哪些头文件的?按说这些被依赖的头文件都会在.cpp中被显示的include,所以不明白这里的INCS是起什么作用的?
2)“PKGS:= gstreamer-1.0 gstreamer-video-1.0 x11 json-glib-1.0 opencv”这一句话中的包名应该是在某个系统配置文件中定义好的吧?应该是定义了这个包名对应的文件路径是什么,相当于是一个全局宏定义?所以才能在Makefile文件中直接饮用。不知理解是否正确。如果是的话这个定义是在什么位置?
3)“deepstream_nvdsanalytics_meta.o: deepstream_nvdsanalytics_meta.cpp $(INCS) Makefile”这句话中最后的那个Makefile是干什么的,起什么作用?
【 在 z16166 的大作中提到: 】
: 删掉这二者之一试试
: SRCS+= redishelper.cpp
: OBJS+= redishelper.o
--
FROM 223.88.88.*
我是要在既有工程中添加一些新的代码文件,而这个既有工程只有Makefile,工程还稍微有点庞大,也不能利用Makefile直接反向生成cmake或者其它编辑环境所需那种工程(依赖)文件。因此搞得我但凡添加一些代码文件就得手动修改Makefile中,有些新添加的代码对既有工程还有些依赖,很崩溃。
这种情况只能这么搞么,常规办法是什么?或者有什么从Makefile反向生成工程文件的方法?
【 在 z16166 的大作中提到: 】
: Makefile就是依赖关系。
: 搞这个Makefile的人希望当头文件、Makefile自身变动时,重新build对应的文件,依赖里面就写了头文件、Makefile。
: pkg-config是有文档的,对应的每个package有一个配置文件来描述。
: ...................
--
FROM 223.88.88.*
有IDE可以从makefile反向导出工程么?
【 在 z16166 的大作中提到: 】
: 这个makefile看着没什么复杂的
:
: 如果工程要跨平台,可以考虑改成cmake。
: ...................
--来自微水木3.5.10
--
FROM 223.88.88.*