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
  • Hello

    Do you want to include simply a .c and .h file, or are you including a more complex module?

    In the first case you can simply add these files to the /src directory in your project and add them to the build system using the target_sources macro like how it's done with main.c

    In the other case you might find more of the info you need on this page:

    https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/develop/modules.html#integrate-modules-in-zephyr-build-system

    Best regards,

    Einar

  • The image below is what I found in the LWGPS documentation i.e, there are the modules that I want to include. 

    add them to the build system using the target_sources macro like how it's done with main.c

    I did'nt quite understand what you mean by this. Could you explain this with an example? 

    P.S: I pasted the .c and .h files in the CMakesLists.txt as 

    target_sources(app PRIVATE src/lwgps.c)
    target_sources(app PRIVATE src/lwgps_opts.h)

    These are present in the source directory of project as you suggested and I tried accessing them from main.c as 

    #include <lwgps_opts.h>
    I am also attaching the whole file for reference.hello_world_nordic.zip 

    Can you explain more elaborately this time please

  • 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)
    

  • Hi

    You might have to include the CMakeLists.txt file located here:

    https://github.com/MaJerle/lwgps/blob/develop/lwgps/CMakeLists.txt

    It includes an add_library call, which seems to be what your error message says is missing.

    -Einar

  • I tried with that as well, it is still throwing the same error I think this is because of the different arraignments of the LWGPS library and the mylib library that is there in your example which in turn will result in I think different configuration for the make file and the CmakeLists.txt file, Could you please tell me how to include it correctly as I am new to including 3rd party library to the Nrf. 

    Edit : I tried understanding the structure of the 3rd party library : lwgps\src\include has lwgps.h(contains #include "lwgps/lwgps_opt.h" ) and lwgps_opts_template.h (this is the file they asked me to change to lwgps_opts.h and import to my project).

    Add lwgps/src/include folder to include path of your toolchain. This is where C/C++ compiler can find the files during compilation process. Usually using -I flag
    
    Add source files from lwgps/src/ folder to toolchain build. These files are built by C/C++ compiler. CMake configuration comes with the library, allows users to include library in the project as subdirectory and library.
    I don't understand how to do the above things for NRF as this is simply not a .h and .c file and is interleaved.

    So this is an issue that I don't understand how to solve it.

Reply
  • I tried with that as well, it is still throwing the same error I think this is because of the different arraignments of the LWGPS library and the mylib library that is there in your example which in turn will result in I think different configuration for the make file and the CmakeLists.txt file, Could you please tell me how to include it correctly as I am new to including 3rd party library to the Nrf. 

    Edit : I tried understanding the structure of the 3rd party library : lwgps\src\include has lwgps.h(contains #include "lwgps/lwgps_opt.h" ) and lwgps_opts_template.h (this is the file they asked me to change to lwgps_opts.h and import to my project).

    Add lwgps/src/include folder to include path of your toolchain. This is where C/C++ compiler can find the files during compilation process. Usually using -I flag
    
    Add source files from lwgps/src/ folder to toolchain build. These files are built by C/C++ compiler. CMake configuration comes with the library, allows users to include library in the project as subdirectory and library.
    I don't understand how to do the above things for NRF as this is simply not a .h and .c file and is interleaved.

    So this is an issue that I don't understand how to solve it.

Children
No Data
Related