Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: build(uwebsockets): add cmakelists #1788

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

Napolitain
Copy link

@Napolitain Napolitain commented Sep 25, 2024

Suggesting a CMakeLists.txt file for easily building the project.
CMake also integrates well with vcpkg (inside IDE notably). This worked for me when building uWebSockets on Windows (with MSVC!).

ran with (through CLion) :

"D:\Program Files\Jetbrains\CLion Nova\bin\cmake\win\x64\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_MAKE_PROGRAM=D:/Program Files/Jetbrains/CLion Nova/bin/ninja/win/x64/ninja.exe" "-DCMAKE_C_COMPILER=D:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe" "-DCMAKE_CXX_COMPILER=D:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe" -DCMAKE_TOOLCHAIN_FILE=C:\Users\-\.vcpkg-clion\vcpkg\scripts\buildsystems\vcpkg.cmake -DWITH_LIBUV:BOOL=ON -G Ninja -S D:\Repos\- -B D:\Repos\-\cmake-build-debug
"D:\Program Files\Jetbrains\CLion Nova\bin\cmake\win\x64\bin\cmake.exe" --build D:\Repos\-\cmake-build-release --target HelloWorld -j 26

also : uNetworking/uSockets#229

image

Remaining tasks :

  • github actions should work with it identically (on that, not sure how to use uSockets CmakeLists during a test)
  • all targets should compile
  • ideally the benchmarks/ too

@Napolitain
Copy link
Author

Hey @uNetworkingAB ,

I’ve been thinking that we could benefit from using CMake as the standard build system, so I drafted some CMakeLists for both uWebSockets and uSockets. I was able to successfully compile all the examples and run the HelloWorld example on Windows (with MSVC!).

I’m planning to add CMakeLists for the benchmarks and tests as well. What are your thoughts on that?

For testing, since uSockets is a submodule, I’m unsure about the best approach for a pull request (PR), as it would involve two parallel PRs. The process might be simpler if both uSockets and uWebSockets were in a monorepo, allowing for a single PR, but I understand that might be difficult or undesirable to change at this point.

@uNetworkingAB
Copy link
Contributor

Project already uses Make and NMake. This CMake support is not Windows compatible (you have hardcoded flags just like the current approach). It is also not any simpler than current approach "make".

It's also known from prior testing that CMake produces slower binaries due to CMake being an intermediary compiler rather than having explicit control of all flags (I have seen 20% perf. loss with CMake PRs).

Project is more concerned with providing standards compliant headers, compatible with ANY "build system" rather than try and implement every single kind of variation of different competing "build systems" (I have enough experience dealing with people to know there are for every CMake fanatic, equal amount of Bazel fanatics, etc).

There are videos of people unfamiliar with the project, still being perfectly capable of quickly finding the "make" approach and building binaries.

TLDR; current approach is no act of randomness. And btw, old versions of uWS had CMake support and it was the most contended parts of the project that nobody could agree on. Literally saw 16 Prs of people making conflicting changes to CMake files. So I just removed it and ever since, has been quiet on that front.

Also, uWS itself already is in vcpkg

@uNetworkingAB
Copy link
Contributor

Speak of the devil - #1789

@Napolitain
Copy link
Author

Project already uses Make and NMake. This CMake support is not Windows compatible (you have hardcoded flags just like the current approach). It is also not any simpler than current approach "make".

If there are mistakes, they can be fixed quickly. CMake has some real benefits: it makes it easier to find and manage dependencies, has built-in testing features, and supports cross-platform builds. It’s more flexible than using Make or NMake and works well with IDEs, making projects easier to set up and maintain.

It's also known from prior testing that CMake produces slower binaries due to CMake being an intermediary compiler rather than having explicit control of all flags (I have seen 20% perf. loss with CMake PRs).

I’m not so sure about that. CMake essentially generates Makefiles or Ninja files, and both can use identical flags. It’s possible the CMake you came across was misconfigured. You can pass any desired flags directly to the compiler, and there’s no inherent difference in the flags applied to Clang through CMake versus a Makefile. Alternatively, maybe the project was using MSVC or GCC? Most of CMake’s additional features are related to tooling: testing, dependency management, incremental builds, and integration with vcpkg. I don’t see it as being overly attached to a tool; I’m also not particularly familiar with Bazel. I just think improving tooling over time is as crucial as refining the code itself, as it ultimately enhances development speed.

Project is more concerned with providing standards compliant headers, compatible with ANY "build system" rather than try and implement every single kind of variation of different competing "build systems" (I have enough experience dealing with people to know there are for every CMake fanatic, equal amount of Bazel fanatics, etc).

CMake doesn't contradict the focus on standards-compliant headers and compatibility but it supports it. CMake promotes best practices and standard C++ features, ensuring the project remains portable across platforms. It acts as an abstraction layer, simplifying the build process without implementing every variation of other systems, as it generates them.

