如何将库链接到cmake中的可执行文件?

时间:2017-05-27 19:24:56

标签: cmake

我的CMakeList.txt中有2个库和1个可执行文件。我想将所有内容链接到可执行文件中。

cmake_minimum_required( VERSION 2.8 )

# Mark the language as C so that CMake doesn't try to test the C++
# cross-compiler's ability to compile a simple program because that will fail
project( jsos C ASM )
set( CMAKE_EXECUTABLE_OUTPUT_PATH "./build/" )

# We had to adjust the CMAKE_C_FLAGS variable in the toolchain file to make sure
# the compiler would work with CMake's simple program compilation test. So unset
# it explicitly before re-setting it correctly for our system
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostartfiles" )

# Set the linker flags so that we use our "custom" linker script
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${PROJECT_SOURCE_DIR}/etc/linker.ld" )

add_library(duktape STATIC
  src/libs/duktape/duktape.c
)

add_library(fdlibm STATIC
  src/libs/fdlibm/e_acos.c
  src/libs/fdlibm/e_acosh.c
  src/libs/fdlibm/e_asin.c
  MORE FILES
)

add_executable(kernel
  src/start.S
  src/kernel.c
  src/cstartup.c
  src/cstubs.c
  src/rpi-gpio.c
  src/rpi-interrupts.c
  src/rpi-armtimer.c
  src/rpi-systimer.c
)

add_dependencies(kernel fdlibm duktape)

target_link_libraries(kernel fdlibm duktape)

add_custom_command(
  TARGET kernel POST_BUILD
  COMMAND ${CMAKE_OBJCOPY} ./kernel${CMAKE_EXECUTABLE_SUFFIX} -O binary ./kernel.img
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
  COMMENT "Convert the ELF output file to a binary image"
)

在我将这些链接在一起的那一刻,我得到了一堆错误,如:

[100%] Linking C executable kernel
libduktape.a(duktape.c.obj): In function `duk_double_trunc_towards_zero':
src/libs/duktape/duktape.c:12102: undefined reference to `fabs'
src/libs/duktape/duktape.c:12102: undefined reference to `floor'

fabsfloor位于fdlibmduk_double_trunc_towards_zero位于duktape库中,因此似乎链接正常。我做错了什么?

1 个答案:

答案 0 :(得分:1)

在你的陈述中:

target_link_libraries(kernel fdlibm duktape)

以这种方式从提供的库的有序列表(在这种情况下为fdlibm duktape)中搜索要解析的外部引用符号:

  • 从链接的库开始;
  • 搜索右侧图书馆的符号;

在您的情况下,当解析duktape的外部符号(其中一些在fdlibm中)时,fdlibm甚至不用于此搜索,并且符号duktape要求没有找到。只需在 duktape之后放入fdlibm 即可找到符号。

例如,如果您有fdlibm取决于duktape中定义的某些符号,反之亦然,您应该使用:

target_link_libraries(kernel fdlibm duktape fdlibm)

以便始终解析符号。