19

I have a question related to CMake in MAC. I make sure that the executable program will link the framework and libraries correctly with the following codes:

link_directories(directory_to_framework_and_libs)
add_executable(program ${FILE_LIST})
target_link_libraries(program framework_name lib1 lib2)

In the first line code, I denote the location where the executable program can search for the framework and libraries. In the third line code, the framework and the libraries will link to the executable program. However, when I compile the xcode.project created from the cmake file with Xcode 4, the project keeps complaining that it cannot find -lframework_name: ld: library not found -lframework_name Any ideas will be appreciated.

feelfree
  • 11,175
  • 20
  • 96
  • 167
  • 2
    It's hard to say what's wrong here without more specific details. In principal, it appears correct. However, I'd recommend avoiding the use of [`link_directories`](http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:link_directories) (see the docs for more info) and use [`find_library`](http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:find_library) instead. This will allow you to pass the full path to the library in the `target_link_libraries` call, and if the library hasn't been found, you'll get an error at CMake configure time rather than at link time. – Fraser Jun 12 '13 at 19:19

5 Answers5

33

You can't link to a framework this way, you have to use find_library as it includes some special handling for frameworks on OSX.

Also, don't use link_directories, CMake use full paths to libraries and it's not needed.

Here's some simple example with AudioUnit:

find_library(AUDIO_UNIT AudioUnit)
if (NOT AUDIO_UNIT)
    message(FATAL_ERROR "AudioUnit not found")
endif()

add_executable(program ${program_SOURCES})
target_link_libraries(program ${AUDIO_UNIT})
heinrich5991
  • 2,694
  • 1
  • 19
  • 26
Guillaume
  • 10,463
  • 1
  • 33
  • 47
  • 1
    Your `if not(...)` should be `if(NOT ...)` I think. – Fraser Jun 12 '13 at 20:41
  • Still not working with CMake 2.8.12, if `program` is actually static library target. In Build Settings Xcode pane, Linker flags remain empty, framework search paths remain empty, in Build Phases pane, no dependency is added, no linkage is added. I observed that in empty project, it is sufficient ot define linker flags and search paths. – lef Mar 25 '14 at 23:03
30

Another solution is as follows:

target_link_libraries(program "-framework CoreFoundation")
target_link_libraries(program "-framework your_frame_work_name")
set_target_properties(program PROPERTIES LINK_FLAGS "-Wl,-F/Library/Frameworks")
Mortennobel
  • 3,383
  • 4
  • 29
  • 46
feelfree
  • 11,175
  • 20
  • 96
  • 167
18

You do not need all this hassle (at least with cmake 2.8.12).

This works fine:

target_link_libraries(program stdc++ "-framework Foundation" "-framework Cocoa" objc)

When CMake sees a link parameter starting with "-", it does not prepend "-l" and passes the argument as-is to the linker (/usr/bin/c++).

You need the quotes for frameworks so that CMake treats the two words as a single entry and does not add "-l" before "Foundation" for example.

Anna B
  • 5,997
  • 5
  • 40
  • 52
  • This is much more in line with standard Apple practice, and since the Apple frameworks are all OS specific anyway (and thus going to be conditionalized for the platform), the more "general" approach mentioned above has no advantages. – brotskydotcom Jun 11 '21 at 04:54
1

For cmake version 3.20.1

https://github.com/Sunbreak/cli-breakpad.trial/blob/1800b187afd5f0c29368196561ddb6b55123d4a0/CMakeLists.txt#L10-L12

if(APPLE)
    find_library(BREAKPAD_CLIENT Breakpad "${CMAKE_CURRENT_SOURCE_DIR}/breakpad/mac/")
    target_link_libraries(cli-breakpad PRIVATE ${BREAKPAD_CLIENT})
Sunbreak
  • 391
  • 3
  • 8
0

For recent versions of CMake,

target_link_libraries(program PRIVATE "-framework framework_name")
Andrew Cheong
  • 29,362
  • 15
  • 90
  • 145