Premake5生成的Xcode项目无法识别vcpkg安装的依赖
问题现象
src/main.cpp 出现“文件未找到”错误:
#include "spdlog/spdlog.h" // 文件未找到 int main(int, char**) { spdlog::info("Welcome to spdlog!"); return 0; }
背景信息
我用vcpkg安装spdlog等依赖,将vcpkg作为子模块放入vendor/packages目录,执行命令:
git submodule add -f https://github.com/Microsoft/vcpkg.git ./vendor/packages
接着通过./vendor/packages/bootstrap-vcpkg.sh完成vcpkg初始化;编辑vcpkg.json添加spdlog依赖后,执行:
./vendor/packages/vcpkg install --x-install-root=vendor/vcpkg-installed
安装依赖。
最后用./vendor/bin/premake/premake5 xcode4生成Xcode项目,使用的premake5版本为5.0.0-dev。
我的premake5.lua配置如下:
workspace "Vulkan2" configurations { "Debug", "Release" } architecture "ARM64" location "./" outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" project "Vulkan2" kind "ConsoleApp" language "C++" targetdir ("bin/" .. outputdir .. "/%{prj.name}/") objdir ("bin-int/" .. outputdir .. "/%{prj.name}/") staticruntime "On" cppdialect "C++17" files { "%{wks.location}/src/**.h", "%{wks.location}/src/**.cpp"} includedirs{ "%{wks.location}/vendor/vcpkg-installed/" .. "arm64-osx" .. "/include/", "%{wks.location}/vendor/vcpkg-installed/arm64-osx/include/spdlog/" -- 这可能多余 } externalincludedirs{ "%{wks.location}/vendor/vcpkg-installed/" .. "arm64-osx" .. "/include/", "%{wks.location}/vendor/vcpkg-installed/arm64-osx/include/spdlog/" } xcodebuildsettings = { ["ALWAYS_SEARCH_USER_PATHS"] = "YES", ["HEADER_SEARCH_PATHS"] = { "%{wks.location}/vendor/vcpkg-installed/" .. "arm64-osx" .. "/include/" } } links {"spdlog"} filter "configurations:Debug" defines { "DEBUG" } symbols "On" libdirs {"%{wks.location}/vendor/vcpkg-installed/" .. "arm64-osx" .. "/debug/lib/"} filter "configurations:Release" defines { "NDEBUG" } optimize "On" libdirs {"%{wks.location}/vendor/vcpkg-installed/" .. "arm64-osx" .. "/lib/"}
奇怪的是,用CMake可以正常生成可用的Xcode项目,CMakeLists.txt配置如下:
cmake_minimum_required(VERSION 3.10) project(Vulkan2) find_package(spdlog CONFIG REQUIRED) add_executable(Vulkan2 src/main.cpp) target_link_libraries(Vulkan2 PRIVATE spdlog::spdlog)
安装依赖后执行./vendor/packages/vcpkg integrate install,再按vcpkg推荐执行:
cmake -G Xcode -S . -B build -DCMAKE_TOOLCHAIN_FILE=/Users/erik/Dev/Projects/Vulkan2/vendor/packages/scripts/buildsystems/vcpkg.cmake
即可成功。
需求与疑问
- 我希望用Premake5实现和CMake一样的效果,请问Premake5是否可以无需CMakeLists.txt生成项目?能否仅通过
links{}和vcpkg.json声明依赖? - 我的
premake5.lua配置是否存在问题?比如libdirs仅在各配置中定义,是否会影响links{spdlog}的执行? - Premake5是否有类似CMake工具链文件的配置方式?
更新
我发现links{}中的非框架库未出现在项目的“Frameworks and Libraries”中,这是否意味着链接步骤失败?手动添加fmt、glfw3、spdlog和vulkan库后,出现以下编译错误:
Ld /Users/erik/Dev/Projects/Vulkan2/bin/Debug-macosx-ARM64/Vulkan2/Vulkan2 normal (in target 'Vulkan2' from project 'Vulkan2') cd /Users/erik/Dev/Projects/Vulkan2 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -Xlinker -reproducible -target arm64-apple-macos14.2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.2.sdk -O0 -L/Users/erik/Library/Developer/Xcode/DerivedData/Vulkan2-bjvzuhuwjwufmfaommqrpgnkatkb/Build/Intermediates.noindex/EagerLinkingTBDs/Debug -L/Users/erik/Dev/Projects/Vulkan2/bin/Debug-macosx-ARM64/Vulkan2 -Lvendor/vcpkg-installed/arm64-osx/lib -L/Users/erik/Dev/Projects/Vulkan2/vendor/vcpkg-installed/arm64-osx/lib -F/Users/erik/Library/Developer/Xcode/DerivedData/Vulkan2-bjvzuhuwjwufmfaommqrpgnkatkb/Build/Intermediates.noindex/EagerLinkingTBDs/Debug -F/Users/erik/Dev/Projects/Vulkan2/bin/Debug-macosx-ARM64/Vulkan2 -filelist /Users/erik/Library/Developer/Xcode/DerivedData/Vulkan2-bjvzuhuwjwufmfaommqrpgnkatkb/Build/Intermediates.noindex/Vulkan2.build/Objects-normal/arm64/Vulkan2.LinkFileList -dead_strip -Xlinker -object_path_lto -Xlinker /Users/erik/Library/Developer/Xcode/DerivedData/Vulkan2-bjvzuhuwjwufmfaommqrpgnkatkb/Build/Intermediates.noindex/Vulkan2.build/Objects-normal/arm64/Vulkan2_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -lspdlog -lglwf3 -lvulkan -lfmt -lspdlog -lfmt -framework Cocoa -lvulkan -framework IOKit -lglfw3 -Xlinker -no_adhoc_codesign -Xlinker -dependency_info -Xlinker /Users/erik/Library/Developer/Xcode/DerivedData/Vulkan2-bjvzuhuwjwufmfaommqrpgnkatkb/Build/Intermediates.noindex/Vulkan2.build/Objects-normal/arm64/Vulkan2_dependency_info.dat -o /Users/erik/Dev/Projects/Vulkan2/bin/Debug-macosx-ARM64/Vulkan2/Vulkan2 ld: warning: ignoring duplicate libraries: '-lfmt', '-lspdlog', '-lvulkan' ld: library 'glwf3' not found clang: error: linker command failed with exit code 1 (use -v to see invocation)
问题解答
1. Premake5能否脱离CMake实现vcpkg依赖管理?
可以,无需CMakeLists.txt。但Premake本身没有像CMake那样原生支持vcpkg的自动依赖发现,不能仅靠links{}和vcpkg.json直接完成依赖配置,需要手动处理头文件路径、库路径,或者借助社区维护的Premake扩展脚本简化流程。
2. 当前premake5.lua的问题分析
- 头文件路径冗余:
includedirs已经包含了arm64-osx/include,无需单独添加spdlog子目录,#include "spdlog/spdlog.h"会自动从主include目录下查找。同时externalincludedirs和includedirs重复设置,Xcode下includedirs已足够,无需重复配置。 - 库路径配置的影响:
libdirs按Debug/Release分配置设置是正确的,Premake处理links时会根据当前激活的配置查找对应libdirs下的库,只要路径正确,不会影响links{spdlog}的执行,前提是路径内存在对应库文件(比如Debug下是libspdlogd.a,Release下是libspdlog.a)。 - Xcode链接库未显示的问题:Premake的
links命令在Xcode下,静态库不会自动显示在“Frameworks and Libraries”列表中,但实际会传递给链接器。手动添加时的glwf3错误是拼写错误,应为glfw3,这才导致链接器找不到库。
3. Premake的工具链配置方式
Premake没有像CMake那样的工具链文件,但可以通过自定义脚本和filter指令模拟类似逻辑:
- 可以编写单独的lua脚本,封装vcpkg的路径规则(比如根据架构、配置自动拼接include和lib路径),再在
premake5.lua中引入。 - 利用
filter根据系统、架构、配置批量设置includedirs、libdirs,避免硬编码平台标识,示例:filter "system:macosx" filter "architecture:ARM64" includedirs "%{wks.location}/vendor/vcpkg-installed/arm64-osx/include" filter "configurations:Debug" libdirs "%{wks.location}/vendor/vcpkg-installed/arm64-osx/debug/lib" filter "configurations:Release" libdirs "%{wks.location}/vendor/vcpkg-installed/arm64-osx/lib"
修复后的premake5.lua示例
workspace "Vulkan2" configurations { "Debug", "Release" } architecture "ARM64" location "./" outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" project "Vulkan2" kind "ConsoleApp" language "C++" targetdir ("bin/" .. outputdir .. "/%{prj.name}/") objdir ("bin-int/" .. outputdir .. "/%{prj.name}/") staticruntime "On" cppdialect "C++17" files { "%{wks.location}/src/**.h", "%{wks.location}/src/**.cpp"} -- 统一设置头文件路径,去除冗余 filter "system:macosx" filter "architecture:ARM64" includedirs "%{wks.location}/vendor/vcpkg-installed/arm64-osx/include" -- 按配置设置库路径 filter "configurations:Debug" defines { "DEBUG" } symbols "On" libdirs "%{wks.location}/vendor/vcpkg-installed/arm64-osx/debug/lib" filter "configurations:Release" defines { "NDEBUG" } optimize "On" libdirs "%{wks.location}/vendor/vcpkg-installed/arm64-osx/lib" -- 链接spdlog,静态库后缀会自动处理 links {"spdlog"} -- 简化Xcode配置,无需重复设置头文件路径 xcodebuildsettings = { ["ALWAYS_SEARCH_USER_PATHS"] = "YES" }
手动添加库时的错误修复
手动添加时把glfw3拼写成了glwf3,修正后即可解决找不到库的问题。建议不要再手动添加库,通过Premake的links和libdirs配置管理,避免重复链接的警告。
内容的提问来源于stack exchange,提问作者saner

