2

I'm attempting to use CMake for the first time and meeting with little success. My CMakeLists.txt is:

# Sets the version of CMake that is required.
cmake_minimum_required(VERSION 2.8.10)

# Name of the project.
project(QTCODERLIB)

# Adds common directories to the build.
include_directories(/usr/local/include)
link_directories(/usr/local/lib)

# Check for header files that we depend on.
include(CheckIncludeFiles)
check_include_files(libavcodec/avcodec.h HAVE_AVCODEC_H)

# Adds all of the source files.
file(GLOB SOURCE RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cxx)

# Builds a library named `qtcoder` from source.
add_library(qtcoder SHARED ${SOURCE})

# Links the library against third-party dependencies.
target_link_libraries(qtcoder avcodec)

My test.cxx file is:

#include "config.h"
#include <libavcodec/avcodec.h>

void f(void) {
  avcodec_register_all();
}

cmake . && make VERBOSE=1 results in this:

/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -H/Users/phowes/Personal/QTCoder/QTCoderLib -B/Users/phowes/Personal/QTCoder/QTCoderLib --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_progress_start /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make -f CMakeFiles/qtcoder.dir/build.make CMakeFiles/qtcoder.dir/depend
cd /Users/phowes/Personal/QTCoder/QTCoderLib && /usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles/qtcoder.dir/DependInfo.cmake --color=
make -f CMakeFiles/qtcoder.dir/build.make CMakeFiles/qtcoder.dir/build
/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_progress_report /Users/phowes/Personal/QTCoder/QTCoderLib/CMakeFiles 1
[100%] Building CXX object CMakeFiles/qtcoder.dir/test.cxx.o
/usr/bin/c++   -Dqtcoder_EXPORTS -fPIC -I/usr/local/include    -o CMakeFiles/qtcoder.dir/test.cxx.o -c /Users/phowes/Personal/QTCoder/QTCoderLib/test.cxx
Linking CXX shared library libqtcoder.dylib
/usr/local/Cellar/cmake/2.8.10.1/bin/cmake -E cmake_link_script CMakeFiles/qtcoder.dir/link.txt --verbose=1
/usr/bin/c++   -dynamiclib -Wl,-headerpad_max_install_names   -o libqtcoder.dylib -install_name /Users/phowes/Personal/QTCoder/QTCoderLib/libqtcoder.dylib CMakeFiles/qtcoder.dir/test.cxx.o  -L/usr/local/lib -lavcodec 
Undefined symbols for architecture x86_64:
  "avcodec_register_all()", referenced from:
      f() in test.cxx.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libqtcoder.dylib] Error 1
make[1]: *** [CMakeFiles/qtcoder.dir/all] Error 2
make: *** [all] Error 2

Both the object file and the library are compiled as 64-bit:

$ lipo -info CMakeFiles/qtcoder.dir/test.cxx.o
Non-fat file: CMakeFiles/qtcoder.dir/test.cxx.o is architecture: x86_64

$ lipo -info /usr/local/lib/libavcodec.dylib
Non-fat file: /usr/local/lib/libavcodec.dylib is architecture: x86_64

The function exists in the library:

$ nm /usr/local/lib/libavcodec.dylib | grep avcodec_register_all
0000000000033c01 T _avcodec_register_all

What am I doing wrong here?

Paul
  • 2,698
  • 22
  • 27
  • 2
    `ld: symbol(s) not found for architecture x86_64` perhaps you have only the 32-bit library? – Daniel Fischer Dec 19 '12 at 20:12
  • As Daniel points out the error indicates that you are attempting to link the 32 bit libraries to a 64 bit application. If you already have the 64 bit libraries installed under lib64 then the find modules that Tom Kerr discussed might help. If you want to force your app to build as 32 bit, related conversation is here: http://www.cmake.org/pipermail/cmake/2011-May/044602.html – Ryan Maloney Dec 19 '12 at 21:06
  • @RyanMaloney I don't think this is the case. `lipo -info` reports both `test.cxx.o` and `/usr/local/lib/libavcodec.dylib` as `architecture: x86_64`. I will update the question with that. – Paul Dec 20 '12 at 13:11
  • 1
    My fault for not looking more closely and misinterpreting the error message. I also overlooked that you were linking with CXX as opposed to C. I believe you'll want to look at the answer to this question: http://stackoverflow.com/questions/4585847/g-linking-error-on-mac-while-compiling-ffmpeg – Ryan Maloney Dec 20 '12 at 13:42
  • Oh just shoot me now... That was it! Thanks @RyanMaloney! Could you post that as an actual answer so that I may accept it? I'd rather you get the credit than self-answering. – Paul Dec 20 '12 at 13:54
  • Glad to see it resolved, answer added. – Ryan Maloney Dec 20 '12 at 14:29

2 Answers2

2

The avcodec libary is a C library and looking at your cmake output you are compiling for CXX. This question addresses how to handle precisely that scenario: g++ Linking Error on Mac while compiling FFMPEG

Community
  • 1
  • 1
Ryan Maloney
  • 552
  • 4
  • 5
1

Usually you'd use find_package to do these sorts of heavy lifting tasks. CMake ships with a lot of modules by default, but sometimes you have to download one for less used projects.

Here is some documentation on how to find libraries.

Here is their contrived example of what you'd expect to see.

cmake_minimum_required(VERSION 2.8)
project(helloworld)
add_executable(helloworld hello.c)
find_package (BZip2)
if (BZIP2_FOUND)
  include_directories(${BZIP_INCLUDE_DIRS})
  target_link_libraries (helloworld ${BZIP2_LIBRARIES})
endif (BZIP2_FOUND)

From simple web searches it isn't clear to me that CMake provides an AVCodec module. I found a few online:

https://github.com/arjanhouben/SDL_ffmpeg/blob/master/Findavcodec.cmake http://whispercast.org/trac/browser/trunk/cmake/FindLibAvCodec.cmake

I see most people using this library are interested in FFMPEG, which maybe is what you are interested too.

https://github.com/zinnschlag/openmw/blob/master/cmake/FindFFMPEG.cmake

If you do need to use one that you download, here are some instructions for how to use custom modoules.

Community
  • 1
  • 1
Tom Kerr
  • 10,444
  • 2
  • 30
  • 46
  • That's awesome! Thanks for the pointer. I'm going to have to play with `find_package` a bit more. I had read some information about it, but didn't completely grok what I saw. – Paul Dec 20 '12 at 13:19