簡體   English   中英

未與GCC和CMAKE一起使用時如何解析未定義的引用

[英]How to resolve undefined reference when they are not used with GCC & CMAKE

我正在嘗試借助CMAKE將一些MSVC項目移植到Linux。 在“圖書館”項目之一中,有些函數只是聲明而未在任何地方定義或在任何地方使用。 例如:

int fun_a();
int fun_unsed() /*This function is never used in project*/
{
    fun_a();
}

現在,當我嘗試在Linux中進行make時,我觀察到對聲明的函數的未定義引用。 但是,相同的代碼可以在具有相同CMAKE文件的MSVC上運行。

我試圖在我的CMAKE文件中使用以下標志(從此處開始 ),但這似乎無濟於事。

SET(GCC_COVERAGE_COMPILE_FLAGS "-unresolved-symbols=ignore-all")
SET(GCC_COVERAGE_LINK_FLAGS    "-unresolved-symbols=ignore-all")

SET( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
SET( CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )

我錯過了什么嗎?

以下是可執行文件的cmake文件

#Add Library Projects to the test application
add_subdirectory ("${PROJECT_BINARY_DIR}/../../src/build/vc/" "${PROJECT_BINARY_DIR}/../../src/build/vc/")


#set additional search paths for libraries
#set(CMAKE_LIBRARY_PATH ${PROJECT_BINARY_DIR}/../../lib/Debug)
  link_directories(${PROJECT_BINARY_DIR}/../../lib ${OPENCV_BUILD}/lib)
  #set ignore undefined & unused functions errors. It seems GCC by defalt looks for them.
  SET(GCC_COVERAGE_LINK_FLAGS    "-unresolved-symbols=ignore-all")
  SET(GCC_COVERAGE_COMPILE_FLAGS "-ffunction-sections")
  SET(GCC_COVERAGE_LINK_FLAGS    "-Wl,-gc-sections -flto")


  SET( CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
  SET( CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )

#Get the exicutable for source files
add_executable (FaceAnalysis ${sources})
  target_link_libraries (FaceAnalysis faceDetect.a libopencv_core.so libopencv_imgproc.so libopencv_imgcodecs.so libopencv_videoio.so libopencv_objdetect.so libopencv_highgui.so libopencv_video.so libopencv_ml.so SDL2)

add_dependencies(FaceAnalysis faceDetect) 

如果確實沒有引用它們,則不會收到“未定義引用”錯誤。

鏈接器錯誤應告訴您在何處使用符號。

編輯:修改后的問題

可以通過要求編譯器將每個函數放入一個單獨的節中來解決此問題,以便將它們保留在目標文件中直至最終鏈接,然后指示鏈接程序丟棄未引用的節。

添加-ffunction-sectionsCFLAGS和/或CXXFLAGS酌情和-Wl,--gc-sectionsLDFLAGS

鏈接時優化器( -flto )也可以執行此操作,但是AFAIK需要啟用優化,因此在Debug構建中將失敗。

如果您的項目中沒有該功能的實現,則必須在另一個庫中實現。 在Visual Studio項目中,右鍵單擊該項目,選擇“屬性”,然后在“鏈接器”下查看鏈接的庫和鏈接目錄。 您將至少看到一個在此定義的庫。 然后在cmake的,你只需要target_link_libraries相同的庫。

正如Simon在回答中所說的,刪除死亡代碼的標志是:

-ffunction-sections-ffunction-sections -Wl,--gc-sections 1

但是,GCC在某些目標中不支持它們,例如Windows和X86和64上的Linux和ELF文件格式。

我的解決方案是通過使用以下標志來減少所有功能的可見性:

-fvisibility=hidden-fvisibility-inlines-hidden 2

所有標記一起刪除了鏈接時間錯誤。


1 -ffunction-sections將每個函數放在不同的部分

-Wl,--gc-sections應該刪除所有未使用的部分。

2此標志將所有功能的可見性從默認(公共)更改為隱藏。 因此,鏈接器現在知道,如果不在可執行文件或庫中使用這些功能,則不再需要這些功能,因此可以隨意刪除它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM