My Development Environment
I’m using WSL2 on Windows 11, with vcpkg as the package manager and VS Code as my IDE.
To ensure the successful build of a C++ project, it’s crucial to resolve all dependencies. The key lies in informing CMake about where to locate them.
For my uWebSockets tutorial, I’ve created a subdirectory named uw, within which I’ve placed a CMake file.
find_path(UWEBSOCKETS_INCLUDE_DIRS "uwebsockets/App.h")
find_path(USOCKET_LIB_A "lib/libuSockets.a")
find_package(ZLIB REQUIRED)
add_executable(UwStart)
include_directories("${UWEBSOCKETS_INCLUDE_DIRS}")
include_directories("${UWEBSOCKETS_INCLUDE_DIRS}/uwebsockets")
target_sources(UwStart PRIVATE start.cpp)
target_link_libraries(UwStart "${USOCKET_LIB_A}/lib/libuSockets.a" ZLIB::ZLIB)
find_path
The vcpkg document mentions that after the vcpkg toolchain takes effect, the find_path command will search the directories managed by vcpkg.
So here, we’re searching for the header files for uWebSockets and the uSockets static library.
Carefully watch the output of cmake; there is a lot of information about the installed packages.
[cmake] The package zlib is compatible with built-in CMake targets:
[cmake]
[cmake] find_package(ZLIB REQUIRED)
[cmake] target_link_libraries(main PRIVATE ZLIB::ZLIB)
[cmake]
[cmake] uwebsockets is header-only and can be used from CMake via:
[cmake]
[cmake] find_path(UWEBSOCKETS_INCLUDE_DIRS ")uwebsockets/App.h")
[cmake] target_include_directories(main PRIVATE ${UWEBSOCKETS_INCLUDE_DIRS})
[cmake]
run cmake build
Watch the OUTPUT carefully. I missed the ZLIB dependency at the beginning. Look at the log bellow:
[build] : && /usr/bin/c++ -g uw/CMakeFiles/UwStart.dir/start.cpp.o -o uw/UwStart vcpkg_installed/x64-linux/debug/lib/libuSockets.a && :
[build] /usr/bin/ld: uw/CMakeFiles/UwStart.dir/start.cpp.o: in function `uWS::DeflationStream::~DeflationStream()':
[build] helloworld/build/vcpkg_installed/x64-linux/include/uwebsockets/PerMessageDeflate.h:211: undefined reference to `deflateEnd'
[build] /usr/bin/ld: uw/CMakeFiles/UwStart.dir/start.cpp.o: in function `uWS::InflationStream::~InflationStream()':
[build] helloworld/build/vcpkg_installed/x64-linux/include/uwebsockets/PerMessageDeflate.h:224: undefined reference to `inflateEnd'
[build] collect2: error: ld returned 1 exit status
[build] ninja: build stopped: subcommand failed.
Follow the reference chains it shows it’s from the zlib. So I added ZLIB dependency. Now it builds.
[build] [2/2] Linking CXX executable uw/UwStart
[driver] Build completed: 00:00:04.492
[build] Build finished with exit code 0
Start the simple server.
Source code:
#include "App.h"
int main()
{
/* Overly simple hello world app */
int port = std::getenv("SERVER_PORT") ? std::stoi(std::getenv("SERVER_PORT")) : 3000;
std::cout << "Starting server on port " << port << std::endl;
uWS::App()
.get("/*", [port](auto *res, auto * /*req*/) // Capture 'port' in the lambda capture list
{ res->end("Hello world!"); })
.listen(port, [port](auto *listen_socket) // Capture 'port' in the lambda capture list
{
if (listen_socket) {
std::cout << "Listening on port " << port << std::endl;
} })
.run();
std::cout << "Failed to listen on port 3000" << std::endl;
}
Command to start:
j:~/helloworld$ SERVER_PORT=3001 ./build/db/uw/UwStart
Starting server on port 3001
Listening on port 3001