How to add a 3rd party .c and .h file to SDK

I want to include a 3rd party library in the sdk and use it in https://github.com/MaJerle/lwgps which is a library for parsing NMEA messages.

I came across this ticket : from Nordic in which it was stated to add

 

# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(external_lib)

target_sources(app PRIVATE src/main.c)

include(ExternalProject)

# Add an external project to be able download and build the third
# party library. In this case downloading is not necessary as it has
# been committed to the repository.

set(MYLIB_LIB_DIR     ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(MYLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mylib/include)

# Create a wrapper CMake library that our app can link with
add_library(mylib_lib STATIC IMPORTED GLOBAL)
add_dependencies(
  mylib_lib
  mylib_project
  )
set_target_properties(mylib_lib PROPERTIES IMPORTED_LOCATION             ${MYLIB_LIB_DIR}/libmylib.a)
set_target_properties(mylib_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${MYLIB_INCLUDE_DIR})

target_link_libraries(app PUBLIC mylib_lib)

but I don't understand what path should I add and I did'nt understand where to make changes in the above code I pasted. 

I am using Visual studio code, actinius icarus 

SDK :2.3.0

Parents Reply Children
  • LWGPS is the library file I want to include into my helloworld project

  • Well in that case my answer would be the same as in the ticket you linked.

    This sample demonstrates how to do this:

    https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/application_development/external_lib

    In this sample they include the external library "mylib".

    So instead of "mylib" you add lwgps to your application folder, and you change the CMakeLists.txt file accordingly.

    -Einar

  • I followed the example that you posted made changes to the library and got it to the same format and make changes to the CmakeLists.txt and observed in the example about the make,  installed make but it is not coming up in the PATH variable : throwing error: 

    'make' is not recognized as an internal or external command,
    operable program or batch file.
     

    I downloaded the complete setup from the site posted in your example : https://gnuwin32.sourceforge.net/packages/make.htm but still I am not able to get make to work on command prompt of any PATH.

     

    [0/1] Re-running CMake...
    Loading Zephyr default modules (Zephyr base (cached)).
    -- Application: C:/TRIAL/hello_world
    -- Cache files will be written to: C:/ncs/v2.3.0/zephyr/.cache
    -- Zephyr version: 3.2.99 (C:/ncs/v2.3.0/zephyr)
    -- Found west (found suitable version "0.14.0", minimum required is "0.7.1")
    -- Board: actinius_icarus_ns, Revision: 2.0.0
    -- Found host-tools: zephyr 0.15.2 (C:/ncs/toolchains/v2.3.0/opt/zephyr-sdk)
    -- Found toolchain: zephyr 0.15.2 (C:/ncs/toolchains/v2.3.0/opt/zephyr-sdk)
    -- Found BOARD.dts: C:/ncs/v2.3.0/zephyr/boards/arm/actinius_icarus/actinius_icarus_ns.dts
    -- Found devicetree overlay: C:/ncs/v2.3.0/zephyr/boards/arm/actinius_icarus/actinius_icarus_ns_2_0_0.overlay
    -- Generated zephyr.dts: C:/TRIAL/hello_world/build/zephyr/zephyr.dts
    -- Generated devicetree_generated.h: C:/TRIAL/hello_world/build/zephyr/include/generated/devicetree_generated.h
    -- Including generated dts.cmake file: C:/TRIAL/hello_world/build/zephyr/dts.cmake
    Parsing C:/ncs/v2.3.0/zephyr/Kconfig
    Loaded configuration 'C:/TRIAL/hello_world/build/zephyr/.config'
    No change to configuration in 'C:/TRIAL/hello_world/build/zephyr/.config'
    No change to Kconfig header in 'C:/TRIAL/hello_world/build/zephyr/include/generated/autoconf.h'
    Dropping partition 'nrf_modem_lib_trace' since its size is 0.
    Dropping partition 'nonsecure_storage' since it is empty.
    CMake Error at CMakeLists.txt:62 (add_dependencies):
      Cannot add target-level dependencies to non-existent target "lwgps_lib".
    
      The add_dependencies works for top-level logical targets created by the
      add_executable, add_library, or add_custom_target commands.  If you want to
      add file-level dependencies see the DEPENDS option of the add_custom_target
      and add_custom_command commands.
    
    
    -- Configuring incomplete, errors occurred!
    See also "C:/TRIAL/hello_world/build/CMakeFiles/CMakeOutput.log".
    See also "C:/TRIAL/hello_world/build/CMakeFiles/CMakeError.log".
    FAILED: build.ninja 
    C:\ncs\toolchains\v2.3.0\opt\bin\cmake.exe --regenerate-during-build -SC:\TRIAL\hello_world -BC:\TRIAL\hello_world\build
    ninja: error: rebuilding 'build.ninja': subcommand failed
    FATAL ERROR: command exited with status 1: 'C:\ncs\toolchains\v2.3.0\opt\bin\cmake.EXE' --build 'c:\TRIAL\hello_world\build'
    
     *  The terminal process terminated with exit code: 1. 
     *  Terminal will be reused by tasks, press any key to close it. 
    

    Could you please tell me where I am going wrong I attached my Project again.6685.hello_world_nordic.zip

  • Hi

    User_PP said:
    I downloaded the complete setup from the site posted in your example

    Have you added it to your PATH?

    https://stackoverflow.com/questions/4822400/register-an-exe-so-you-can-run-it-from-any-command-line-in-windows

    Once you have Make in your path, make sure you can compile the basic unmodified example before you move on to your modified version.

    -Einar

  • Yes I added it to the PATH, make is working now I tried the library from your example it is building without errors but with my library it is generating the following error: 

    Loading Zephyr default modules (Zephyr base (cached)).
    -- Application: C:/TRIAL/hello_world
    -- Cache files will be written to: C:/ncs/v2.3.0/zephyr/.cache
    -- Zephyr version: 3.2.99 (C:/ncs/v2.3.0/zephyr)
    -- Found west (found suitable version "0.14.0", minimum required is "0.7.1")
    -- Board: actinius_icarus_ns, Revision: 2.0.0
    -- Found host-tools: zephyr 0.15.2 (C:/ncs/toolchains/v2.3.0/opt/zephyr-sdk)
    -- Found toolchain: zephyr 0.15.2 (C:/ncs/toolchains/v2.3.0/opt/zephyr-sdk)
    -- Found BOARD.dts: C:/ncs/v2.3.0/zephyr/boards/arm/actinius_icarus/actinius_icarus_ns.dts
    -- Found devicetree overlay: C:/ncs/v2.3.0/zephyr/boards/arm/actinius_icarus/actinius_icarus_ns_2_0_0.overlay
    -- Generated zephyr.dts: C:/TRIAL/hello_world/build/zephyr/zephyr.dts
    -- Generated devicetree_generated.h: C:/TRIAL/hello_world/build/zephyr/include/generated/devicetree_generated.h
    -- Including generated dts.cmake file: C:/TRIAL/hello_world/build/zephyr/dts.cmake
    Parsing C:/ncs/v2.3.0/zephyr/Kconfig
    Loaded configuration 'C:/TRIAL/hello_world/build/zephyr/.config'
    No change to configuration in 'C:/TRIAL/hello_world/build/zephyr/.config'
    No change to Kconfig header in 'C:/TRIAL/hello_world/build/zephyr/include/generated/autoconf.h'
    Dropping partition 'nrf_modem_lib_trace' since its size is 0.
    Dropping partition 'nonsecure_storage' since it is empty.
    CMake Error at CMakeLists.txt:62 (add_dependencies):
      Cannot add target-level dependencies to non-existent target "lwgps_lib".
    
      The add_dependencies works for top-level logical targets created by the
      add_executable, add_library, or add_custom_target commands.  If you want to
      add file-level dependencies see the DEPENDS option of the add_custom_target
      and add_custom_command commands.
    
    
    -- Configuring incomplete, errors occurred!
    See also "C:/TRIAL/hello_world/build/CMakeFiles/CMakeOutput.log".
    See also "C:/TRIAL/hello_world/build/CMakeFiles/CMakeError.log".
    FAILED: build.ninja 
    C:\ncs\toolchains\v2.3.0\opt\bin\cmake.exe --regenerate-during-build -SC:\TRIAL\hello_world -BC:\TRIAL\hello_world\build
    ninja: error: rebuilding 'build.ninja': subcommand failed
    FATAL ERROR: command exited with status 1: 'C:\ncs\toolchains\v2.3.0\opt\bin\cmake.EXE' --build 'c:\TRIAL\hello_world\build'

    I am not understanding why this error is coming up 

    My CmakeLists.text looks like this : 

    # SPDX-License-Identifier: Apache-2.0
    
    cmake_minimum_required(VERSION 3.20.0)
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(hello_world)
    
    target_sources(app PRIVATE src/main.c)
    
    # The external static library that we are linking with does not know
    # how to build for this platform so we export all the flags used in
    # this zephyr build to the external build system.
    #
    # Other external build systems may be self-contained enough that they
    # do not need any build information from zephyr. Or they may be
    # incompatible with certain zephyr options and need them to be
    # filtered out.
    zephyr_get_include_directories_for_lang_as_string(       C includes)
    zephyr_get_system_include_directories_for_lang_as_string(C system_includes)
    zephyr_get_compile_definitions_for_lang_as_string(       C definitions)
    zephyr_get_compile_options_for_lang_as_string(           C options)
    
    set(external_project_cflags
      "${includes} ${definitions} ${options} ${system_includes}"
      )
    
    include(ExternalProject)
    
    # Add an external project to be able download and build the third
    # party library. In this case downloading is not necessary as it has
    # been committed to the repository.
    set(mylib_src_dir   ${CMAKE_CURRENT_SOURCE_DIR}/lwgps)
    set(mylib_build_dir ${CMAKE_CURRENT_BINARY_DIR}/lwgps)
    
    set(MYLIB_LIB_DIR     ${mylib_build_dir}/lib)
    set(MYLIB_INCLUDE_DIR ${mylib_src_dir}/include)
    
    if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
    # https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html
    set(submake "$(MAKE)")
    else() # Obviously no MAKEFLAGS. Let's hope a "make" can be found somewhere.
    set(submake "make")
    endif()
    
    ExternalProject_Add(
      mylib_project                 # Name for custom target
      PREFIX     ${mylib_build_dir} # Root dir for entire project
      SOURCE_DIR ${mylib_src_dir}
      BINARY_DIR ${mylib_src_dir} # This particular build system is invoked from the root
      CONFIGURE_COMMAND ""    # Skip configuring the project, e.g. with autoconf
      BUILD_COMMAND
      ${submake}
      PREFIX=${mylib_build_dir}
      CC=${CMAKE_C_COMPILER}
      AR=${CMAKE_AR}
      CFLAGS=${external_project_cflags}
      INSTALL_COMMAND ""      # This particular build system has no install command
      BUILD_BYPRODUCTS ${MYLIB_LIB_DIR}/liblwgps.a
      )
    
    # Create a wrapper CMake library that our app can link with
    add_library(mylib_lib STATIC IMPORTED GLOBAL)
    add_dependencies(
      lwgps_lib
      lwgps_project
      )
    set_target_properties(mylib_lib PROPERTIES IMPORTED_LOCATION             ${MYLIB_LIB_DIR}/lwgpslib.a)
    set_target_properties(mylib_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${MYLIB_INCLUDE_DIR})
    
    target_link_libraries(app PUBLIC lwgps_lib)
    

Related