Build external library in subdirectory

Hi,

First, I would like to say I’m new to using CMake to there might be an obvious solution to this that I’m missing.

I’m trying to build zstd to be used in Android with jni with the following CMakeLists.txt. I cloned the repository as a submodule into the zstd folder.

cmake_minimum_required(VERSION 3.9.0)

project(reactnativezstd)

set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 11)

set(ZSTD_BUILD_PROGRAMS OFF) # Avoid  Target "zstd" of type EXECUTABLE may not be linked into another target error
set(ZSTD_LEGACY_SUPPORT OFF)

add_subdirectory(../zstd/build/cmake zstd)

add_library(reactnativezstd
        SHARED
            ../cpp/react-native-zstd.cpp
            cpp-adapter.cpp
        )

target_include_directories(
    reactnativezstd
    PUBLIC
        ../zstd/lib
        ../cpp
)

target_link_libraries(
    reactnativezstd
    PRIVATE
    zstd
)

However I keep getting the same error: ld: error: cannot find -lzstd

Any ideas of what I’m missing?

Here is the full error:

 Build command failed.
  Error while executing process /home/julien/Android/Sdk/cmake/3.10.2.4988404/bin/ninja with arguments {-C /home/julien/Projects/react-native-zstd/android/.cxx/Debug/681tx4bf/armeabi-v7a libzstd_shared reactnativezstd}
  ninja: Entering directory `/home/julien/Projects/react-native-zstd/android/.cxx/Debug/681tx4bf/armeabi-v7a'
  [1/2] Linking CXX shared library ../../../../build/intermediates/cxx/Debug/681tx4bf/obj/armeabi-v7a/libreactnativezstd.so
  FAILED: ../../../../build/intermediates/cxx/Debug/681tx4bf/obj/armeabi-v7a/libreactnativezstd.so 
  : && /home/julien/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=armv7-none-linux-androideabi21 --gcc-toolchain=/home/julien/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/julien/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fPIC -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security  -O2 -frtti -fexceptions -Wall -fstack-protector-all -O0 -fno-limit-debug-info  -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -shared -Wl,-soname,libreactnativezstd.so -o ../../../../build/intermediates/cxx/Debug/681tx4bf/obj/armeabi-v7a/libreactnativezstd.so CMakeFiles/reactnativezstd.dir/home/julien/Projects/react-native-zstd/cpp/react-native-zstd.cpp.o CMakeFiles/reactnativezstd.dir/cpp-adapter.cpp.o  -lzstd -latomic -lm && :
  /home/julien/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lzstd
  /home/julien/Projects/react-native-zstd/cpp/react-native-zstd.cpp:15: error: undefined reference to 'ZSTD_compressBound'
  /home/julien/Projects/react-native-zstd/cpp/react-native-zstd.cpp:18: error: undefined reference to 'ZSTD_compress'
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  [2/2] Linking C shared library ../../../../build/intermediates/cxx/Debug/681tx4bf/obj/armeabi-v7a/libzstd.so
  ninja: build stopped: subcommand failed.

Thank you!

zstd is built in its own folder. Linking reactnativezstd is done in a separate folder. The linker doesn’t find zstd, since it’s not in the folder where reactnativezstd is linked.

Hi Alain, thank you for your time.
So what’s the right way to make find zstd? With add_library? Or is it something else?

The line

add_subdirectory(../zstd/build/cmake zstd)

makes all targets of the zstd project build as part of your project. You can make reactnativezstd depend on the right target and CMake will compute what to pass to the linker to make it find the library.

Thanks Alain, I got it working with the following.

cmake_minimum_required(VERSION 3.10.2)

project(reactnativezstd)

set (CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_CXX_STANDARD 11)
#
set(ZSTD_BUILD_PROGRAMS OFF) # Avoid  Target "zstd" of type EXECUTABLE may not be linked into another target error
set(ZSTD_LEGACY_SUPPORT OFF)
set(ZSTD_BUILD_TESTS OFF)

add_subdirectory(../zstd/build/cmake _zstd)
#

add_library(reactnativezstd
            SHARED
            ../cpp/react-native-testlib.cpp
            cpp-adapter.cpp
)

target_include_directories(
    reactnativezstd
    PUBLIC
       ../zstd/lib
        ../cpp
)
#
add_library(libzstd STATIC IMPORTED)
set_property(TARGET libzstd PROPERTY IMPORTED_LOCATION _zstd/lib/libzstd.a)

target_link_libraries(
        reactnativezstd
        PRIVATE
        libzstd
)

Are there some improvements to this file or is it fine as it is?

Why do you not simply use the libzstd_static target?

target_link_libraries(
        reactnativezstd
        PRIVATE
        libzstd_static
)

Hi Claus,
Indeed that works too. I was not aware that I could do that. Does the _static notation work for any library?

Quoting my own comment:

libzstd_static is one of these targets. It is provided by the CMake code of the zstd project. More precisely, it is defined here:

1 Like

I see, thank you for your time!