[英]Function multiple definition linker error building on GCC - Makefile issue
所以我試圖使用Makefile來構建一個項目,而且我對makefile一般來說相對較新。 我在連接函數時遇到了多個定義錯誤,我很確定它是由於我的makefile。 我不能發布大部分項目,因為它非常大,但makefile在下面,有什么突出顯然是錯誤的嗎?
我在頭文件中聲明了+定義了一些函數,並將它們的定義移動到cpp中從鏈接器錯誤中刪除了這些函數 - 但是我不能對所有這些函數執行此操作(編輯:其他正被多次定義的函數不是在標題中,它們在cpp / cc文件中作為標准,說“我不能為所有這些文件執行此操作”暗示它們都是那樣的,抱歉),因為很大一部分是我無法編輯的代碼庫。 代碼中不應該有任何錯誤,因為它在沒有我添加的單獨項目中構建正常(沒有一個導致鏈接器錯誤),所以我認為它必須是我的makefile,但我無法弄清楚我做錯了什么。 有任何想法嗎?
# Compiler
CXX = g++
# Linker settings
LDFLAGS = -lGL -lGLU -lXext -lX11
# Executable name
EXEC = SplotchPreviewer
# Optimizations for compilation
OPTIMIZE = -std=c++98 -pedantic -Wno-long-long -Wfatal-errors -Wextra -Wall -Wstrict-aliasing=2 -Wundef -Wshadow -Wwrite-strings -Wredundant-decls -Woverloaded-virtual -Wcast-qual -Wcast-align -Wpointer-arith -O2 -g
# Pre-processor settings
CPPFLAGS = $(OPTIMIZE) -I. -Icxxsupport -Ic_utils
# Default Splotch objects
OBJS_SPLOTCH_DEFAULT = cxxsupport/error_handling.o reader/mesh_reader.o cxxsupport/mpi_support.o cxxsupport/paramfile.o \
cxxsupport/string_utils.o cxxsupport/announce.o reader/gadget_reader.o reader/millenium_reader.o \
reader/bin_reader.o reader/tipsy_reader.o splotch/splotchutils.o splotch/scenemaker.o \
cxxsupport/walltimer.o c_utils/walltime_c.o booster/mesh_creator.o booster/randomizer.o \
booster/p_selector.o booster/m_rotation.o cxxsupport/paramfile.o cxxsupport/error_handling.o \
c_utils/walltime_c.o cxxsupport/string_utils.o cxxsupport/announce.o \
cxxsupport/walltimer.o
# Default Previewer objects
OBJS_PREVIEWER_DEFAULT = main.o previewer/Previewer.o previewer/libs/core/Parameter.o previewer/libs/core/ParticleSimulation.o \
previewer/libs/core/WindowManager.o previewer/libs/core/Camera.o previewer/libs/core/ParticleData.o \
previewer/libs/core/MathLib.o previewer/libs/core/FileLib.o previewer/libs/events/OnQuitApplicationEvent.o \
previewer/libs/events/OnKeyReleaseEvent.o previewer/libs/events/OnKeyPressEvent.o previewer/libs/events/OnExposedEvent.o \
previewer/libs/events/OnButtonReleaseEvent.o previewer/libs/events/OnButtonPressEvent.o previewer/libs/core/Texture.o \
previewer/libs/animation/AnimationSimulation.o
#temp force render method
RENDER_METHOD = FFSDL
# Current build specific objects
ifeq ($(RENDER_METHOD),FFSDL)
OBJS_BUILD_SPECIFIC = previewer/libs/renderers/FF_DrawList.o previewer/libs/materials/FF_ParticleMaterial.o
endif
# All objects for this build
OBJS = $(OBJS_SPLOTCH_DEFAULT) $(OBJS_PREVIEWER_DEFAULT) $(OBJS_BUILD_SPECIFIC)
# Rules (note: object files automatically removed when building)
.SUFFIXES: .o .cc .cxx .cpp
.cpp.o:
$(CXX) -c $(CPPFLAGS) -o "$@" "$<"
.cc.o:
$(CXX) -c $(CPPFLAGS) -o "$@" "$<"
.cxx.o:
$(CXX) -c $(CPPFLAGS) -o "$@" "$<"
$(EXEC): $(OBJS)
$(CXX) $(OBJS) $(LDFLAGS) -o $(EXEC)
rm $(OBJS)
clean:
rm -f $(OBJS)
rm -f $(EXEC)
我已經刪除了一兩個不必要的東西,因此它中的一兩個沒有多大意義(為什么有一個渲染方法選項,只有一個方法可用)例如我有點模糊我是否正確編寫規則,並且圖這可以解釋我的問題? 雖然它看起來像其他makefile一樣似乎工作,所以我不知道是什么問題。 任何人都有任何想法? 如有必要,我可以提供更多信息嗎?
我在頭文件中聲明了+定義了一些函數,並將它們的定義移動到cpp中,從鏈接器錯誤中刪除了這些函數
聽起來它們不是內聯的,在這種情況下,在鏈接程序時只允許單個定義。
將inline
添加到標頭中的任何函數定義以解決問題。 這放寬了“一個定義規則”以允許在多個翻譯單元中定義這些功能,只要所有定義相同即可。
更新:此外,您對OBJS_SPLOTCH_DEFAULT
的定義包含重復項; 重復cxxsupport/paramfile.o
,可能還有其他人。 您需要刪除重復項。 我建議按字母順序保留這樣的長列表,以便更容易搜索和查找重復項。
問題不在makefile中。 它在這里:
我在頭文件中聲明了+定義了一些函數,並將它們的定義移動到cpp中,從鏈接器錯誤中刪除了這些函數 - 但我不能對所有這些函數執行此操作,因為很大一部分是我無法編輯的代碼庫。
問題是,當您在多個源文件中包含該標頭時,您將獲得多個函數定義副本,這就是鏈接器所抱怨的內容。 所以你有三個選擇:不要使用那些代碼(嚴重的:一般來說,這是一個可怕的編碼實踐); 不要在多個源文件中使用該標頭; 或者像@Mike建議的那樣添加內聯。
如果您在.h
文件中定義並聲明了一個函數,那么除非您可以通過編譯選項或使用inline
來減少變量的范圍,否則您將獲得多個定義的符號。
如果你不能重寫這些.h
文件來將例程聲明為inline
,那么一個丑陋的解決方案是創建一個並行的.h
,它只是重新聲明所有這些例程(聲明,介意,也沒有定義)。 你所有的代碼#includes
此平行.h
文件。
您創建一個.c
/ .cpp
文件,其中#includes
來自共享代碼庫的.h
文件。
您鏈接生成的單個.o
,它將來自共享代碼庫的實現公開到您的代碼庫中。
這是丑陋的,而且是黑客,我肯定會使用@ Mike的答案而不是這個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.