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

Add CMake build system support #49

Merged
merged 3 commits into from Apr 9, 2019

Conversation

Projects
None yet
2 participants
@spinda
Copy link
Contributor

spinda commented Apr 8, 2019

This adds support for building libhydrogen with CMake and—more importantly—easily integrating libhydrogen with CMake-based projects and IDEs.

The CMakeLists.txt file supports everything the Makefile does, including installation and automatically running tests on build. It also supports MSVC, as well as CMake's find_package() dependency mechanism, so a project using libhydrogen can add the following to its own CMakeLists.txt to pull in libhydrogen:

# uncomment to use a local copy of libhydrogen or, say, git submodule
# instead of searching for a system-installed version:
#add_subdirectory(./libhydrogen)

find_package(hydrogen REQUIRED)
target_link_libraries(foo PRIVATE hydrogen::hydrogen)
@jedisct1

This comment has been minimized.

Copy link
Owner

jedisct1 commented Apr 8, 2019

Isn't CMake a little bit tacky?

Using a complicated build system to compile a single file sounds overkill, but if we do, maybe something more modern such as Meson would be a better choice?

@spinda

This comment has been minimized.

Copy link
Contributor Author

spinda commented Apr 8, 2019

Less "tacky" and more "mature", I would say :)

I went with CMake for a few reasons that I think make it a stronger choice than competing build systems.

Firstly, it has broad support in the larger C/C++ ecosystem. For example, Visual Studio, CLion, VS Code, and QtCreator all work natively with CMake projects, and plugins are available for any other major IDE. Even if you don't use an IDE to develop libhydrogen itself, developers who do can more easily pull libhydrogen in as a dependency to their own projects if it speaks CMake. Robust support for CMake exists outside the realm of IDEs, too. Even Meson supports integrating CMake dependencies!

Continuing along the same lines, I've found modern CMake's dependency integration story to be quite straightforward and flexible when I'm working with a well-configured package. Say I'm working on a project called foo. I can declare a dependency on libhydrogen by dropping this into foo's CMakeLists.txt:

find_package(hydrogen REQUIRED)
target_link_libraries(foo PRIVATE hydrogen::hydrogen)

By default, CMake will look for a system-installed copy of libhydrogen when configuring foo. However, I can override this with a local copy of libhydrogen (say, integrated as a submodule into foo's git repository) by inserting:

add_subdirectory(some/path/to/libhydrogen)

I don't even have to modify foo to make this work. In the project I'm working on right now, I have a directory structure that looks like this:

foo-project
├── CMakeLists.txt
└── libhydrogen
│   └── CMakeLists.txt
└── libfoo
    └── CMakeLists.txt

libfoo's CMakeLists.txt declares its dependency on libhydrogen using the two find_package/target_link_libraries lines above, but contains no hard-coded information as to where libhydrogen is located. The top-level CMakeLists.txt looks like:

add_subdirectory(libhydrogen)
add_subdirectory(libfoo)

Once the local copy of libhydrogen is registered in this "workspace", any other project in the workspace (e.g., libfoo) will connect up to it automatically when resolving a dependency on libhydrogen. This way, I can make any necessary local modifications to my copy of libhydrogen in the course of developing libfoo, and also have libfoo be usable in standalone form when those modifications are upstreamed.

Finally, and—admittedly—more specific to my particular use case, CMake is the standard way to compile C/C++ code into Android projects via Android NDK, so libhydrogen supporting CMake means easier use on that platform.


I've discussed what I see as CMake's strengths versus other, comparable build systems. But of course there's another alternative: no build system at all. A developer can always simply bundle up libhydrogen's source code into a single C file—as you pointed out—and drop it manually into their project. However, going down that road makes it harder to update libhydrogen, and, I think, makes it very likely that the developer simply won't update at all once they get their project working. Having the ability to integrate libhydrogen as a dependency at a higher level, without having to modify libhydrogen itself or hardcode information about its internal structure, makes following along with upstream a much smoother process (with git, a simple git submodule update --remote). I'd say this is a desirable property for a security library.

spinda added some commits Apr 9, 2019

CMake: don't auto-run tests if cross-compiling
Otherwise this could fail if, say, you're building for an ARM system
from an x86 system.
CMake: allow configuring target architecture
Default to -march=native, unless we detect cross-compiling, in which
case default to leaving out -march=... entirely (as detecting the host
system's architecture doesn't help with optimizing for the target
platform).
@jedisct1

This comment has been minimized.

Copy link
Owner

jedisct1 commented Apr 9, 2019

Alright, let's get this in, then. But I probably won't be able to maintain this. I have no idea how to make this work for e.g. WebAssembly or the Arduino IDE.

We should make sure that the project never depends on this, and that the .c file can always be compiled directly.

@jedisct1 jedisct1 merged commit 838aa37 into jedisct1:master Apr 9, 2019

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@spinda

This comment has been minimized.

Copy link
Contributor Author

spinda commented Apr 10, 2019

Excellent, thanks! Your point about making sure libhydrogen can always be compiled directly seems completely reasonable to me.

I can add a target for the Arduino IDE, and for WebAssembly if you have an example of how you'd do that with, say, a Makefile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.