-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
[llvm][CMake] Check dependency cxx source compiles #68549
[llvm][CMake] Check dependency cxx source compiles #68549
Conversation
If a CMake project doesn't enable the C language, then the CMake FFI and Terminfo find modules will fail their checks for linking. This commit allows projects to enable only C++ by checking if a C compiler is set, and if it is not, it checks whether C++ compilation succeeds.
Hey, LGTM % naming but let's wait for a review from someone who worked on those cmakes. @jackoalan @JDevlieghere as you implemented/reviewed D114327, could you review that PR? Also, @lzaoral does it fix your issue from #53950? @ekilmer did you test it only on git-main version of LLVM? |
@ekilmer Thanks for the PR but in the meantime I've stopped contributing to projects that depend on LLVM so I won't test it. Moreover, unless this change is also backported to LLVM 14, projects will still need to use some workaround for the original issue. |
Is there any reason to not use |
LLVM has C API bindings, so it's possible that a user would only enable the C language. Unconditionally using |
These modules are used when configuring the LLVM build itself. Can you really do that with just a C compiler? I'm aware of the bindings but without a C++ compiler, you can't build the thing it's binding in the first place. So is there a configuration mode where you only build the C bindings against a pre-built LLVM? Is libffi or terminfo used in those C bindings? |
You're correct that building the LLVM project requires a C++ compiler, and I'm not sure if building the C bindings separately is possible, but it doesn't look like it. I'm also not sure if libffi or terminfo are used in the C bindings. However, I think that is beside the point. This PR is fixing downstream consumers of LLVM---those building projects out-of-tree. In the linked issue #53950, the opening post gives a small, standalone CMakeLists.txt that calls A user might want to (or already does) only enable the C compiler, and I think we should continue to support that. Unless the LLVM C bindings were to be split from the other targets (a breaking change), a call to More concretely, the following is an example project that currently works using LLVM 17, 16, 15, and 14 C bindings, and unconditionally using # CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(llvm-c-test LANGUAGES C)
find_package(LLVM REQUIRED)
include_directories(${LLVM_INCLUDE_DIR})
add_executable(sum sum.c)
target_link_libraries(sum PRIVATE LLVM-C) With a sibling file `sum.c`/**
* Copied from https://github.com/QDucasse/LLVM-C/blob/9cfdece261d406f6dcdf90aa42843843707a7a43/examples/Chapter1/sum.c
*
* LLVM equivalent of:
*
* int sum(int a, int b) {
* return a + b;
* }
*/
#include <llvm-c/Core.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/BitWriter.h>
#include <llvm-c/Target.h>
#include <llvm-c/TargetMachine.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[]) {
// Module creation
LLVMModuleRef mod = LLVMModuleCreateWithName("my_module");
// Function prototype creation
LLVMTypeRef param_types[] = { LLVMInt32Type(), LLVMInt32Type() };
LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), param_types, 2, 0);
LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry");
// Builder creation
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, entry);
// Instruction added to the builder
LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp");
LLVMBuildRet(builder, tmp);
//Analysis
char *error = NULL;
LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
LLVMDisposeMessage(error);
// Bitcode writing to file
if (LLVMWriteBitcodeToFile(mod, "sum.bc") != 0) {
fprintf(stderr, "error writing bitcode to file, skipping\n");
}
// Dispose the builder
LLVMDisposeBuilder(builder);
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, it wasn't clear to me that this was functionality was also triggered when including llvm from a downstream project. Thank you for clarifying that and even including an example. This shows that it's indeed necessary to check both check_c_source_compiles
and check_cxx_source_compiles
. LGTM!
@JDevlieghere Great! I don't have commit access, so would you (or someone else we can ping) be able to help me out with landing this? Thank you for the review! |
If a CMake project doesn't enable the C language, then the CMake FFI and Terminfo find modules will fail their checks for compilation and linking.
This commit allows projects to enable only C++ by first checking if a C compiler is set before testing C source compilation; if not, it checks whether C++ compilation succeeds.
Fixes #53950