main.cpp 调用 mylib.cpp 里的 say_hello 函数

改进:mylib 作为一个静态库

改进:mylib 作为一个动态库

改进:mylib 作为一个对象库
对象库类似于静态库,但不生成 .a 文件,只由 CMake 记住该库生成了哪些对象文件

对象库类似于静态库,但不生成 .a 文件,只由 CMake 记住该库生成了哪些对象文件对象库是 CMake 自创的,绕开了编译器和操作系统的各种繁琐规则,保证了跨平台统一性。在自己的项目中,我推荐全部用对象库(OBJECT)替代静态库(STATIC)避免跨平台的麻烦。对象库仅仅作为组织代码的方式,而实际生成的可执行文件只有一个,减轻了部署的困难。
避免剔除没引用的对象文件
静态库的麻烦:GCC 编译器自作聪明,会自动剔除没有引用符号的那些对象

对象库可以绕开编译器的不统一:保证不会自动剔除没引用到的对象文件

动态库也可以避免剔除没引用的对象文件,但引入了运行时链接的麻烦

add_library 无参数时,是静态库还是动态库?
会根据 BUILD_SHARED_LIBS 这个变量的值决定是动态库还是静态库。ON 则相当于 SHARED,OFF 则相当于 STATIC。如果未指定 BUILD_SHARED_LIBS 变量,则默认为 STATIC。
因此,如果发现一个项目里的 add_library 都是无参数的,意味着你可以用:cmake -B build -DBUILD_SHARED_LIBS:BOOL=ON来让他全部生成为动态库。
稍后会详解命令行传递变量的规则。
小技巧:设定一个变量的默认值
要让 BUILD_SHARED_LIBS 默认为 ON,可以用下图这个方法: 如果该变量没有定义,则设为 ON,否则保持用户指定的值不变。 这样当用户没有指定 BUILD_SHARED_LIBS 这个变量时,会默认变成 ON。 也就是说除非用户指定了 -DBUILD_SHARED_LIBS:BOOL=OFF 才会生成静态库,否则默认是生成动态库。


常见坑点:动态库无法链接静态库

解决:让静态库编译时也生成位置无关的代码(PIC),这样才能装在动态库里

也可以只针对一个库,只对他启用位置无关的代码(PIC)

