带有静态链接库的CMake未定义引用

时间:2020-08-04 10:35:00

标签: cmake compiler-errors embedded

我对CMake还是陌生的,并试图学习它。我正在尝试使用CMake从IDE编译示例项目。当我尝试链接某些供应商提供的静态库时,会出现问题。

该项目基本上是:

If
在项目根目录中的

CMakeLists.txt

PROJECT_DIR
  source
    main.c
  include
    main.h
  device
    familyfolder
      morefolders
  emlib
    src
      somesource.c
      em_core.c
      ...
    inc
      someheader.h
      em_core.h
      ...
  protocol
    bluetooth/lib
      EFR32BG1P
        libbluetooth.a
        librail.a
        libnvm3.a
        ...
    bluetooth/ble_stack
      src
        host
          gecko_bglib.c
        soc
          ...
      inc
        soc
          native_gecko.h
          someheader1.h
          someheader2.h
          ...
        host
          someheader3.h
        common
          bg_types.h (which is included by native_gecko.h)
          someheader4.h
emp中的

CMakeLists.txt

# Base EFM32 CMake file
#
# This can be used as is as a project base, or by adding the efm32-base
# repository as a submodule to another project, copying this CMakeLists file
# to the top level directory, and updating the BASE_LOCATION variable to reflect this
# change
#
## Copyright (c) 2016 Ryan Kurte
# This file is covered under the MIT license available at: https://opensource.org/licenses/MIT

###### Project Environment #####

# Set minimum CMake version
cmake_minimum_required(VERSION 2.8.4)

# Optional verbose mode, uncomment or pass in -DCMAKE_VERBOSE_MAKEFILE=ON
# set(CMAKE_VERBOSE_MAKEFILE ON)

set(BASE_LOCATION .)

# Set the compiler (must be prior to project setup)
include(${BASE_LOCATION}/toolchain/arm-gcc.cmake)

##### Project Setup #####

# Configure project and languages
project(efm32-test C CXX ASM)

# ${DEVICE} sets the target specific model name
if (NOT DEVICE)
    set(DEVICE EFR32BG1P232F256GM48)
    # set(DEVICE BGM13P22F512GA)
    set(BOARD BRD4100A)
    # set(BLE_LIB EFR32BG13P)
endif ()

# ${JLINK_DEVICE} device model setting specifically for JLink. (Defaults to ${DEVICE} when not set)
# set(JLINK_DEVICE EFM32TG11BXXXF128)

# When ${JLINK_SERVER_IP} is set, JLink will try to connect over IP to a JLink server
# set(JLINK_SERVER_IP 127.0.0.1)

# Set build
if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE DEBUG)
endif ()

##### Modules #####

# Libraries can be added to the LIBS variable
# or manually included here.

# Add base libs (emlib, CMSIS, device files)
include(${BASE_LOCATION}/toolchain/efm32-base.cmake)

add_subdirectory(${BASE_LOCATION}/cmsis)
add_subdirectory(${BASE_LOCATION}/emlib)
add_subdirectory(${BASE_LOCATION}/emdrv)
add_subdirectory(${BASE_LOCATION}/device)
add_subdirectory(${BASE_LOCATION}/protocol)
add_subdirectory(${BASE_LOCATION}/hardware)
add_subdirectory(${BASE_LOCATION}/radio)

# This is normally set in efm32-base.cmake, but libraries may modify it so set
# it after libraries/subdirectories have been added
set(CMAKE_EXE_LINKER_FLAGS "${COMMON_DEFINITIONS} -Xlinker -T${LINKER_SCRIPT} -Wl,-Map=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections -Wl,-v")

##### Files #####

# Add project headers
include_directories(${BASE_LOCATION}/include)

# Generate executable and link
add_executable(${PROJECT_NAME}
        source/main.c
        source/init_mcu.c
        source/init_board.c
        source/init_app.c
        source/gatt_db.c
        source/pti.c
        source/app.c
        source/application_properties.c)

