繁体   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