3

I'm trying to write a CMake function that creates an object library of LLVM bitcode files. Here is what I have so far

function(build_llvm_lib OUTPUT SRC)
  if(NOT LLVM_FOUND)
    message(FATAL_ERROR "LLVM build requested but LLVM not found")
  endif()

  set(SRCS ${SRC} ${ARGN})

  set(CMAKE_C_OUTPUT_EXTENSION ".bc")
  set(CMAKE_CXX_OUTPUT_EXTENSION ".bc")
  set(CMAKE_STATIC_LIBRARY_SUFFIX ".bc")

  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -emit-llvm")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -emit-llvm")

  set(CMAKE_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang)
  set(CMAKE_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++)
  set(CMAKE_AR ${LLVM_TOOLS_BINARY_DIR}/llvm-ar)
  set(CMAKE_RANLIB ${LLVM_TOOLS_BINARY_DIR}/llvm-ranlib)

  add_library(${OUTPUT} OBJECT ${SRCS})
endfunction(build_llvm_lib)

However, the problem that I'm having is that even though I am setting the CMake variables like CMAKE_CXX_FLAGS and CMAKE_CXX_OUTPUT_EXTENSION these don't seem to be having any affect (i.e. they are being ignore) when CMake is run. When I look at the generated Makefile these settings don't appear and when I run make a regular object file is built rather than an LLVM bitcode file.

I'm kind of a CMake newb, so can someone please explain what's going on here? Is there some sort of misunderstanding I'm making here with CMake functions?

2
  • 3
    You need to add PARENT_SCOPE, cf. cmake.org/cmake/help/v3.7/command/set.html Commented Oct 26, 2016 at 17:03
  • Excellent, thanks! For some reason CMAKE_<LANG>_OUTPUT_EXTENSION is still being ignored, but some Googling seems to show that this is not unusual. I don't really understand why PARENT_SCOPE works though. Won't this mean that when build_llvm_lib returns future calls to add_library (outside of this function) will also create LLVM bitcode files, rather than regular object files? Commented Oct 26, 2016 at 17:17

1 Answer 1

3

While all CMake variables may have different values when you create different targets, CMake expects some of variables be the same for all targets. Examples of those variables:

  • CMAKE_<LANG>_COMPILER

  • CMAKE_AR

  • CMAKE_RANLIB

  • CMAKE_<LANG>_OUTPUT_EXTENSION

This means that you cannot use different compilers for different targets in the same project. See, e.g. this question.

Variables CMAKE_<LANG>_FLAGS also should be defined globally, for all targets.

Only CMake variables and functions which are propagated to the target's property have per-target meaning.

For example, you may define additional compiler options for concrete targets using commands add_compile_options, add_definitions or by manually setting target's properties COMPILE_FLAGS or COMPILE_DEFINITIONS.


In your build_llvm_lib function body only CMAKE_STATIC_LIBRARY_SUFFIX variable probably has per-target nature: while it is not stated in the documentation, I suspect it just sets SUFFIX property for newly-defined targets.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Ok, so if I understand you correctly I should not be using this approach to begin with? And I would be better off following the answer here and run CMake twice?
Yes, it is better to create distinct project for create libraries with llvm.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.