1

I am trying to port some MSVC projects to Linux with help of CMAKE. 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. But same code works on MSVC with same CMAKE files.

I tried to use below flags in my CMAKE files(from here), but it doesn't seems to help.

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

#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) 
YSC
  • 38,212
  • 9
  • 96
  • 149
Rama
  • 11
  • 1
  • 4
  • Show precise `CMakeLists.txt`. There is some specific about setting *CMAKE_CXX_FLAGS*. Also, run build process `make V=1`, with that option you may see complete command lines used for compile and link. – Tsyvarev Jun 18 '17 at 20:51
  • 1
    @Tsyvarev added CMakeLists.txt file, make V=1 is not providing any extra information – Rama Jun 18 '17 at 23:06
  • Sorry, I meant `make VERBOSE=1`. Content of your `CMakeLists.txt` looks reasonable, except: 1. You set *GCC_COVERAGE_LINK_FLAGS* variable **twice**, so the second assignment will overwrite the first one. 2. In the first assignment it should be additional dash at the beginning of the value: `--unresolved-symbols=...`. – Tsyvarev Jun 19 '17 at 08:25

3 Answers3

2

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.

The link-time optimizer (-flto) can also do this, but AFAIK requires optimization to be enabled, so it would fail in Debug builds.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
  • I think I did not ask question correctly, I corrected it. the function is referenced, but calling function is not used. – Rama Jun 18 '17 at 17:49
  • Tried mentioned flags for compiler, linker. But still I see error. Even -flto also doesn't seem to work. – Rama Jun 18 '17 at 20:40
  • @Rama Those flags are indeed correct. The problem is that GCC (and I think also Clang, though not sure) do not support those flags on some targets (Windows and Linux, X86 and 64). They support them at least in ARM targets (maybe also in other platforms) – LoPiTaL Jan 24 '19 at 11:01
0

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. You'll see at least one library defined there. Then in CMAKE you just need to target_link_libraries to the same lib.

Stewart
  • 4,356
  • 2
  • 27
  • 59
0

The flags which remove death code are, as Simon said in his answer:

-ffunction-sections and -Wl,--gc-sections1

But, GCC does not support them in some targets, like Windows and Linux on X86 and 64, with ELF file format.

My solution was to reduce the visibility of all functions, by also using the following flags:

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

All the flags together, removed the link time error.


1 -ffunction-sections puts each function in a different section

-Wl,--gc-sections should remove all the sections that are unused.

2 This flags change the visibility of all functions from default (public) to hidden. 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.

LoPiTaL
  • 2,495
  • 16
  • 23