我试图在CMAKE的帮助下将一些MSVC项目移植到Linux。 在其中一个库项目中,有一些函数只是声明而不是在任何地方定义或在任何地方使用。 例如:
int fun_a();
int fun_unsed() /*This function is never used in project*/
{
fun_a();
}
现在,当我尝试在Linux中进行make时,我正在观察对声明的函数的未定义引用。但是相同的代码在MSVC上使用相同的CMAKE文件。
我尝试在我的CMAKE文件中使用以下标记(来自here),但它似乎没有帮助。
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)
答案 0 :(得分:2)
如果它们确实未被引用,那么您将无法获得未定义的引用"错误。
链接器错误应告诉您符号的使用位置。
修改:修改后的问题
这可以通过要求编译器将每个函数放入一个单独的部分来解决,因此它们在目标文件中保持分开直到最后一个链接,然后指示链接器丢弃未引用的部分。
根据需要将-ffunction-sections
添加到CFLAGS
和/或CXXFLAGS
,将-Wl,--gc-sections
添加到LDFLAGS
。
链接时优化器(-flto
)也可以这样做,但AFAIK要求启用优化,因此在Debug版本中会失败。
答案 1 :(得分:0)
如果项目中没有该功能的实现,则必须在另一个库中实现。在Visual Studio项目中,右键单击项目,选择“属性”,然后在“链接器”下查看链接的库和链接目录。您将看到至少定义了一个库。然后在CMAKE中,您只需要target_link_libraries
到同一个库。
答案 2 :(得分:0)
正如Simon在回答中所说的那样,删除死亡代码的标志是:
-ffunction-sections
和-Wl,--gc-sections
1
但是,GCC在某些目标(例如X86和64上的Windows和Linux)上不支持ELF文件格式。
我的解决方案是通过使用以下标志来降低所有功能的可见性:
-fvisibility=hidden
和-fvisibility-inlines-hidden
2
所有标记一起删除了链接时间错误。
1 -ffunction-sections
将每个函数放在不同的部分
-Wl,--gc-sections
应该删除所有未使用的部分。
2 此标志将所有功能的可见性从默认(公共)更改为隐藏。因此,链接器现在知道,如果不在可执行文件或库中使用这些功能,则不再需要这些功能,因此可以随意删除它们。