2

I'm pretty new to CMake, but I already encountered an error which I do not understand.

For given reasons, I have the following C++ setup: I have two own static libraries, multiple external static libraries and one executable. My own libraries a defines common stuff and all external libraries are linked into it. My library b defines more special stuff and has library a linked into it. Finally, b is linked into my executable c. Both b and c use functions from different external libraries, which should be visible through a.

I have the following CMakeLists.txt, where I reduced the problem by using only one external library: ZeroC Ice.

Root CMakeLists.txt

cmake_minimum_required (VERSION 3.3.0)
project (myproject)

# some settings
if (CMAKE_COMPILER_IS_GNUCC)
    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCC)
if (CMAKE_COMPILER_IS_GNUCXX)
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmessage-length=0")
endif (CMAKE_COMPILER_IS_GNUCXX)
set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})

# ZeroC Ice
find_package (Ice 3.6.0 REQUIRED COMPONENTS Ice IceUtil)
include_directories (${Ice_INCLUDE_DIRS})

# libraries and executable
add_subdirectory (a)
add_subdirectory (b)
add_subdirectory (c)

CMakeLists.txt for a

set (a_FILES
    stuff.cpp
)
add_library (a STATIC ${a_FILES})

# link to third-party libraries
target_link_libraries (a PUBLIC
    ${Ice_LIBRARIES}
)

CMakeLists.txt for b

set (b_FILES
    more_stuff.cpp
)
add_library (b STATIC ${b_FILES})

# link to a
target_link_libraries (b PUBLIC
    a
)

CMakeLists.txt for c

set (c_FILES
    main.cpp
)
add_executable (c ${c_FILES})

# link to b
target_link_libraries (c PUBLIC
    b
)

In this example, stuff.cpp, more_stuff.cpp and main.cpp use classes from the Ice library. a and strangely even b compile and link without any problem. Only c throws a lot of similar linker errors:

C:/PROGRA~2/ZeroC/ICE-36~1.0/include/Ice/FactoryTableInit.h:27: undefined reference to `_imp___ZN11IceInternal16FactoryTableInitD1Ev'

For me, the CMakeLists.txt setup looks just fine and googleing for days did not change anything. I would appreciate any help!

I'm working on Windows 10 with CMake 3.3.1 and CMake Generator "Eclipse CDT4 - MinGW Makefiles" (g++ version 4.8.1).

Thanks in advance! :)

EDIT:

The g++ linker output for c shows that it tries to link against liba.a libb.a C:/.../ice.lib C:/.../iceutil.lib, which seems just fine to me. Anyways, the undefined reference linker errors occur in header files whose classes are implemented inside of ice.lib, so I don't know what is going wrong here...

2 Answers2

1

a and b are static libraries which are just archieved objects with symbols for external references, no linking happens. c is an executable which finally resolves these symbols and links the dependencies. It doesn't look like CMake transports the Ice library link upwards, you can try to just link her for the executable.

Youka
  • 2,646
  • 21
  • 33
  • Okay, thanks for that information. It's planned that there are many other executables like `c`, and I want to avoid that every executable has to exlicitly link all external libraries. Anyways, when I add `${Ice_LIBRARIES}` to `target_link_libraries` in CMakeLists.txt of `c` and play around with the order of the linked libraries, nothing changes. – justanothercoder Sep 15 '15 at 12:30
  • The question is *why* it doesn't "transport the Ice library link upwards." CMake's usage requirements should make it do exactly that. – Angew is no longer proud of SO Sep 15 '15 at 12:34
  • Good question...I tried to replace the `PUBLIC` in `target_link_libraries` with `LINK_PUBLIC` and already added the `-Wl,--export-all-symbols` linker flag. No idea what I could do more... – justanothercoder Sep 15 '15 at 13:08
-1

I found a "workaround" by myself: Using another CMake generator. By using Visual Studio as underlying compiler and linker, the issue does not appear. It seems like the problem was mixing up .lib and .a libraries. Since the default Ice installation on windows only provides .lib files, I ended up switching to VS and everything worked.