0

I have a multi-target CMake file where all the targets are building fine on OS X, but when I build the target on Ubuntu Linux, it does not link the system libraries added in target_include_directories.

Here's an example of a target (each target is similar).

set(SOURCE_FILES_TARGET)
set(RELEASE_LIBS iconv m xml2 z icucore resolv curl )
add_executable(TARGET_NAME ${SOURCE_FILES_TARGET)
target_include_directories(TARGET_NAME PRIVATE external_lib1/headers external_lib2/headers )
target_link_libraries(TARGET_NAME ${RELEASE_LIBS})
target_link_libraries(TARGET_NAME ${CMAKE_SOURCE_DIR}/lib1.a)
target_link_libraries(TARGET_NAME ${CMAKE_SOURCE_DIR}/lib2.a)

The libraries are a little different for linux (comparing the .la files), but even one which is the same (xml2) results in undefined reference errors. Also, on OS X the "target_link_libraries" command works as listed above, and with -lxml2 format.

I tried to add the "pthreads" library on linux (as it asked for this, but not on OS X), and the only way I was able to add it was

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")

however, this is a global setting for all targets. Basically, if I put pthread into target_link_libraries it is ignored, just like the rest of them.

How should I best add these libraries to the targets? Maybe I'm missing something on the OS X side and it just happens to work?

user1122069
  • 1,767
  • 1
  • 24
  • 52
  • 1
    You have two different questions (the library problem and the `-pthread` linker flag problem), please keep it to one question per question. – Some programmer dude Dec 04 '17 at 14:27
  • As for the library problem, what *is* your problem? What errors do you get? Can you show us the output of a verbose build (where the commands are shown)? – Some programmer dude Dec 04 '17 at 14:27
  • 1
    If you have undefined reference errors, then your problem comes from the `target_link_libraries()` command, not `target_include_directories()`. – piwi Dec 04 '17 at 14:30
  • `IF(PLATFORM)` as mentioned here: https://stackoverflow.com/a/9160449/2979092 – WLGfx Dec 04 '17 at 14:31
  • Note: https://stackoverflow.com/questions/23250863/difference-between-pthread-and-lpthread-while-compiling – stark Dec 04 '17 at 14:40

1 Answers1

1

Not sure what your problem exactly is, but here some tips that may help you.

Instead of setting the library names and tell you program to compile against them, you should rather try to find the libraries using find_library() and link your program against the variable resulting from the CMake command. That way, CMake may actually tell you if the library is not found.

For example:

find_library(XML2_LIBRARY xml2)
add_executable(TARGET_NAME ${XML2_LIBRARY})

That way, you can provide several possible library names (for example the names may be different depending on the system you are compiling on). Also, you can tell CMake to look into additional directories (eg. CMAKE_LIBRARY_PATH) without changing your CMakeLists.txt.

You should also check for CMake modules that provide configuration for the dependencies you are interested in (CMake 3.7 has a FindLibXml2 module).

For pthread, you should check CMake's FindThreads.

piwi
  • 5,136
  • 2
  • 24
  • 48
  • I think the target_include_directories PRIVATE flag was casing the headers + sources to be compiled. I set to SYSTEM INTERFACE, but now it doesn't find them in the angle brackets. I think I'm making progress, but no way to be sure yet. Tried your suggestion - I have SOURCE_FILES in add_executable where you put the XML library - I can't remove SOURCE_FILES + the alternatives I tried did not validate. – user1122069 Dec 04 '17 at 22:10
  • nvm about the PRIVATE flag comment. I seem to have gotten something working somehow. – user1122069 Dec 04 '17 at 23:08
  • adding depenencies after the library include fixed the problem. I thought that I had tried that, but the multi-targets confused a lot of my tests, and a number of minor issues also confused things. pthreads works just fine now also. – user1122069 Dec 05 '17 at 00:17