1

I have a subdirectory containing Python language bindings of the project, and I want to build it for several Python version (Python 2 and 3). How can I do that? I thought to create two bindirs from the same source first:

add_subdirectory(python, python2)
add_subdirectory(python, python3)

[edit] However, they need specific parameters, and so I tried to set them in advance:

set(PYTHON_INCLUDE_PATH /usr/include/python2.7)
[...]
add_subdirectory(python, python2)
set(PYTHON_INCLUDE_PATH /usr/include/python3.6)
[...]
add_subdirectory(python, python3)

However, then Cmake complains about duplicated target names. How can I solve this? Or is there a better way to run multiple builds from the same source?

olebole
  • 521
  • 4
  • 17

1 Answers1

0

The CMakeLists.txt file in the python subdir can add multiple targets via add_executable or add_library or (add_custom_target and add_custom_command). Each target added in this manner will need a different target name so it would probably look something like this:

add_libary(my_python2_bindings <list_of_sources>)
add_library(my_python3_bindings <another_list_of_sources>)

The drawback is that both can't use the same name as the target name, which is what the ultimate file name will be based on. If that's a requirement you could use set the target properties for the output name and for where it is created.

 project(my_python_bindings)

 add_libary(my_python2_bindings <list_of_sources>)
 set_target_properties(my_python2_bindings PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
 set_target_properties(my_python2_bindings PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python2")


 add_library(my_python3_bindings <another_list_of_sources>)
 set_target_properties(my_python3_bindings PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
 set_target_properties(my_python3_bindings PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python3")

Edit: for many python versions do something like this in the CMakeLists.txt in the python subdir you would have a list containing all python versions PYTHON_VERSION_LIST and then

foreach(version ${PYTHON_VERSION_LIST})
  add_library(my_python${version}_bindings <list_of_sources>)
  set_target_properties(my_python${version}_bindings PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
  set_target_properties(my_python${version}_bindings PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python3")
endforeach()

But now you need to add an if clause for different source lists for each version. In that case its probably easier to just expand my original example to be 2.7, 3.5, and 3.6 instead of only 2 and 3.

Also, if each version is genuinely different like it sounds like they are, you probably want to think hard about giving them all the same filename.

therealjumbo
  • 1,079
  • 1
  • 10
  • 14
  • The problem is that there are not just two fixed Python versions, but several (2.7, 3.5, 3.6 in the moment), and I wanted to put the `add_subdir` within a loop over the actual available Python versions. The problem could probably be solved by having parameterized target names, like `python_bindings_${PYTHON_VERSION}`. Is this possible? – olebole Sep 05 '17 at 19:38
  • You can also parameterize variables like this: `add_library(my_python${version}_bindings ${SRC_${version}})` to get different source lists for each case. That will expand to `add_library(my_python3.5_bindings ${SRC_3.5})` – therealjumbo Sep 05 '17 at 22:01