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

Modernize CMake #4644

Merged
merged 1 commit into from
May 27, 2020
Merged

Modernize CMake #4644

merged 1 commit into from
May 27, 2020

Conversation

alexreinking
Copy link
Member

@alexreinking alexreinking commented Feb 25, 2020

This PR overhauls the CMake build to use modern features and improve our ability to be used/included by other projects. Note that a recent version of CMake (3.16+) is now required.

New features:

  1. Clients now use find_package(Halide) to use Halide.
  2. Clients can alternately include Halide as a Git submodule and simply add_subdirectory our root. This also works with FetchContent, which automates cloning a git repo and downloading it to the build dir.
  3. Apps are built in the same way our clients would build them. Each one has an associated test that builds it and confirms that the app runs without crashing. See apps/lens_blur/CMakeLists.txt for an example.
  4. Python bindings are now built on all platforms.
  5. Tests build with precompiled headers.
  6. The new autoschedulers are packaged with the build and conveniently available from CMake.
  7. All of the tutorials are now built and tested (they weren't before!)

Changes outside CMake:

  1. Documentation is handled by doc/CMakeLists.txt. There is no more Doxyfile.
  2. Tests no longer have include access to the whole source tree. They can see the runtime includes and the test/common includes only. The affected sources and the Makefile have been modified accordingly.
  3. OpenGL tests use system headers (as a consequence of the previous)
  4. Tests in the tests/ folder must now obey the following rules:
    a. Print "Success!" upon success unless it is an error or warning test.
    b. Print a message beginning with "[SKIP]" if the test will not run for some reason (e.g. no GPU).

Breaking changes:

  1. halide.cmake and its associated functions are gone.
  2. Generator stubs are no longer supported from CMake.
  3. CMake 3.16+ required. This is the default version on Ubuntu 20.04 LTS and Visual Studio 2019.

Fixes #870
Fixes #2400
Fixes #2643
Fixes #2821
Fixes #2852
Fixes #2942
Fixes #3658
Fixes #4009
Fixes #4284
Fixes #4476
Fixes #4581
Fixes #4890
Fixes #4893
Fixes #4895
Fixes #4943
Fixes #4948

Makefile Show resolved Hide resolved
@steven-johnson
Copy link
Contributor

(Note: normally I know we don't bother rebasing commits before landing, but in this case, I suspect it will make tracking down issues after the fact simpler; once this gets close(r) to landing, definitely consider collapsing this all into a single commit)

@alexreinking
Copy link
Member Author

(Note: normally I know we don't bother rebasing commits before landing, but in this case, I suspect it will make tracking down issues after the fact simpler; once this gets close(r) to landing, definitely consider collapsing this all into a single commit)

Ok!

.clang-format Outdated Show resolved Hide resolved
.gitignore Show resolved Hide resolved
CMakeLists.txt Show resolved Hide resolved
Makefile Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
cmake/HalideTestHelpers.cmake Outdated Show resolved Hide resolved
dependencies/clang/CMakeLists.txt Outdated Show resolved Hide resolved
dependencies/jpeg/CMakeLists.txt Show resolved Hide resolved
test/correctness/CMakeLists.txt Outdated Show resolved Hide resolved
tools/CMakeLists.txt Show resolved Hide resolved
@alexreinking
Copy link
Member Author

I opened a bug with LLVM that inquires about their lack of a ClangConfigVersion.cmake

https://bugs.llvm.org/show_bug.cgi?id=45027

@steven-johnson
Copy link
Contributor

Prefer generator expressions to conditional execution of commands

Can you expand a bit on why these are preferred?

@steven-johnson
Copy link
Contributor

Test on macOS

I just tried this on mine, with my usual cmake invocation: cmake -DLLVM_DIR=${LLVM_CONFIG} --obj-root/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -DHALIDE_SHARED_LIBRARY=ON ..

and it fails quickly (for recent-trunk LLVM) with

CMake Error at dependencies/clang/CMakeLists.txt:1 (find_package):
  By not providing "FindClang.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Clang", but
  CMake did not find one.

  Could not find a package configuration file provided by "Clang" with any of
  the following names:

    ClangConfig.cmake
    clang-config.cmake

  Add the installation prefix of "Clang" to CMAKE_PREFIX_PATH or set
  "Clang_DIR" to a directory containing one of the above files.  If "Clang"
  provides a separate development package or SDK, be sure it has been
  installed.

@alexreinking
Copy link
Member Author

@steven-johnson for now add:

-DClang_DIR=$(${LLVM_CONFIG} --obj-root)/lib/cmake/clang

to the cmake command line. That's what the bug I opened with LLVM is about.

@alexreinking
Copy link
Member Author

alexreinking commented Feb 27, 2020

Prefer generator expressions to conditional execution of commands

Can you expand a bit on why these are preferred?

@steven-johnson

Yes, it's because they can be installed for end-users as-is. An example where this is necessary is with the Halide::ImageIO target that only links to PNG if it is available and only defines HALIDE_NO_PNG if it isn't.

If you were to wrap it in a conditional at configure time, then the fact that we built with PNG would propagate to our users as a requirement. OTOH if we didn't build with PNG, then the resulting library wouldn't have PNG support either. This way, it does the right thing depending on our client's build environment, not ours.

Another issue is with multi-config generators, like Visual Studio. If you want to do something based on the build configuration (ie. Debug or Release) only generator expressions are correct.

Ultimately, I have found fewer "gotchas" with generator expressions and since they're terser anyway, I think they're all around better to use when you can.

@steven-johnson
Copy link
Contributor

@steven-johnson for now add:

-DClang_DIR=$(${LLVM_CONFIG} --obj-root)/lib/cmake/clang

to the cmake command line. That's what the bug I opened with LLVM is about.

Now I get about halfway thru the build, then fail with

error: unknown warning option '-Wsuggest-override'; did you mean '-Wshift-overflow'?

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README_cmake.md Outdated Show resolved Hide resolved
packaging/CMakeLists.txt Outdated Show resolved Hide resolved
test/generator/CMakeLists.txt Outdated Show resolved Hide resolved
steven-johnson added a commit to halide/build_bot that referenced this pull request May 14, 2020
In anticipation of halide/Halide#4644 landing, we need better CMake coverage on our buildbots. This refactors to:

- Pull all the CMake support for building Halide into a non-windows-specific chunk
- Smarten up the use of CTest to more fully test everything we want to test
- Hopefully streamline the code some
- Use Ninja everywhere possible

I'm sure this will take a few tries to get right (we'll have to take down the buildbots to try it out, so scheduling suggestions welcomed) -- offering this up for initial review and comments.

(Note that I wrote this with an eye toward the code in the branch above; it's possible that it may have glitches with our current CMake code in addition to general errors...)
@steven-johnson
Copy link
Contributor

I think this is finally ready to land, pending green

@abadams
Copy link
Member

abadams commented May 27, 2020

It just occurred to me that for cuda, opencl, and d3d12, we don't need to mention them in the build files at all (with the exception of cuda_mat_mul). The runtime dlopens those if it needs them. You don't need to link the generated code against them. So it should be possible to just delete a large chunk of the generator cmake file and avoid any problems with people having libcuda installed somewhere cmake can't find it.

Edit: two of the generator tests also use the cuda or opencl API directly: acquire_release and define_extern_opencl

@alexreinking
Copy link
Member Author

It just occurred to me that for cuda, opencl, and d3d12, we don't need to mention them in the build files at all (with the exception of cuda_mat_mul). The runtime dlopens those if it needs them. You don't need to link the generated code against them. So it should be possible to just delete a large chunk of the generator cmake file and avoid any problems with people having libcuda installed somewhere cmake can't find it.

Edit: two of the generator tests also use the cuda or opencl API directly: acquire_release and define_extern_opencl

Handled.

@alexreinking
Copy link
Member Author

The only outstanding failure is with Halide's dgemm transB on size 64 when compiling with (say) HL_TARGET=x86-64-linux. Landing...

@alexreinking alexreinking merged commit a5aa574 into master May 27, 2020
steven-johnson added a commit to halide/build_bot that referenced this pull request May 27, 2020
In anticipation of halide/Halide#4644 landing, we need better CMake coverage on our buildbots. This refactors to:

- Pull all the CMake support for building Halide into a non-windows-specific chunk
- Smarten up the use of CTest to more fully test everything we want to test
- Hopefully streamline the code some
- Use Ninja everywhere possible
@alexreinking alexreinking deleted the cmake-modern branch August 9, 2020 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment