Build uWebSockets on Windows 10 with CMake - c++

I want to use uWebSockets(UWS) in my C++ project to transfer images over the network. The setup will be running on multiple operating systems, so the best way of creating the build files seemed like using CMake.
However, I am new to CMake and having a hard time building UWS. I don't understand how to start working with the official repository on Windows 10, so I found another repository that includes a CMakeFiles.txt file and some of the dependencies (openssl, zlib, libuv, but it doesn't include uSockets for some reason). The root CMakeFiles.txt includes:
[...]
find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED)
find_path(LIBUV_INCLUDE_DIR uv.h)
find_library(LIBUV_LIBRARY NAMES uv uv1)
[...]
It looks straightforward, but when I try to run mkdir build && cd build; cmake .., it cannot find OpenSSL. Here is the error message it spits out:
[...]
[cmake] Could not find a package configuration file provided by "OpenSSL" with any
[cmake] of the following names:
[cmake]
[cmake] OpenSSLConfig.cmake
[cmake] openssl-config.cmake
[...]
The above error message suggests that I need to set up a config file for each of these libraries. Yet, if I understand the find_package docs correctly, the command itself searches the library in various locations under the root folder. What kind of a folder structure does the find_package need in order to work?
More generally, am I wasting my time with this alternative repo? Is there a better way of using UWS with Windows 10? The official repo has a question about how to use it on Windows but I don't understand how that's an answer to the question. It only points to this page where it says any specific build systems will not officially be supported.
Any help would be appreciated.

Importing dependencies with add_subdirectory seems like a good way around this. When I ran cmake, I was receiving LNK2019 Error. I realized the following code snippet I found online was causing the problem, and the system works when I delete it.
if(MSVC)
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
endif()

Related

CMake can't find protobuf when compiling Google's protobuf example

I am trying to solve this problem for 2 days now with no luck. I've read an endless number of threads allover the web and tried a lot of suggestions but so far with no luck.
I'm doing this on Windows 10 with VS2017 and most recent VS Code installed. I installed protobuf with vcpkg install protobuf:
The package protobuf:x64-windows provides CMake targets:
find_package(protobuf CONFIG REQUIRED)
target_link_libraries(main PRIVATE protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite)
I downloaded Google's example code and extracted it on my drive. The .PROTO file compiles without a problem:
d:\protobuf-3.12.2\examples>protoc -I=d:\protobuf-3.12.2\examples --cpp_out=d:\protobuf-3.12.2\examples d:\protobuf-3.12.2\examples\addressbook.proto
and creates the two files "addressbook.pb.cc" and "addressbook.pb.h" as expected.
Now when I try to compile the project in Visual Studio Code it constantly fails no matter how I modify the CMakeLists.txt file. As mentioned I went through dozens of threads regarding this problem and tried a lot with no luck.
Update 29.05.2020
I checked that protobuf is installed just once and indeed the demo package also included a full protobuf installation. I removed this extra demo package and un-/installed protobuf with vcpgk. I then compiled the .proto file with protoc (which is in my path) and got the two files "addressbook.pb.cc" and "addressbook.pb.h".
Then I tried to compile the project again, this time using the CMakeLists.txt that came with the demo.
The relevant part seems to be right in the beginning:
# Minimum CMake required
cmake_minimum_required(VERSION 2.8.12)
# Project
project(protobuf-examples)
# Find required protobuf package
find_package(protobuf CONFIG REQUIRED)
if(protobuf_VERBOSE)
message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")
endif()
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
Compiling this gives me:
[main] Building folder: examples
[main] Configuring folder: examples
[cms-client] Configuring using the "Visual Studio 15 2017" CMake generator with platform "x64" and toolset "host=x64"
[cmake] Selecting Windows SDK version 10.0.17763.0 to target Windows
...
[cmake] CMake Error at CMakeLists.txt:8 (find_package):
[cmake] Could not find a package configuration file provided by "protobuf" with any
[cmake] of the following names:
[cmake]
[cmake] protobufConfig.cmake
[cmake] protobuf-config.cmake
[cmake]
[cmake] Add the installation prefix of "protobuf" to CMAKE_PREFIX_PATH or set
[cmake] "protobuf_DIR" to a directory containing one of the above files. If
[cmake] "protobuf" provides a separate development package or SDK, be sure it has
[cmake] been installed.
[cmake]
[cmake]
[cmake] Configuring incomplete, errors occurred!
[cmake] See also "d:/vcpkg/buildtrees/protobuf/src/v3.12.0-8ba83cbbdb/examples/build/CMakeFiles/CMakeOutput.log".
[cms-driver] Error during CMake configure: [cmake-server] Configuration failed.
The file protobuf-config.cmake can be found multiple times in the protobuf folder:
D:\vcpkg\buildtrees\protobuf\<BUILDCFG>\share\protobuf\protobuf-config.cmake
D:\vcpkg\installed\<BUILDCFG>\share\protobuf\protobuf-config.cmake
D:\vcpkg\packages\<BUILDCFG>\share\protobuf\protobuf-config.cmake
What could be the cause that CMake can't locate these files?
Fair warning I am no expert.
I ran in to a similar problem in my own build trying to get Boost working and I think it has to do with your environment variables and how you have your Visual Studio setup. While you are setting crucial things such as
SET(PROTOBUF_INCLUDE_DIR "d:/vcpkg/packages/protobuf_x64-windows/include/")
The actual find_package(protobuf CONFIG REQUIRED) throws these settings out the window. Once it finds that config file it only cares about what the config file is finding, I think this is the cause of how your first MESSAGE has the right one, and then your 2nd one doesn't find one.
Are you positive you only have one installation of protobuf on your machine?
It appears to be finding this "used as include directory in directory D:/protobuf-3.12.2/examples"
yet you are trying to find "D:/vcpkg/packages/protobuf_x64-windows" no?
Try adding a "-DCMAKE_PREFIX_PATH="d:/vcpkg/packages/protobuf_x64-windows" to your CMake options in Visual Studio
Good luck and sorry if this doesn't help, I'm relatively new to programming but its worth a try.
in this thread fraser solved the problem but if you need to develop according to protobuf CMake config and find_package command in CMake for finding protobuf libraries. your protobuf library must be compiled with CMake and do not use configure routine .
after compile protobuf with CMake , a config file named protobuf-config.cmake will be generated into the prefix/lib/CMake/protobuf directory.
If the problem is in finding the protobuf installation then your protobuf path isn't on the Environment Variables try adding that to your path and let me know in case if it is there.
Will glad to help you more in case this doesn't work

