Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upRefactor third-party libraries to build from source on Linux #5706
Conversation
|
Best approach to make sure the config files are a good starting point is to make sure there're as few @Smjert and I will probably re-generate them using the custom toolchain and then make a diff and look at what changes. |
| inputs: | ||
| workingDirectory: $(Build.BinariesDirectory)/build | ||
| cmakeArgs: --build . --target format_check | ||
| # Temporary; this is disabled because it complains about the config.h files |
alessandrogario
Aug 16, 2019
Author
Contributor
We need to enable this back on, but we should prevent generated config files from causing this check to fail
We need to enable this back on, but we should prevent generated config files from causing this check to fail
Smjert
Aug 22, 2019
Contributor
I think that the easiest way is to add an ignore folder option (if it's not already there) in the script that checks the format.
We can ignore the entire libraries folder and be done with it.
Though if we want to have it more flexible, we should also probably add an option to specify single files.
I think that the easiest way is to add an ignore folder option (if it's not already there) in the script that checks the format.
We can ignore the entire libraries folder and be done with it.
Though if we want to have it more flexible, we should also probably add an option to specify single files.
|
|
||
| # The formula will be configured with the C_FLAGS and CXX_FLAGS parameters; we should | ||
| # forward them to the configure script when possible | ||
| message(WARNING "TODO: Use C_FLAGS") |
alessandrogario
Aug 16, 2019
Author
Contributor
We are not yet passing the compiler/linker flags to the openssl configure script. We receive them as C_FLAGS and CXX_FLAGS from the main osquery project
We are not yet passing the compiler/linker flags to the openssl configure script. We receive them as C_FLAGS and CXX_FLAGS from the main osquery project
| BUILD_COMMAND | ||
| "${CMAKE_COMMAND}" -E env CC="${CMAKE_C_COMPILER}" | ||
| "${CMAKE_COMMAND}" -E make_directory "${CMAKE_INSTALL_PREFIX}/etc/openssl" && | ||
| $(MAKE) depend -j 10 && |
alessandrogario
Aug 16, 2019
Author
Contributor
This is a totally arbitrary value that we should make configurable and default to a sane value
This is a totally arbitrary value that we should make configurable and default to a sane value
theopolis
Aug 19, 2019
Member
You should be able to remove -j 10 right now with the use of $(MAKE).
You should be able to remove -j 10 right now with the use of $(MAKE).
theopolis
Aug 19, 2019
Member
Does this use of $(MAKE) within the BUILD_COMMAND property work with Ninja as the generator?
Does this use of $(MAKE) within the BUILD_COMMAND property work with Ninja as the generator?
alessandrogario
Aug 20, 2019
Author
Contributor
The formula system was implemented using custom commands that are triggered when the required library files are referenced. The build command is executed in a new environment and is detached from the main project. It should work in theory, but I didn't test it yet.
The formula system was implemented using custom commands that are triggered when the required library files are referenced. The build command is executed in a new environment and is detached from the main project. It should work in theory, but I didn't test it yet.
Smjert
Aug 26, 2019
•
Contributor
I had to change to make because $(MAKE) is only valid if the generator calling the command is make; that's what you use for coordinating with the jobserver and avoid to spawn too many jobs.
With the change it will spawn more jobs than you required when building osquery, but it shouldn't be too much of an issue, especially for building openssl.
I had to change to make because $(MAKE) is only valid if the generator calling the command is make; that's what you use for coordinating with the jobserver and avoid to spawn too many jobs.
With the change it will spawn more jobs than you required when building osquery, but it shouldn't be too much of an issue, especially for building openssl.
| function(opensslMain) | ||
| generateMetadataTargets() | ||
|
|
||
| if(NOT DEFINED thirdparty_zlib_INCLUDE_DIRS OR |
alessandrogario
Aug 16, 2019
Author
Contributor
The metadata exchange mechanism relies on the fact that if the required parameters are missing the configuration step will still succeed (without creating the formula target)
The metadata exchange mechanism relies on the fact that if the required parameters are missing the configuration step will still succeed (without creating the formula target)
| endif() | ||
|
|
||
| # Generate the formula runner that will actually build the libraries | ||
| # TODO(alessandro): Change it so we use a completely new environment |
alessandrogario
Aug 16, 2019
Author
Contributor
We should launch the build command with a completely clean environment
We should launch the build command with a completely clean environment
|
A series of things still to do:
Glibc 2.28 deprecated some macros and moved them into a different include if one really needs them:
This shouldn't be a problem when using the custom toolchain, but if we also want to support building with system one, this has to be fixed. |
|
Some overall notes
|
| @@ -0,0 +1,210 @@ | |||
| # Copyright (c) 2014-present, Facebook, Inc. | |||
theopolis
Aug 19, 2019
Member
The path libraries/cmake/facebook/modules/api.cmake doesn't make a lot of sense.
Alternatively, move this logic into /cmake/
The path libraries/cmake/facebook/modules/api.cmake doesn't make a lot of sense.
Alternatively, move this logic into /cmake/
theopolis
Aug 19, 2019
Member
I don't feel strongly about this. Your call on where api and utils are located.
I don't feel strongly about this. Your call on where api and utils are located.
alessandrogario
Aug 22, 2019
Author
Contributor
I have stored the APIs there since they are layer-specific. Since the libraries folder (at least on the CMake side) is self-contained and not used directly by the main project, I ended up saving the file near the entry point (the find_package handlers).
We can move it elsewhere, keeping in mind however that the FindPackage script should keep using relative paths
I have stored the APIs there since they are layer-specific. Since the libraries folder (at least on the CMake side) is self-contained and not used directly by the main project, I ended up saving the file near the entry point (the find_package handlers).
We can move it elsewhere, keeping in mind however that the FindPackage script should keep using relative paths
| BUILD_COMMAND | ||
| "${CMAKE_COMMAND}" -E env CC="${CMAKE_C_COMPILER}" | ||
| "${CMAKE_COMMAND}" -E make_directory "${CMAKE_INSTALL_PREFIX}/etc/openssl" && | ||
| $(MAKE) depend -j 10 && |
theopolis
Aug 19, 2019
Member
You should be able to remove -j 10 right now with the use of $(MAKE).
You should be able to remove -j 10 right now with the use of $(MAKE).
| BUILD_COMMAND | ||
| "${CMAKE_COMMAND}" -E env CC="${CMAKE_C_COMPILER}" | ||
| "${CMAKE_COMMAND}" -E make_directory "${CMAKE_INSTALL_PREFIX}/etc/openssl" && | ||
| $(MAKE) depend -j 10 && |
theopolis
Aug 19, 2019
Member
Does this use of $(MAKE) within the BUILD_COMMAND property work with Ninja as the generator?
Does this use of $(MAKE) within the BUILD_COMMAND property work with Ninja as the generator?
|
The approach is great, thanks for flushing this out! My inline comments are low-pri. Take a look at the 1,2,3 points I made in the overall PR comment. If they are reasonably addressed then I am good-to-go on this! |
|
So you were right, @alessandrogario fixed that. |
|
Sorry about the noise but you'll need to rebase one more time for changes to |
|
|
We can iterate on this in follow up PRs as well. |
|
FYI, I was trying to speed up the checkout in my last commit to this branch. Feel free to overwrite/replace/remove if it messed something up or there are fundamental issues with the changes. |
|
I've rebased on master and fixed a thing, otherwise even the previous build would fail. |
|
For the only test that's failing, it seems that zlib is not using the correct CRC32 implementation for gzip. |
|
So the issue is a bit tricky: I tried to avoid to compile that symbol, but it's used by |
|
Interesting, can we use linker flags instead of patching? I’m not sure what flags or if this is possible, but we should look. |
I've checked, using the preprocessor you can pass |
|
Great progress, how are we doing on the list of TODOs? Should we squash everything into a small commit set? |
|
A single commit might be good too, or at least a very small set, to make bisecting easier. |
If possible we wanted to preserve the contribution of everyone, even though to be honest I'm not really sure how much is possible, given that our commits are mixed and sometimes they directly depends on each other. I've updated the TODO list for what there's still to do, I'll update it again if I missed something.
|
Add a way to compile third-party libraries from source instead of downloading prebuilt ones. Each library source code is downloaded with git into a submodule at configure time, in response to the find_package(library_name) CMake call, except for OpenSSL where the official source archive is used. Each submodule is attached to a release tag on its own upstream repository. All the libraries are built using CMake directly, except for OpenSSL which uses a formula system, which permits to build libraries with a separate build system when there's no easy way to integrate it directly with CMake. This new dependency system determines which library is fetched from where using the concept of "layers". Currently we have three of them: source, formula, facebook, where the last layer represents the pre-built libraries. The provided order will be used when looking for libraries. A system to patch submodule source code has been added and it's currently used with googletest, libudev and util-linux. Patches should be put under libraries/cmake/source/<library name>/patches/<submodule>, where <submodule> is often one and is "src", but in other cases, like AWS, there are multiple with a more specific name. If for whatever reason the submodule cloning or the patching fails, the submodule has to be unregistered and its folder should be cleared. This should be achievable with "git submodule deinit -f <submodule path>" Following some other changes on existing functionality: - Changed the CMake variable BUILD_TESTING to OSQUERY_BUILD_TESTS to avoid enabling tests on third party libraries. Due to an issue with glog the BUILD_TESTING variable will be always forced to OFF. - Moved compiler and linker flags to their own file cmake/flags.cmake - Moved all the third-party CMakeLists.txt used for pre-built libraries under libraries/cmake/facebook - Added the --exclude-folders option to tools/format-check.py and tools/git-clang-format.py, so that it's possible to ignore any third party library source code. - The format and format_check target use the new --exclude-folders option to exclude libraries/cmake/source from formatting. - The test and osquery binaries are properly compiled with PIE (#5611) Co-authored-by: Stefano Bonicatti <stefano.bonicatti@gmail.com> Co-authored-by: Teddy Reed <teddy@casualhacking.io>

This PR converts all the libraries required by osquery to source modules, by converting the Makefile-based build systems to CMake.
All the libraries have been rewritten, except for OpenSSL, which is implemented using a formula-based system similar to the old one we were using with brew.
Each library resides in a git submodule that is directly attached to a release tag on the upstream repository. Each submodule is fetched at configure-time in a lazy way, in response to the find_package(library_name) CMake call.
The new dependency system implements "layers"; they are configurable, and determine which library is fetched from where. We currently have three layers implemented: source, formula, facebook. The provided order will be used when looking for libraries.