I'm trying to build a C++ project with 3rd-party library managed by vcpkg
. CMake is able to correctly find the libraries using find_package
during configuration. However, when I build the target, the compilation always fails with "header file not found error".
I'm trying to build a C++ project on my Apple M1 laptop. I'm using CMake inside VS Code.
$ uname -a
Darwin My-MacBook-Air.local 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar 6 21:00:41 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T8103 arm64
$ which cmake
/opt/homebrew/bin/cmake
$ cmake --version
cmake version 3.26.3
Below is my settings.json
(from VS Code) and CMakeList.txt
{
"C_Cpp.default.cppStandard": "c++20",
"cmake.configureOnOpen": true,
"cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "~/Srcs/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
}
cmake_minimum_required(VERSION 3.20.0)
project(myproj VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 20)
# headers
include_directories(include)
# create library
add_library(myproj-lib STATIC
"src/core/crypto_msg.cpp"
"src/rsa/rsa.cpp"
)
# add external libraries
# openssl
set(OPENSSL_ROOT_DIR "~/Srcs/vcpkg/installed/arm64-osx")
find_package(OpenSSL REQUIRED)
target_link_libraries(myproj-lib PUBLIC OpenSSL::Crypto)
# fmt
find_package(fmt REQUIRED)
target_link_libraries(myproj-lib PUBLIC fmt::fmt)
# range
find_package(range-v3 REQUIRED)
target_link_libraries(myproj-lib PUBLIC range-v3)
# main func
add_executable(myproj-main main.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Adding the following two lines in CMakeList.txt
as suggested in the comments
get_property(dir TARGET fmt::fmt PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
message(STATUS ${dir})
I get the following:
[cmake] -- /Users/Bob/Srcs/vcpkg/installed/arm64-osx/include
Looks like the path is correctly added. Checking build/compile_commands.json
also shows the path is passed to compiler via -isystem /Users/Bob/Srcs/vcpkg/installed/arm64-osx/include
:
"/Library/Developer/CommandLineTools/usr/bin/c++ -I/Users/Bob/myproj/include -isystem /Users/Bob/Srcs/vcpkg/installed/arm64-osx/include -g -std=gnu++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk -o CMakeFiles/myproj-lib.dir/src/core/crypto_msg.cpp.o -c /Users/Bob/myproj/src/core/crypto_msg.cpp"
When I configure the project using the following command, everything seems fine:
$ /opt/homebrew/bin/cmake --no-warn-unused-cli -DCMAKE_TOOLCHAIN_FILE:STRING=~/Srcs/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -S/Users/Bob/myproj -B/Users/Bob/myproj/build -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] -- The C compiler identification is AppleClang 12.0.5.12050022
[cmake] -- The CXX compiler identification is AppleClang 12.0.5.12050022
[cmake] -- Detecting C compiler ABI info
[cmake] -- Detecting C compiler ABI info - done
[cmake] -- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
[cmake] -- Detecting C compile features
[cmake] -- Detecting C compile features - done
[cmake] -- Detecting CXX compiler ABI info
[cmake] -- Detecting CXX compiler ABI info - done
[cmake] -- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
[cmake] -- Detecting CXX compile features
[cmake] -- Detecting CXX compile features - done
[cmake] -- Found OpenSSL: /Users/Bob/Srcs/vcpkg/installed/arm64-osx/debug/lib/libcrypto.a (found version "3.1.0")
[cmake] -- Configuring done (2.6s)
[cmake] -- Generating done (0.0s)
[cmake] -- Build files have been written to: /Users/Bob/myproj/build
However, build failed as follows:
$/opt/homebrew/bin/cmake --build /Users/Bob/myproj/build --config Debug --target all --
[2/3] Building CXX object CMakeFiles/myproj-main.dir/main.cpp.o
FAILED: CMakeFiles/myproj-main.dir/main.cpp.o
/Library/Developer/CommandLineTools/usr/bin/c++ -I/Users/Bob/myproj/include -g -std=gnu++2a -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk -MD -MT CMakeFiles/myproj-main.dir/main.cpp.o -MF CMakeFiles/myproj-main.dir/main.cpp.o.d -o CMakeFiles/myproj-main.dir/main.cpp.o -c /Users/Bob/myproj/main.cpp
In file included from /Users/Bob/myproj/main.cpp:2:
/Users/Bob/myproj/include/core/core.hpp:4:10: fatal error: 'fmt/format.h' file not found
#include <fmt/format.h>
^~~~~~~~~~~~~~
1 error generated.
ninja: build stopped: subcommand failed.
(base)
Here the issue with fmt
is just a coincidence, as it's the first included 3rd-party header. In fact, none of the vcpkg
-managed libraries can be linked. The #include
statement fails for all of them.
Where did I go wrong? How can I fix this?
Thanks for adding the get_property
check and checking your compile_commands.json file like I asked.
I might be wrong / misread, but I don't see anything where you specify that your myproj-main
target should link to the fmt::fmt
target. You do link fmt::fmt
with PUBLIC
to your myproj-lib
target, but that won't automatically make your myproj-main
target link to fmt::fmt
as well, unless you target_link_libraries(myproj-main PRIVATE myproj-lib)
. So either you do that (depends on if you actually meant to do that in the first place or not- don't do that if you didn't), or you target_link_libraries(myproj-main PRIVATE fmt::fmt)
.
I assume that what you're showing from your compile_commands.json is for a source file other than your main.cpp, because if it was, then you wouldn't be getting this include error at all.