1

I have a source file which is valid in (at least) two languages. Say, C and C++ or C and CUDA.

I want to compile this file in both languages, each time into a different library. What's the idiomatic way of doing this in recent versions of CMake?

Notes:

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • So why not just 1. Copy the file. 2. Compile one with one and copy with the other. – KamilCuk Oct 20 '21 at 12:06
  • 1
    @KamilCuk: Why would I want to copy the file? It's one single file, not two of them. If you mean copy the file during generation - that would be really bad, since then I won't have valid debug information. – einpoklum Oct 20 '21 at 12:08
  • `Why would I want to copy the file?` To compile it with a different language. `If you mean copy the file during generation` It doesn't really matter _when_, but with `add_custom_command`. The `LANGUAGE` property is indexed with filenames, so to compile same file with different langague, you have to have a different filename, so just copy it. – KamilCuk Oct 20 '21 at 13:01
  • @KamilCuk: I could create an entirely separate project entirely for the other language. In fact, my perfect clone will write it. Anyway, this won't do. It needs to be the same file, not a copy. I know the `LANGUAGE` property is indexed by filename, and that's what I want to get around. – einpoklum Oct 20 '21 at 13:05
  • 2
    I _think_ source_properties are scoped to directory, so you could I think do something like `set(USELANG C) add_subdirectory(dir uses_c) set(USELANG CXX) add_subdirectory(dir uses_cxx)` and in `dir/CMakeLists.txt` put `set_source_file_properties(file.c_or_cpp PROPERTIES LANGAUGE ${USELANG})`. Please try. – KamilCuk Oct 20 '21 at 13:27

2 Answers2

2

This elaborates on @KamilCuk's suggestion in a comment on the OP, written before I noticed the comment.

The LANGUAGE property is set on the source file itself, which is the core of your question. The documentation for this property describes it being visible in the scope of the directory where it is set. That means that one way to have different languages is to set the property in two different directories. For example:

src/
  CMakeLists.txt
  common/
    main.c
  app1/
    CMakeLists.txt
  app2/
    CMakeLists.txt

src/CMakeLists.txt:

add_subdirectory(app1)
add_subdirectory(app2)

app1/CMakeLists.txt:

set_property(SOURCE ../common/main.c PROPERTY LANGUAGE CXX)
add_executable(app1 ../common/main.c)

app2/CMakeLists.txt:

set_property(SOURCE ../common/main.c PROPERTY LANGUAGE C)
add_executable(app2 ../common/main.c)

This will build main.c into two different targets, with two different LANGUAGE settings.

The docs also hint at being able to set the property explicitly against other directory scopes including binary directories. I was hoping this would help make the job simpler, but I can't get it to work.

Peter
  • 14,559
  • 35
  • 55
0

Since, indeed, LANGUAGE is a per-file property, I believe what should happen - and would allow for a proper idiom here - is to have a binary relation of language-to-use for pairs of (target, source file).

I've suggested this to KitWare in an issue report (gitlab.kitware.com).

einpoklum
  • 118,144
  • 57
  • 340
  • 684