0
votes

I'm new to CMake and I don't really know what I'm doing ... I am currently trying to link a static library (libavcodec.a) against a shared one (GreenVideo). I keep having errors saying that my functions provided by my static lib are "undefined reference". My CMakeLists.txt looks like this:

PROJECT(GreenVideo)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include/)

link_directories(/home/nde/svn/Visio/trunk/applications/dorsalistaApp/components/GreenVideo/lib)


ADD_LIBRARY( GreenVideo SHARED
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/xvmc.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/vdpau.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/dxva2.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/avcodec.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/avfft.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/dv_profile.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/vaapi.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/vda.h
            ${CMAKE_CURRENT_SOURCE_DIR}/include/libavcodec/version.h

            metadatagen.h metadatagen.cpp

            greenvideofactory.h
            greenvideofactory.cpp
        )



target_link_libraries(GreenVideo /home/nde/svn/Visio/trunk/applications/dorsalistaApp/components/GreenVideo/lib/libavcodec.a)

Is there anything suspicious in the way I'm doing it ?

Regards, Nicolas

1

1 Answers

3
votes

Your static library obviously has some undefined references. Static library does not store the information about how those reference can be resolved, unlike shared library (.so).

In fact, static library is just an arcive, a collection of objecf files (.o).

To fix your issues you must add more link libraries afrer .../ibavcodec.a. All the libraries that libavcodec.a may need, such as for example: c, stdc++, rt etc..

Edit:

Okay, it seems i figured out your problem. It's not with the way you link your library, it's because of the way you include libavcodec's header files.

Where you include header file like:

#include <libavcodec/avcodec.h>

you must do

extern "C" {
#include <libavcodec/avcodec.h>
}

You can also wrap many includes in one extern "C" { ... } like:

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/common.h>
...
}

What's the problem? C++ symbols have name mangling. So your linker looks for C++ symbols in libavcodec.a but those are not there.