CMake "find_package" command on a package that was not installed is unexpectedly successful

I am following chapter-02/recipe-06 in "CMake Cookbook". This particular example requires the Eigen C++ libraries.
I attempted to build the example and got the error that Eigen was not found.
CMake Error at CMakeLists.txt:9 (find_package):
Could not find a package configuration file provided by "Eigen3" (requested
version 3.3) with any of the following names:
Eigen3Config.cmake
eigen3-config.cmake
Add the installation prefix of "Eigen3" to CMAKE_PREFIX_PATH or set
"Eigen3_DIR" to a directory containing one of the above files. If "Eigen3"
provides a separate development package or SDK, be sure it has been
installed.
This was expected because the library was not installed on my system.
I then downloaded the ".zip" file for the Eigen libraries and unzipped it to an arbitrary location outside of my project. I created a "build" folder in the Eigen directory and ran cmake .. in the "build" folder. (I only ran cmake - I did NOT build or install the package.)
After running CMake on the Eigen build directory, I went back to the example code for "recipe-06" and it was magically able to find the Eigen library and built successfully even though Eigen was never built or installed.
Somehow just running CMake in the Eigen project made CMake aware of the Eigen libraries location. After doing this, any projects that do find_package to find Eigen3 somehow get the ${Eigen3_DIR} variable defined and are able to find it.
Looking at the CMake documentation for find_package I don't see any explanation of why this works. Eigen is not in any of the typical locations that find_package searches. According to the documentation it looks like it should NOT be found.
Even more interesting - it doesn't matter where I put Eigen on my system. I can put it literally anywhere and it will still find it.
According to everything I see in the documentation it should not be found... but it is found. So the question is how? Why does this work?
Additional info: I am using CMake version 3.13.3
There are 2 "origins" of XXXConfig.cmake files, used internally by find_package() call.
Usually, XXXConfig.cmake file is produced when the project is installed, and the file contains information about installed libraries and headers.
But CMake provides also an export() command, which allows to export build tree.
export(PACKAGE <name>)
Store the current build directory in the CMake user package registry for package <name>. The find_package command may consider the directory while searching for package <name>.
Eigen's CMakeLists.txt uses export() command, so the project becomes detectable with find_package just after running cmake for Eigen.

How to know variable such as 'OpenCV' in CMake

