Search code examples
c++macosvisual-studio-codecmakevcpkg

CMake configure succeeded but fails to build target due to header not found


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".

Context

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)

Error description

Update 1

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"

Original description

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?


Solution

  • 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.