简体   繁体   English

未与GCC和CMAKE一起使用时如何解析未定义的引用

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

I am trying to port some MSVC projects to Linux with help of CMAKE. 我正在尝试借助CMAKE将一些MSVC项目移植到Linux。 In one of the Library project there are some functions which are just declared and not being defined anywhere or used anywhere. 在“图书馆”项目之一中,有些函数只是声明而未在任何地方定义或在任何地方使用。 for ex: 例如:

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

Now when I try to do make in Linux, I am observing undefined reference to the declared functions. 现在,当我尝试在Linux中进行make时,我观察到对声明的函数的未定义引用。 But same code works on MSVC with same CMAKE files. 但是,相同的代码可以在具有相同CMAKE文件的MSVC上运行。

I tried to use below flags in my CMAKE files(from here ), but it doesn't seems to help. 我试图在我的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}" )

am I missing something? 我错过了什么吗?

Below is cmake file for executable 以下是可执行文件的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) 

If they were indeed unreferenced, you wouldn't get an "undefined reference" error. 如果确实没有引用它们,则不会收到“未定义引用”错误。

The linker error should tell you where the symbol is used. 链接器错误应告诉您在何处使用符号。

Edit: revised question 编辑:修改后的问题

This can be worked around by asking the compiler to put each function into a separate section, so they are kept apart inside the object files until the final link, and then instructing the linker to discard sections that are unreferenced. 可以通过要求编译器将每个函数放入一个单独的节中来解决此问题,以便将它们保留在目标文件中直至最终链接,然后指示链接程序丢弃未引用的节。

Add -ffunction-sections to CFLAGS and/or CXXFLAGS as appropriate, and -Wl,--gc-sections to LDFLAGS . 添加-ffunction-sectionsCFLAGS和/或CXXFLAGS酌情和-Wl,--gc-sectionsLDFLAGS

The link-time optimizer ( -flto ) can also do this, but AFAIK requires optimization to be enabled, so it would fail in Debug builds. 链接时优化器( -flto )也可以执行此操作,但是AFAIK需要启用优化,因此在Debug构建中将失败。

If you have no implementation for the function in your project, then it must be implemented in another library. 如果您的项目中没有该功能的实现,则必须在另一个库中实现。 In your visual studio project, right-click on the project, select "Properties", then under "Linker" take a look at the linked libraries and link directories. 在Visual Studio项目中,右键单击该项目,选择“属性”,然后在“链接器”下查看链接的库和链接目录。 You'll see at least one library defined there. 您将至少看到一个在此定义的库。 Then in CMAKE you just need to target_link_libraries to the same lib. 然后在cmake的,你只需要target_link_libraries相同的库。

The flags which remove death code are, as Simon said in his answer: 正如Simon在回答中所说的,删除死亡代码的标志是:

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

But, GCC does not support them in some targets, like Windows and Linux on X86 and 64, with ELF file format. 但是,GCC在某些目标中不支持它们,例如Windows和X86和64上的Linux和ELF文件格式。

My solution was to reduce the visibility of all functions, by also using the following flags: 我的解决方案是通过使用以下标志来减少所有功能的可见性:

-fvisibility=hidden and -fvisibility-inlines-hidden 2 -fvisibility=hidden-fvisibility-inlines-hidden 2

All the flags together, removed the link time error. 所有标记一起删除了链接时间错误。


1 -ffunction-sections puts each function in a different section 1 -ffunction-sections将每个函数放在不同的部分

-Wl,--gc-sections should remove all the sections that are unused. -Wl,--gc-sections应该删除所有未使用的部分。

2 This flags change the visibility of all functions from default (public) to hidden. 2此标志将所有功能的可见性从默认(公共)更改为隐藏。 So the linker now know that the functions are not needed anymore if they are not used inside the executable or library, so it is free to remove them. 因此,链接器现在知道,如果不在可执行文件或库中使用这些功能,则不再需要这些功能,因此可以随意删除它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM