Skip to content

[CMake] Fix bad dependency in symlink_clang_headers #5034

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

Merged
merged 1 commit into from
Sep 28, 2016

Conversation

llvm-beanz
Copy link
Contributor

The problem here is a bit complicated. The symlink_clang_headers target creates two symlinks to clang's headers, one under the build directory at lib/swift/clang, and the other under a temporary path.

The one under the temporary path is a bad symlink, and it is only created during the build so that it can be installed. It isn't actually used by the build. Ninja treats the bad symlink as a non-existing file, and since the build rule that creates it has the restat property on it this results in the commands to symlink the clang headers directory running over and over and over again during the build.

This patch prevents that by not generating the bad symlink during the build. Instead we generate it at install time using the LLVMInstallSymlink script that is vended as part of LLVM's distribution.

The problem here is a bit complicated. The symlink_clang_headers target creates two symlinks to clang's headers, one under the build directory at lib/swift/clang, and the other under a temporary path.

The one under the temporary path is a bad symlink, and it is only created during the build so that it can be installed. It isn't actually used by the build. Ninja treats the bad symlink as a non-existing file, and since the build rule that creates it has the restat property on it this results in the commands to symlink the clang headers directory running over and over and over again during the build.

This patch prevents that by not generating the bad symlink during the build. Instead we generate it at install time using the LLVMInstallSymlink script that is vended as part of LLVM's distribution.
@llvm-beanz
Copy link
Contributor Author

@swift-ci please smoke test

@jrose-apple
Copy link
Contributor

Seems reasonable to me, but I'd want to make sure it doesn't break our existing install process. @shahmishal, @zisko?

@shahmishal
Copy link
Member

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - 58ca217
Test requested by - @shahmishal

@llvm-beanz
Copy link
Contributor Author

Huh... That error doesn't seem related to my change.

@swift-ci please test platform linux

@llvm-beanz
Copy link
Contributor Author

@swift-ci please test linux platform

@shahmishal
Copy link
Member

LGTM

@llvm-beanz llvm-beanz merged commit 3f0adbd into swiftlang:master Sep 28, 2016
function(swift_install_symlink_component component)
cmake_parse_arguments(
ARG # prefix
"" "LINK_NAME;TARGET;DESTINATION" "" ${ARGN})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chris, one CMake utility that would be useful is a wrapper around cmake_parse_arguments that is self documenting. I.e.:

swift_parse_arguments(
PREFIX Arg
FLAGS ""
OPTIONS "LINK_NAME;TARGET;DESTINATION"
MULTIVALUE_OPTIONS ""
ARGS ${ARGN}).

Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better yet, we should suggest that syntax to the CMake developers and see if they'll run with it.

That said, I generally think that the bar for providing a wrapper around built-in CMake functionality should be pretty high. CMake has excellent online documentation, and providing custom wrappers for built-in functionality makes the code less approachable from someone outside the project. I do like the syntax you're suggesting, but IMO the benefit isn't substantial enough to break from convention.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@llvm-beanz I disagree with you here. We are already in many parts of swift performing these annotations in the comments. It would be better to just make the code self document rather than rely on comments. OR we should strip out all of the comments. I would prefer that we be consistent here. Notice how you left in one of the comments (for the prefix), but removed the one for options, etc. We should be consistent here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to add the full set of comments in. Also, I realized why CMake doesn't support the behavior you suggested, and I think it would be very difficult for us to support it.

Take for example this situation:

swift_parse_args(PREFIX FOO MULTIVALUE_OPTIONS OPTIONS)

What is the expected behavior of that? It could be specifying a multi-value option named "OPTIONS", or defining MULTIVALUE_OPTIONS and OPTIONS as empty.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Please just add in the comments. Thanks!

return()
endif()

foreach(path ${CMAKE_MODULE_PATH})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than iterating over the cmake module path, I wonder if LLVM can just tell us its module path via the exports. I think we have that, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no variable defined in the config files and in-tree builds, so this solution is probably the most portable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the in tree builds, we know the location of this file. For the out of tree builds, we have this:

set(LLVM_CMAKE_DIR "@LLVM_CONFIG_CMAKE_DIR@")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And again that value is already exported. So for instance in my local build:

set(LLVM_CMAKE_DIR "/Volumes/Files/work/solon/llvm/cmake/modules")

The file you are looking for is in that folder.

DESTINATION "lib/swift")
swift_install_symlink_component(clang-resource-dir-symlink
LINK_NAME clang
TARGET ../clang/${CLANG_VERSION}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use an absolute path here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The target is the path the symlink points to, which is intentionally relative to where it gets installed to. That makes it so the install directory can be moved around or relocated without breaking.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

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.

6 participants