efm32_configure_linker_addresses(${PROJECT_NAME})

target_link_libraries(${PROJECT_NAME} ${LIBS} emlib emdrv cmsis device radio)

# Link optional libraries if available
if (${HAS_HARDWARE})
    target_link_libraries(${PROJECT_NAME} hardware)
endif ()

if (${HAS_PROTOCOL})
    target_link_libraries(${PROJECT_NAME} protocol)
endif ()

##### Post build #####

# Add post build commands
include(${BASE_LOCATION}/toolchain/post-build.cmake)

# Add JLink commands
include(${BASE_LOCATION}/toolchain/jlink.cmake)

##### CMake debug prints #####
if (CMAKE_VERBOSE_MAKEFILE)
    print_debug_info()
endif()

协议中的

CMakeList.txt

# EFM32 Emlib CMake file
project(emlib)

# find . -name '*.c' | sort -u
add_library(${PROJECT_NAME}
        src/em_core.c
        src/alot_other_files.c)

target_include_directories(${PROJECT_NAME} PUBLIC inc)

target_link_libraries(${PROJECT_NAME} device protocol)

从main.c开始-包括其中的native_gecko.h是主要内容。

project(protocol)

string(TOLOWER ${DEVICE} DEVICE_L)

set(BLE_LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/ble_stack/linker/GCC/${DEVICE_L}.ld")

if (NOT EXISTS ${BLE_LINKER_SCRIPT})
    message("No bluetooth specific linker script defined, skipping protocol")
    set(HAS_PROTOCOL FALSE PARENT_SCOPE)
    return()
endif ()

set(HAS_PROTOCOL TRUE PARENT_SCOPE)

message("Found bluetooth specific linker script, using this instead:\n before: ${LINKER_SCRIPT}\n after: ${BLE_LINKER_SCRIPT}")

set(LINKER_SCRIPT ${BLE_LINKER_SCRIPT} PARENT_SCOPE)

add_library(${PROJECT_NAME}
            bluetooth/ble_stack/src/host/gecko_bglib.c)
#           bluetooth/ble_stack/src/soc/rtos_bluetooth.c)

target_include_directories(${PROJECT_NAME} PUBLIC
        bluetooth/ble_stack/inc/soc
        bluetooth/ble_stack/inc/host
        bluetooth/ble_stack/inc/common)
        
target_link_libraries(${PROJECT_NAME} PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/lib/EFR32BG1P/GCC/libmbedtls.a
  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/lib/EFR32BG1P/GCC/libcoex.a
  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/lib/EFR32BG1P/GCC/libpsstore.a
  emlib)
  
target_link_libraries(${PROJECT_NAME} PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/lib/EFR32BG1P/GCC/libbluetooth.a
  emlib)
  
target_link_libraries(${PROJECT_NAME} PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/lib/EFR32BG1P/GCC/librail.a
  emlib)
  
target_link_libraries(${PROJECT_NAME} PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/lib/EFR32BG1P/GCC/libnvm3.a
  emlib)

当我尝试包括静态库并将其链接到emlib的依赖项

/* Board headers */
#include "init_mcu.h"
#include "init_board.h"
#include "init_app.h"
#include "ble-configuration.h"
#include "board_features.h"

/* Bluetooth stack headers */
#include "bg_types.h"
#include "native_gecko.h"
#include "gatt_db.h"

/* Libraries containing default Gecko configuration values */
#include "em_emu.h"
#include "em_cmu.h"

在协议文件夹的CMakeLists.txt文件中,即时获取

target_link_libraries(protocol PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/bluetooth/lib/EFR32BG1P/GCC/librail.a
  emlib)

应该在libs文件夹中,并且也要事先进行编译。

按要求,或多或少是完整的错误部分。目前主要是静态库依赖错误的重复。

undefined reference to some function

0 个答案:

没有答案