代码之家  ›  专栏  ›  技术社区  ›  JoeVictor

C++-为什么没有源文件静态库就无法使用?

  •  0
  • JoeVictor  · 技术社区  · 2 年前

    根据我的理解 mylib.a 该文件应该只能作为即插即用文件使用。但如果没有源代码,我就无法使用它,我正在努力避免这种情况。

    我适应了 this tutorial 使用以下目录结构的CMake进行编译:

    /
       lib
          libmy_math.a
       main.cpp
       my_math.h
       my_math.cpp
       CMakeLists.txt
    

    这些文件的内容与教程中的内容完全相同。唯一添加的文件是 CMakeLists.txt 它基本上只是在构建之前运行库编译部分:

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.21)
    project(Test)
    
    ### Uncomment this ONCE to compile a libmy_math.a file
    # add_library(my_math STATIC my_math.cpp)
    
    add_executable(Test main.cpp)
    
    find_library(MY_MATH_LIB my_math HINTS ./lib)
    target_link_libraries(Test PUBLIC ${MY_MATH_LIB})
    

    作为 CMake 文件中说,取消对第5行的注释将编译库,然后在编译时将其链接到我的代码。

    我正在尝试打包我的代码,这样我就不会向客户端显示编译库的源代码( my_math ),但是如果我删除 my_math.h my_math.cpp 文件,我得到一个“ file not found “导入时出错:

    /Users/Joe/Desktop/Test/main.cpp:1:10: fatal error: 'my_math.h' file not found
    #include "my_math.h"
             ^~~~~~~~~~~
    
    

    我认为您可以在不需要源代码的情况下编译库。我在这里错过了什么?

    2 回复  |  直到 2 年前
        1
  •  3
  •   lorro    2 年前

    静态库并不包含标头可以包含的每一个定义——想想宏等。因此,您仍然需要标头。但是,您不再需要.cpp来链接库。

        2
  •  3
  •   ComicSansMS    2 年前

    除了中所述的问题 Iorro's answer 这个 find_library 在这里打电话不会按预期工作。

    find_library(MY_MATH_LIB my_math HINTS ./lib)
    target_link_libraries(Test PUBLIC ${MY_MATH_LIB})
    

    这样做的目的是,在运行CMake时,查找 my_math.a 文件然而在构建过程的这一点上, my_math.a 尚未建成。您只是第一次运行CMake,所以您所拥有的只是源文件。尚未编译任何内容。

    相反,您想做的是直接链接到库目标,因为CMake已经知道这一点,并且可以自己解决依赖关系。因此,您需要将上面的两行替换为:

    target_link_libraries(Test PUBLIC my_math)
    

    这现在引入了一种奇怪的不对称性,即测试如何使用库(因为它是同一构建的一部分),而客户端如何使用同一库(它们不是同一构建中的一部分,因此需要执行 find_package 在他们可以使用它之前打电话)。看看CMake config-file packages 对于一种允许您在这里恢复对称性的机制,代价是您的CMake脚本中需要大量的样板。