I am using OpenCV with gcc and cmake. And I found a tutorial https://docs.opencv.org/3.4.0/db/df5/tutorial_linux_gcc_cmake.html .In the file CMakeLists.txt, there are some variables such as OpenCV and OpenCV_INCLUDE_DIRS.
cmake_minimum_required(VERSION 3.9)
project(VideoRecord)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(VideoRecord main.cpp)
target_link_libraries(VideoRecord ${OpenCV_LIBS})
I want to know where to find these variables definition.
EDIT
Thanks #qbranchmaster's answer. I tried to search FindOpenCV.cmake but failed.
First try.
➜ ~ cmake --help-module-list | grep "FindOpen"
FindOpenACC
FindOpenAL
FindOpenCL
FindOpenGL
FindOpenMP
FindOpenSSL
FindOpenSceneGraph
FindOpenThreads
Another try.
➜ / find . "FindOpenCV.cmake"
In addition, my os is osx and I install cmake with brew. I comiple and install OpenCV manually.
These variables are part of the package config script shipping with OpenCV.
Note that find_package is a two-headed beast. The classic mode of operation is finding libraries through find-scripts. This is still the approach being used today for third-party libraries that are not aware of CMake. However, if your dependency is itself being built with CMake, it can provide a package config file instead, which allows for a more powerful mode of operation.
The idea here is that instead of you telling CMake how to find a dependency, the dependency itself tells CMake how clients can find it. This is the approach that is taken by libraries like OpenCV and Qt.
To answer your question, those variables are being set by the package config file in your local OpenCV installation, the template of which can be found in the OpenCV source code under cmake/templates/OpenCVConfig.cmake.in.
They are defined in CMake OpenCV module. CMake has numerous modules that aid in finding various libraries like OpenCV (FindOpenCV.cmake module).
Using this command you can get a list of modules that your CMake supports:
cmake --help-module-list
Some libraries come with their own *.cmake modules which should be installed in some system path. If you are using Ubuntu, your cmake modules should be localised in:
/usr/share/cmake/Modules/
If not, just search system for file FindOpenCV.cmake. In that file you will find these variables.
In general, you get variable names from the documentation or source code of the package you want to find.
Often you can derive the name to put into find_package from the provided FindFoo.cmake module file name, because "Foo" would be the name. The find module is either part of CMake or comes with the third-party library.
If there is no find module, some modules provide FooConfig.cmake files, where "Foo" is again the string to put into find_package.
If you have neither a find nor a config file, you need to find the library by other means, e.g., FindPkgConfig or find_library / find_file.

How to change where CMakeLists.txt looks for Boost Libraries Ubuntu

I was using Boost 1.54.0 and it was located in "/usr/include". We blew that away and installed Boost 1.57.0. It got installed in "/usr/local/include".
Now, my CLion project, which uses CMake cannot find the Boost library. Here is my CMakeLists.txt file:
And here are my errors:
I have no idea how to make CMake look in the correct place for Boost.
According to the FindBoost documentation (http://www.cmake.org/cmake/help/v3.1/module/FindBoost.html), you can set a CMake variable BOOST_ROOT to give CMake a hint about where to look.
In your CMakeLists.txt file, you can add the following before the find_package(Boost...) line:
set(BOOST_ROOT /usr/local)
Update:
I agree with the comments that putting machine specific configuration parameters directly in CMakeLists.txt is not best practice.
As an alternative to directly setting this variable, you can pass options like this to the cmake process in CLion by doing the following:
Navigate to File -> Settings... -> Build, Execution, and Deployment -> CMake. Under Generation, add -DBOOST_ROOT=/usr/local to CMake options.

How to build google's C++ libphonenumber library for Win32

Some developers on our team are using the Java and C# versions of libphonenumber, a normalization library for international phone numbers.
They claim it is wonderful/magical/etc.
Unfortunately, being a Win32 C++ developer, my simple mind can't quite grasp all the wonder and magic of the CMake, boost, and host of other libraries and I can't build the library at all.
Can someone provide some hints ot tips or URLs to help point me in the right direction so that we can build this project and make use of it?
The current stumbling block is when trying to run CMake (following the instructions in the very short readme) I get the following error message:
> -- Could NOT find Boost
> -- Configuring incomplete, errors occurred!
I thought I set BOOST_ROOT correctly, but apparently either I set it wrong or I am missing other env vars.
How can I build this library?
We use VS 2008, but I also have VS 2010 on my machine. I would be happy to get a build with either one.
Your CMake may be outdated wrt to the Boost version you installed. Check the file FindBoost.cmake located in the CMake Modules directory. It must contain a section like this:
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
"1.46.1" "1.47" "1.47.0"
"1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42"
"1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37"
"1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0"
"1.34" "1.33.1" "1.33.0" "1.33")
You can try to pass BOOST_INCLUDEDIR and BOOST_LIBRARYDIR to the compiler; this way you can totally bypass the cmake module search.
Change Boost_ADDITIONAL_VERSIONS in FindBoost.cmake, step that you've already done
Change the CMakeLists.txt from \libphonenumber\cpp, change the line find_package (Boost 1.40.0 COMPONENTS thread)
into
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF) //since CMake 2.8.3
find_package (Boost 1.47.0 COMPONENTS thread)
3. Run mkdir build in \libphonenumber\cpp, cd build
4. Run cmake -G "your generator" -DBOOST_ROOT="you_path_to_boost_147_0 folder,", ex: cmake -G "Visual Studio 10" ../ -DBOOST_ROOT="E:\libphonenumber\cpp\3rdparty"
Try to compile it using cygwin, it is like a standard UNIX build environment but running on Windows. It usually is a lot easier to compile open source libraries using it than using Visual Studio.