Правильный способ связать статическую библиотеку в общую библиотеку с CMake - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть проект CMake со следующей структурой

root  
 |- common
      |- Bitmap.h
      |- Bitmap.cpp
      |- BytesUtils.h
      |- BytesUtils.cpp
 |- encoding
 |- jni
     |- impl.cpp
 |- main.cpp

Проект создаст два артефакта: исполняемый файл, использующий main.cpp, и разделяемую библиотеку, использующую исходный код в jni / для загрузкиJNI.Они оба используют общие исходные файлы и кодировку.

Вот мой root / CMakeLists.txt

file(GLOB_RECURSE COMMON_SOURCE
    "common/*.h"
    "common/*.cpp"
    )
file(GLOB_RECURSE ENCODING_SOURCE
    "encoding/*.h"
    "encoding/*.cpp"
    )

add_library(common STATIC ${COMMON_SOURCE})
add_library(encoding STATIC ${ENCODING_SOURCE})

add_executable(main main.cpp)
target_link_libraries(main common)
target_link_libraries(main encoding)

add_subdirectory(jni)

, а вот jni / CMakeLists.txt

set(JAVA_HOME "/usr/lib/jvm/jdk1.8.0_221")
#set(JAVA_HOME "/usr/lib/jvm/java-8-openjdk-amd64/")

include_directories(${JAVA_HOME}/include)
include_directories(${JAVA_HOME}/include/linux)

file(GLOB_RECURSE JNI_SOURCE
    "*.h"
    "*.cpp"
    )

add_library(lqf SHARED ${JNI_SOURCE})
target_link_libraries(lqf common)
target_link_libraries(lqf encoding)

Когда я загружаю библиотеку с использованием JNI, я получаю следующую ошибку:

/usr/lib/jvm/jdk1.8.0_221/bin/java: symbol lookup error: /home/harper/git/lqf/lqf-cpp/cmake-build-debug/lib/liblqf.so: undefined symbol: _ZN6common6BitmapC1EPmj

Используя nm, чтобы посмотреть на сгенерированный, я обнаружил, что все функции из общего / Bitmap.cpp помечены как неопределенный символ

 U _ZN6common6Bitmap10appendBitsEhj
 U _ZN6common6Bitmap11moveForwardEj
 U _ZN6common6BitmapC1EPmj

Но функции из другого исходного кода в общем / включены правильно

0000000000002894 T _ZN6common10BytesUtils19readIntLittleEndianEPhPj
00000000000028d0 T _ZN6common10BytesUtils35readIntLittleEndianPaddedOnBitWidthEPhPjh
00000000000029d3 T _ZN6common10BytesUtils18readUnsignedVarIntEPhPj

Единственное различие, которое я вижу, состоит в том, что Bitmap - это класс, а BytesUtils - это набор функций.

Bitmap.h

#include <cstdint>

namespace common {
    class Bitmap {
    public:
        Bitmap(uint64_t *data, uint32_t offset);
        void appendWord(uint64_t *word, uint32_t count);
        void appendBits(uint8_t bit, uint32_t rep);
        void moveForward(uint32_t count);
    };
}

Bitmap.cpp:

#include "Bitmap.h"

common::Bitmap::Bitmap(uint64_t *data, uint32_t offset) {...}
void common::Bitmap::appendBits(uint8_t bit, uint32_t repetition) {...}
void common::Bitmap::appendWord(uint64_t *word, uint32_t count) {...}
void common::Bitmap::moveForward(uint32_t count) {...}

Итак, как правильно построить общую библиотеку, чтобы эти символы были включены?

Обновление @ 24 сентября 2019 г. 21: 32

Это вызвано зависимостями между статическими библиотеками.Библиотека кодирования использует общую библиотеку, но я не смог добавить target_link_libraries между ними.После добавления target_link_libraries(encoding, common) таблицы символов фиксируются.

1 Ответ

1 голос
/ 25 сентября 2019

Это вызвано зависимостями между статическими библиотеками.Библиотека кодирования использует общую библиотеку, но я не смог добавить target_link_libraries между ними.После добавления target_link_libraries(encoding common) таблицы символов фиксируются.

...