c++ - 无法从 SO 文件调用 SO 文件的函数 - C++ makefile
问题描述
我的项目目录是这样的:
- 库
- 垃圾箱
- FooProj
- 生成文件
- foo.h
- foo.cpp
- 酒吧项目
- 生成文件
- 酒吧.h
- 酒吧.cpp
- 主项目
- 生成文件
- 主文件
- 生成文件
FooProj 和 BarProj 是共享库项目(编译为 so 文件)。
问题是当 bar.cpp 从 foo.h(位于不同的共享库中)调用函数时,我在 main.cpp 上遇到编译错误,提示未定义对 foo() 的引用。
g++ -std=c++14 -rdynamic -g -I../FooProj/ -I../BarProj/ -L../libs/ main.cpp -o ../bins/run -lFooProj -lBarProj
../libs//libBarProj.so: undefined reference to `foo()'
collect2: error: ld returned 1 exit status
makefile:5: recipe for target 'all' failed
make[1]: *** [all] Error 1
make[1]: Leaving directory '/builds/test/MainProj'
makefile:2: recipe for target 'all' failed
make: *** [all] Error 2
这是我的编码文件:
//foo.h
#ifndef _FOO_
#define _FOO_
void foo();
#endif
//foo.cpp
#include "foo.h"
#include <iostream>
void foo() { std::cout << "foo" << std::endl; }
FooProj 的生成文件
SHELL = /bin/sh
CXX = g++
CXXFLAGS = -std=c++14 -rdynamic -fPIC -g
LDFLAGS = -shared
TARGET = ../libs/libFooProj.so
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS = $(SOURCES:.cpp=.o)
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
all: $(TARGET)
$(TARGET): $(OBJECTS) $(HEADERS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(HEADERS)
.
//bar.h
#ifndef _BAR_
#define _BAR_
void bar();
#endif
//bar.cpp
#include "bar.h"
#include "foo.h"
#include <iostream>
void bar()
{
std::cout << "bar" << std::endl;
std::cout << "call foo function:" << std::endl;
foo();
}
BarProj 的生成文件
SHELL = /bin/sh
CXX = g++
CXXFLAGS = -std=c++14 -rdynamic -pthread -fPIC -g -L../libs/ -lFooProj -I../FooProj/
LDFLAGS = -shared
TARGET = ../libs/libBarProj.so
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS = $(SOURCES:.cpp=.o)
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
all: $(TARGET)
$(TARGET): $(OBJECTS) $(HEADERS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(HEADERS)
主文件
#include "bar.h"
int main()
{
bar();
return 0;
}
MainProj 的生成文件:
#include "bar.h"
int main()
{
bar();
return 0;
}
整个项目的makefile:
all:
$(MAKE) all -C FooProj/
$(MAKE) all -C BarProj/
$(MAKE) all -C MainProj/
我应该怎么做才能解决这个问题?我不明白为什么我的 BarProj 共享库不能从 FooProj 调用函数。
解决方案
问题出在 BarProj 的 makefile 上。我从 CXXFLAGS 中删除了 -lFooProj 并将其放在行尾:
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(HEADERS)
这解决了问题。
完整的 BarProj 生成文件:
SHELL = /bin/sh
CXX = g++
CXXFLAGS = -std=c++14 -rdynamic -pthread -fPIC -g -L../libs/ -I../FooProj/
LDFLAGS = -shared
TARGET = ../libs/libBarProj.so
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS = $(SOURCES:.cpp=.o)
PREFIX = $(DESTDIR)/usr/local
BINDIR = $(PREFIX)/bin
all: $(TARGET)
$(TARGET): $(OBJECTS) $(HEADERS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJECTS) $(HEADERS) -lFooProj
推荐阅读
- python - Python,捕捉内存错误
- node.js - 循环中的nodejs承诺
- c# - 类之间调用
- c# - 组合 ConcurrentQueue 和 ConcurrentStack
- hibernate - JPA:查询 dsl 错误:java.lang.NoSuchFieldError:LIKE_IC
- php - PHP SQL 将 Select 语句转换为用于数据库插入的变量
- ruby-on-rails - Rails 迁移什么都不做?
- android - 当设备方向从纵向更改为横向时,活动进入循环
- java - spring boot Ojdbc6 类未找到
- jquery - 当我使用 Vue 从 Api 带来 html 内容时,Javascript 没有运行