除了 POSITION_INDEPENDENT_CODE 还有哪些这样的属性?

另一种方式:set_target_properties 批量设置多个属性

另一种方式:通过全局的变量,让之后创建的所有对象都享有同样的属性
相当于改变了各个属性的初始默认值。 要注意此时 set(CMAKE_xxx) 必须在 add_executable 之前才有效。
如果你从百度学的 CMake,你可能会犯如下的错误
对于 CXX_STANDARD 这种 CMake 本就提供了变量来设置的东西,就不要自己去设置 -std=c++17 选项,会和 CMake 自己设置好的冲突,导致出错。
请始终用 CXX_STANDARD 或是全局变量 CMAKE_CXX_STANDARD 来设置 -std=c++17 这个 flag,CMake 会在配置阶段检测编译器是否支持 C++17。 CUDA 的 -arch=sm_75 也是同理,请使用 CUDA_ARCHITECTURES 属性。 再说了 -std=c++17 只是 GCC 编译器的选项,无法跨平台用于 MSVC 编译器。
Windows的dll/动态链接库
假如你一定要用动态链接库(Windows 对动态链接很不友好)
__declspec(dllexport)

__declspec(dllimport)

add_subdirectory()


常见问题:老师,我链接了自己的 dll,但是为什么运行时会找不到?
这是因为你的 dll 和 exe 不在同一目录。Windows 比较蠢,他只会找当前 exe 所在目录,然后查找 PATH,找不到就报错。而你的 dll 在其他目录,因此 Windows 会找不到 dll。
- 解决1:把 dll 所在位置加到你的 PATH 环境变量里去,一劳永逸。
- 解决2:把这个 dll,以及这个 dll 所依赖的其他 dll,全部拷贝到和 exe 文件同一目录下。
手动拷贝 dll 好麻烦,能不能让 CMake 把 dll 自动生成在 exe 同一目录?
归根到底还是因为 CMake 把定义在顶层模块里的 main 放在 build/main.exe。 而 mylib 因为是定义在 mylib 这个子模块里的,因此被放到了 build/mylib/mylib.dll。
解决1:设置 mylib 对象的 xx_OUTPUT_DIRECTORY 系列属性
可以设置 mylib 的这些属性,让 mylib.dll 文件输出到 PROJECT_BINARY_DIR,也就是项目根目录(main 所在的位置)。这样 main.exe 在运行时就能找到 mylib.dll 了。 是的,为了伺候这睿智的 Wendous 系统,需要设置全部 6 个属性,是不是非常繁琐?

不懂就问,为什么说 Linux 系统是永远滴神?
Linux 系统支持 RPATH,CMake 会让生成出来可执行文件的 RPATH 字段指向他链接了的 .so 文件所在目录,运行时会优先从 RPATH 里找链接库,所以即使不在同目录也能找到。 所以还有第三种解决方案:微软,我卸卸你全家(指卸载)。然后安装 Arch Linux 系统。