There are videos of people unfamiliar with the project, still being perfectly capable of quickly finding the "make" approach and building binaries.

The problem is not compiling, but maintaining and building on top. Tooling is important and makefiles are just inferior in IDE than more proper buildsystem.

TLDR; current approach is no act of randomness. And btw, old versions of uWS had CMake support and it was the most contended parts of the project that nobody could agree on. Literally saw 16 Prs of people making conflicting changes to CMake files. So I just removed it and ever since, has been quiet on that front.

People may not have changed it simply because they don’t know how to modify build.c. Conflicts don’t necessarily mean that it was an issue either. If contributors are making conflicting changes, it just means they were not aligned, which can be addressed by having a clean CMake setup and proper guidelines.

Also, uWS itself already is in vcpkg

Which doesn't allow me to custom build.

--

Anyway, I guess it's not necessary to do. However, I believe it could offer significant benefits. We could even consider moving away from vcpkg entirely and leverage CMake's FetchContent tool instead. This would allow us to include the library at CMake configure time and build it as a dependency with specific options, such as whether to add libuv or other features, all managed through CMake's own dependency management system.

@Napolitain
Copy link
Author

Speak of the devil - #1789

😂

@uNetworkingAB
Copy link
Contributor

I just get this when I try your branch:

cmake .
make

[...]

/usr/bin/ld: cannot find uSockets/*.o: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [GNUmakefile:7: examples] Error 255

@Napolitain
Copy link
Author

Napolitain commented Sep 27, 2024

just of curiosity, why is it GNUmakefile ?
probably it conflicts with old makefile ? usually people use cmake with out of source dir (I think -B build)
(though it is very much draft yet)

@uNetworkingAB
Copy link
Contributor

It's not working

alexhultman@Windows11:~/cmakepr/uWebSockets$ mkdir build
alexhultman@Windows11:~/cmakepr/uWebSockets$ cd build
alexhultman@Windows11:~/cmakepr/uWebSockets/build$ cmake ..
-- The C compiler identification is GNU 11.4.0
-- The CXX compiler identification is GNU 11.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Building uWebSockets
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11") 
-- Building uSockets
-- Building uWebSocketsTests
-- Building uWebSocketsBenchmarks
-- Building uWSLibEpollBenchmarker
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alexhultman/cmakepr/uWebSockets/build
alexhultman@Windows11:~/cmakepr/uWebSockets/build$ make
[  1%] Building C object uSockets/CMakeFiles/uSockets.dir/src/bsd.c.o
[  2%] Building C object uSockets/CMakeFiles/uSockets.dir/src/context.c.o
[  3%] Building C object uSockets/CMakeFiles/uSockets.dir/src/crypto/openssl.c.o
[  4%] Building C object uSockets/CMakeFiles/uSockets.dir/src/eventing/epoll_kqueue.c.o
[  5%] Building C object uSockets/CMakeFiles/uSockets.dir/src/eventing/gcd.c.o
[  7%] Building C object uSockets/CMakeFiles/uSockets.dir/src/eventing/libuv.c.o
[  8%] Building C object uSockets/CMakeFiles/uSockets.dir/src/io_uring/io_context.c.o
[  9%] Building C object uSockets/CMakeFiles/uSockets.dir/src/io_uring/io_loop.c.o
[ 10%] Building C object uSockets/CMakeFiles/uSockets.dir/src/io_uring/io_socket.c.o
[ 11%] Building C object uSockets/CMakeFiles/uSockets.dir/src/loop.c.o
[ 12%] Building C object uSockets/CMakeFiles/uSockets.dir/src/quic.c.o
[ 14%] Building C object uSockets/CMakeFiles/uSockets.dir/src/socket.c.o
[ 15%] Building C object uSockets/CMakeFiles/uSockets.dir/src/udp.c.o
[ 16%] Linking C static library libuSockets.a
[ 16%] Built target uSockets
[ 17%] Building CXX object CMakeFiles/uWebSocketsCachingApp.dir/examples/CachingApp.cpp.o
c++: warning:  -flto: linker input file unused because linking not done
c++: error:  -flto: linker input file not found: No such file or directory
make[2]: *** [CMakeFiles/uWebSocketsCachingApp.dir/build.make:76: CMakeFiles/uWebSocketsCachingApp.dir/examples/CachingApp.cpp.o] Error 1
make[2]: *** Deleting file 'CMakeFiles/uWebSocketsCachingApp.dir/examples/CachingApp.cpp.o'
make[1]: *** [CMakeFiles/Makefile2:222: CMakeFiles/uWebSocketsCachingApp.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

@Napolitain
Copy link
Author

will check tomorrow, with different compilers / system
i fixed the -O3 flags that i moved in a wrong place but thats not likely the answer to those errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants