使用cmake重用静态库的自定义makefile

时间:2011-10-24 13:56:39

标签: linux cmake

我想这将是一个关于在cmake中包含现有makefile的库的一般性问题;但这是我的背景 -

我正在尝试将scintilla包含在另一个CMake项目中,我遇到以下问题:

在Linux上,scintilla在(例如)${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk目录中有一个makefile;如果你在该目录中运行make(像往常一样),你会得到一个${CMAKE_CURRENT_SOURCE_DIR}/scintilla/bin/scintilla.a文件 - 我猜这是静态库。

现在,如果我尝试使用cmake的ADD_LIBRARY,我必须在cmake中手动指定scintilla的来源 - 我宁愿不要弄乱它,因为我已经有了一个makefile。所以,我宁愿调用通常的scintilla make - 然后指示CMAKE以某种方式引用生成的scintilla.a。 (我想这会确保跨平台兼容性 - 但请注意,目前跨平台对我来说不是问题;我只想建立sc​​intilla作为其中的一部分已经使用cmake的项目,仅在Linux中

所以,我已经尝试了一下:

ADD_CUSTOM_COMMAND(
  OUTPUT scintilla.a
  COMMAND ${CMAKE_MAKE_PROGRAM}
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk
  COMMENT "Original scintilla makefile target" )

...但是,add_custom_command添加了一个“目标,没有输出”;所以我正在尝试几种方法来构建它,所有这些都失败了(作为评论给出的错误):

ADD_CUSTOM_TARGET(scintilla STATIC DEPENDS scintilla.a) # Target "scintilla" of type UTILITY may not be linked into another target.

ADD_LIBRARY(scintilla STATIC DEPENDS scintilla.a) # Cannot find source file "DEPENDS".

ADD_LIBRARY(scintilla STATIC) # You have called ADD_LIBRARY for library scintilla without any source files.
ADD_DEPENDENCIES(scintilla scintilla.a)

我显然用cmake引用了一个菜鸟 - 所以,是否有可能让cmake运行一个预先存在的makefile,并“捕获”它的输出库文件,这样cmake的其他组件项目可以链接吗?

非常感谢任何答案,
干杯!

编辑:可能重复:CMake: how do i depend on output from a custom target? - Stack Overflow - 但是,这里的破损似乎是由于需要专门设置,cmake项目的其余部分才能识别...

2 个答案:

答案 0 :(得分:9)

您还可以使用导入的目标和这样的自定义目标:

# set the output destination
set(SCINTILLA_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk/scintilla.a)
# create a custom target called build_scintilla that is part of ALL
# and will run each time you type make 
add_custom_target(build_scintilla ALL 
                   COMMAND ${CMAKE_MAKE_PROGRAM}
                   WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk
                   COMMENT "Original scintilla makefile target")

# now create an imported static target
add_library(scintilla STATIC IMPORTED)
# Import target "scintilla" for configuration ""
set_property(TARGET scintilla APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(scintilla PROPERTIES
  IMPORTED_LOCATION_NOCONFIG "${SCINTILLA_LIBRARY}")

# now you can use scintilla as if it were a regular cmake built target in your project
add_dependencies(scintilla build_scintilla)

add_executable(foo foo.c)
target_link_libraries(foo scintilla)

# note, this will only work on linux/unix platforms, also it does building
# in the source tree which is also sort of bad style and keeps out of source 
# builds from working.  

答案 1 :(得分:2)

好吧,我想我有点儿;基本上,在构建scintilla的CMakeLists.txt中,我只使用了它:

ADD_CUSTOM_TARGET(
  scintilla.a ALL
  COMMAND ${CMAKE_MAKE_PROGRAM}
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk
  COMMENT "Original scintilla makefile target" )

...然后,稍微复杂一点的部分是在项目的其他地方找到正确的cmake文件,其中定义了${PROJECT_NAME} - 以便添加依赖项:

ADD_DEPENDENCIES(${PROJECT_NAME} scintilla.a)

...最后,图书馆需要链接。

请注意,在此前的命令中,scintilla.a只是名称/标签/标识符/字符串(所以它可能是其他任何内容,如scintilla--a或某些) ;但是对于链接 - 需要实际`scintilla.a文件的完整路径(在此项目中最终以变量${SCINTILLA_LIBRARY}结束)。在这个项目中,链接基本上是通过

的形式发生的
list(APPEND PROJ_LIBRARIES ${SCINTILLA_LIBRARY} )

...我真的不知道cmake之后如何处理实际链接(但它似乎有效)

为了保持一致性,我尝试在ADD_CUSTOM_TARGET中使用${SCINTILLA_LIBRARY}而不是scintilla.a作为标识符,但出现错误:“目标名称可能不包含斜杠。使用ADD_CUSTOM_COMMAND生成文件< / EM>”。因此,使用ADD_CUSTOM_COMMAND可能会更聪明/更正确地解决这个问题 - 但是,我读到它“ defines a new command that can be executed during the build process. The outputs named should be listed as source files in the target for which they are to be generated. ”......到现在为止,我完全感到困惑。文件,什么是标签,什么是目标 - 所以我想我会离开这个(如果没有破坏则不解决它:))

嗯,最终知道一种更正确的方法仍然很好,
干杯!