通过 cmake 重用静态库的自定义 makefile

发布于 2024-12-11 14:37:16 字数 1949 浏览 0 评论 0原文

我想这将是一个关于在 cmake 中包含具有现有 makefile 的库的通用问题;但这是我的上下文 -

我试图在另一个 CMake 项目中包含 scintilla ,并且遇到以下问题:

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

现在,如果我尝试使用 cmake 的 ADD_LIBRARY,我必须在 cmake 中手动指定 scintilla 的源 - 而且我不想弄乱它,因为我已经有了一个 makefile。因此,我宁愿调用通常的 scintilla make - 然后指示 CMAKE 以某种方式引用生成的 scintilla.a。 (我想这将不能确保跨平台兼容性 - 但请注意,目前跨平台对我来说不是问题;我只想构建 scintilla 作为此的一部分已使用 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:我该怎么做取决于自定义目标的输出? - Stack Overflow - 但是,这里的损坏似乎是由于需要专门有一个 cmake 项目的其余部分可以识别的库......

I guess this would be a generic question on including libraries with existing makefiles within cmake; but here's my context -

I'm trying to include scintilla in another CMake project, and I have the following problem:

On Linux, scintilla has a makefile in (say) the ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/gtk directory; if you run make in that directory (as usual), you get a ${CMAKE_CURRENT_SOURCE_DIR}/scintilla/bin/scintilla.a file - which (I guess) is the static library.

Now, if I'd try to use cmake's ADD_LIBRARY, I'd have to manually specify the sources of scintilla within cmake - and I'd rather not mess with that, given I already have a makefile. So, I'd rather call the usual scintilla make - and then instruct CMAKE to somehow refer to the resulting scintilla.a. (I guess that this then would not ensure cross-platform compatibility - but note that currently cross-platform is not an issue for me; I'd just like to build scintilla as part of this project that already uses cmake, only within Linux)

 

So, I've tried a bit with this:

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

... but then, add_custom_command adds a "target with no output"; so I'm trying several approach to build upon that, all of which fail (errors given as comment):

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)

 

I'm obviously quote a noob with cmake - so, is it possible at all to have cmake run a pre-existing makefile, and "capture" its output library file, such that other components of the cmake project can link against it?

Many thanks for any answers,
Cheers!

 

EDIT: possible duplicate: CMake: how do i depend on output from a custom target? - Stack Overflow - however, here the breakage seems to be due to the need to specifically have a library that the rest of the cmake project would recognize...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

葬花如无物 2024-12-18 14:37:16

您还可以使用导入的目标和自定义目标,如下所示:

# 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.  

You could also use imported targets and a custom target like this:

# 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.  
忆梦 2024-12-18 14:37:16

好吧,我想我已经有了一些;基本上,在构建 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}< /code> 被定义 - 以便添加依赖项:

ADD_DEPENDENCIES(${PROJECT_NAME} scintilla.a)

...最后,需要链接库。

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

list(APPEND PROJ_LIBRARIES ${SCINTILLA_LIBRARY} )

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

为了保持一致性,我尝试使用 ${SCINTILLA_LIBRARY} 而不是 scintilla.a 作为 ADD_CUSTOM_TARGET 中的标识符,但收到错误:“目标名称可能不包含使用ADD_CUSTOM_COMMAND生成文件。”。因此,这可能可以通过 ADD_CUSTOM_COMMAND 更智能/更正确地解决 - 但是,我读到它“定义一个可以在构建过程中执行的新命令。指定的输出应作为源文件列在目标中“......现在我完全困惑什么是文件,什么是标签,什么是目标 - 所以我想我会离开这里(如果它没有损坏,就不要修复它:))

好吧,最终知道一个更正确的方法来做到这一点仍然很好,
干杯!

OK, I think I have it somewhat; basically, in the CMakeLists.txt that build scintilla, I used this only:

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

... and then, the slightly more complicated part, was to find the correct cmake file elsewhere in the project, where the ${PROJECT_NAME} was defined - so as to add a dependency:

ADD_DEPENDENCIES(${PROJECT_NAME} scintilla.a)

... and finally, the library needs to be linked.

Note that in the commands heretofore, the scintilla.a is merely a name/label/identifier/string (so it could be anything else, like scintilla--a or something); but for linking - the full path to the actual `scintilla.a file is needed (which in this project ends up in a variable ${SCINTILLA_LIBRARY}). In this project, the linking basically occurs through a form of a

list(APPEND PROJ_LIBRARIES ${SCINTILLA_LIBRARY} )

... and I don't really know how cmake handles the actual linking afterwards (but it seems to work)

 

For consistency, I tried to use ${SCINTILLA_LIBRARY} instead of scintilla.a as identifier in the ADD_CUSTOM_TARGET, but got error: "Target names may not contain a slash. Use ADD_CUSTOM_COMMAND to generate files". So probably this could be solved smarter/more correct with ADD_CUSTOM_COMMAND - however, I read that it "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."... And by now I'm totally confused so as to what is a file, what is a label, and what is a target - so I think I'll leave at this (and not fix it if it ain't broken :) )

Well, it'd still be nice to know a more correct way to do this eventually,
Cheers!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文