bindings, build: fix bindings and visualizer build

Includes:
- scan python scripts
- run python scripts from ns3
- replace visualizer file copy with configure_file to prevent cmake refreshes
- replace ns__init__.py file copy with configure_file to prevent cmake refreshes
- fix bindings scanning with cmake
- pass include directories to modulegen for castxml consumption
- add missing parameters of Recv in python-unit-tests.py
- change apiscan targets from apiscan-module to libmodule-apiscan
- change bindings targets from module-bingings to libmodule-bindings
- scanning and bindings build tests
- scan scratch python scripts
- replace FindPython3 with FindPython to be compatible with CMake 3.10
- do not export private visual-simulator-impl.h
- do not export udp-socket-impl.h
- use .so suffix for bindings on Mac instead of .dylib
This commit is contained in:
Gabriel Ferreira
2022-01-26 01:53:28 -03:00
parent 192019ce94
commit 9342082c53
16 changed files with 330 additions and 102 deletions

View File

@@ -30,7 +30,7 @@
# Hidden argument (this is not a function, so you don't really need to pass arguments explicitly)
# deprecated_header_files = "list;of;deprecated;.h;files", copy won't get triggered if deprecated_header_files isn't set
# ignore_pch = TRUE or FALSE, prevents the PCH from including undesired system libraries (e.g. custom GLIBC for DCE)
# module_enabled_features = "list;of;enabled;features;for;this;module" (used by fd-net-device)
macro(
build_lib_impl
@@ -42,6 +42,7 @@ macro(
test_sources
#deprecated_header_files
#ignore_pch
#module_enabled_features
)
# cmake-format: on
@@ -215,24 +216,23 @@ macro(
# Build lib examples if requested
if(${ENABLE_EXAMPLES})
if((EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/examples)
AND (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/examples/CMakeLists.txt)
)
add_subdirectory(examples)
endif()
if((EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/example)
AND (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/example/CMakeLists.txt)
)
add_subdirectory(example)
endif()
foreach(example_folder example;examples)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${example_folder})
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${example_folder}/CMakeLists.txt)
add_subdirectory(${example_folder})
endif()
scan_python_examples(${CMAKE_CURRENT_SOURCE_DIR}/${example_folder})
endif()
endforeach()
endif()
# Get architecture pair for python bindings
set(arch gcc_ILP32)
set(arch_flag)
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
if((${CMAKE_SIZEOF_VOID_P} EQUAL 8) AND (NOT APPLE))
set(arch gcc_LP64)
set(arch_flag -m64)
set(arch_flags -m64)
else()
set(arch gcc_ILP32)
set(arch_flags)
endif()
# Add target to scan python bindings
@@ -243,49 +243,63 @@ macro(
${PROJECT_SOURCE_DIR}/${folder}/${libname}/bindings
)
file(MAKE_DIRECTORY ${bindings_output_folder})
set(module_api ${bindings_output_folder}/modulegen__${arch}.py)
set(module_api_ILP32 ${bindings_output_folder}/modulegen__gcc_ILP32.py)
set(module_api_LP64 ${bindings_output_folder}/modulegen__gcc_LP64.py)
set(modulescan_modular_command
${Python3_EXECUTABLE}
${Python_EXECUTABLE}
${PROJECT_SOURCE_DIR}/bindings/python/ns3modulescan-modular.py
)
# To build the header map for the module, we start by copying the headers
# and prepending the dictionary start
set(header_map "{\\\"${header_files};")
set(header_map "")
# We need a python map that takes header.h to module e.g. "ptr.h": "core"
foreach(header ${header_files})
# header is a relative path to the current working directory
get_filename_component(
header_name ${CMAKE_CURRENT_SOURCE_DIR}/${header} NAME
)
string(APPEND header_map "\"${header_name}\":\"${libname}\",")
endforeach()
# We then remove model/ helper/ prefixes e.g.
# {'model/angles.h;model/antenna-model.h;... ->
# {'angles.h;antenna-model.h;...)
string(REPLACE "model/" "" header_map "${header_map}")
string(REPLACE "helper/" "" header_map "${header_map}")
# Now we replace list entry separators (;) with ending of the string quote
# ("), followed by the relative module e.g.
# {"model/angles.h;model/antenna-model.h;... -> {"angles.h" : "antenna",
# "antenna-model.h": "antenna", "...)
string(REPLACE ";" "\\\": \\\"${libname}\\\", \\\"" header_map
"${header_map}"
set(ns3-headers-to-module-map "${ns3-headers-to-module-map}${header_map}"
CACHE INTERNAL "Map connecting headers to their modules"
)
# We now remove the last character ("), which needs to be replaced with a
# (}), to close the dictionary e.g. "antenna-model.h" : "antenna", " ->
# "antenna-model.h" : "antenna"
string(LENGTH "${header_map}" header_map_len)
math(EXPR header_map_len "${header_map_len}-3")
string(SUBSTRING "${header_map}" 0 ${header_map_len} header_map)
# API scan needs the include directories to find a few headers (e.g. mpi.h)
get_target_property(include_dirs ${lib${libname}} INCLUDE_DIRECTORIES)
set(modulegen_include_dirs)
foreach(include_dir ${include_dirs})
if(include_dir MATCHES "<")
# Skip CMake build and install interface includes
continue()
else()
# Append the include directory to a list
set(modulegen_include_dirs ${modulegen_include_dirs} -I${include_dir})
endif()
endforeach()
# Append end of dictionary (})
string(APPEND header_map "}")
set(module_to_generate_api ${module_api_ILP32})
set(LP64toILP32)
if("${arch}" STREQUAL "gcc_LP64")
set(module_to_generate_api ${module_api_LP64})
set(LP64toILP32
${Python_EXECUTABLE}
${PROJECT_SOURCE_DIR}/buildsupport/pybindings_LP64_to_ILP32.py
${module_api_LP64} ${module_api_ILP32}
)
endif()
add_custom_target(
apiscan-${lib${libname}}
COMMAND ${modulescan_modular_command} ${CMAKE_OUTPUT_DIRECTORY} ${libname}
${header_map} ${module_api} ${arch_flag}
${lib${libname}}-apiscan
COMMAND
${modulescan_modular_command} ${CMAKE_OUTPUT_DIRECTORY} ${libname}
${PROJECT_BINARY_DIR}/header_map.json ${module_to_generate_api}
\"${arch_flags} ${modulegen_include_dirs}\"
COMMAND ${LP64toILP32}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${lib${libname}}
)
add_dependencies(apiscan-all apiscan-${lib${libname}})
add_dependencies(apiscan-all ${lib${libname}}-apiscan)
endif()
# Build pybindings if requested and if bindings subfolder exists in
@@ -316,10 +330,12 @@ macro(
if((NOT EXISTS ${module_hdr}) OR (NOT EXISTS ${module_src})) # OR TRUE) # to
# force
# reprocessing
string(REPLACE ";" "," ENABLED_FEATURES "${ns3-libs}")
string(REPLACE ";" "," ENABLED_FEATURES
"${ns3-libs};${module_enabled_features}"
)
set(modulegen_modular_command
GCC_RTTI_ABI_COMPLETE=True NS3_ENABLED_FEATURES="${ENABLED_FEATURES}"
${Python3_EXECUTABLE}
${Python_EXECUTABLE}
${PROJECT_SOURCE_DIR}/bindings/python/ns3modulegen-modular.py
)
execute_process(
@@ -354,11 +370,12 @@ macro(
${CMAKE_CURRENT_SOURCE_DIR}/bindings/scan-header.h
)
endif()
add_library(${libname}-bindings SHARED "${python_module_files}")
set(bindings-name lib${libname}-bindings)
add_library(${bindings-name} SHARED "${python_module_files}")
target_include_directories(
${libname}-bindings PUBLIC ${Python3_INCLUDE_DIRS}
${bindings_output_folder}
${bindings-name} PUBLIC ${Python_INCLUDE_DIRS} ${bindings_output_folder}
)
target_compile_options(${bindings-name} PRIVATE -Wno-error)
# If there is any, remove the "lib" prefix of libraries (search for
# "set(lib${libname}")
@@ -367,35 +384,45 @@ macro(
string(REPLACE ";" "-bindings;" bindings_to_link
"${ns_libraries_to_link};"
) # add -bindings suffix to all lib${name}
string(REPLACE "lib" "" bindings_to_link "${bindings_to_link}"
)# remove lib prefix from all lib${name}-bindings
endif()
target_link_libraries(
${libname}-bindings
${bindings-name}
PUBLIC ${LIB_AS_NEEDED_PRE} ${lib${libname}} "${bindings_to_link}"
"${libraries_to_link}" ${LIB_AS_NEEDED_POST}
PRIVATE ${Python_LIBRARIES}
)
target_include_directories(
${libname}-bindings PRIVATE ${PROJECT_SOURCE_DIR}/src/core/bindings
${bindings-name} PRIVATE ${PROJECT_SOURCE_DIR}/src/core/bindings
)
set(suffix)
if(APPLE)
# Python doesn't like Apple's .dylib and will refuse to load bindings
# unless its an .so
set(suffix SUFFIX .so)
endif()
# Set binding library name and output folder
set_target_properties(
${libname}-bindings
PROPERTIES OUTPUT_NAME ${prefix}${libname_sub} PREFIX ""
${bindings-name}
PROPERTIES OUTPUT_NAME ${prefix}${libname_sub}
PREFIX ""
${suffix}
LIBRARY_OUTPUT_DIRECTORY
${CMAKE_OUTPUT_DIRECTORY}/bindings/python/ns
)
set(ns3-python-bindings-modules
"${libname}-bindings;${ns3-python-bindings-modules}"
"${bindings-name};${ns3-python-bindings-modules}"
CACHE INTERNAL "list of modules python bindings"
)
# Make sure all bindings are built before building the visualizer module
# that makes use of them
if(NOT (${name} STREQUAL visualizer))
add_dependencies(${libvisualizer} ${libname}-bindings)
if(${ENABLE_VISUALIZER})
if(NOT (${name} STREQUAL visualizer))
add_dependencies(${libvisualizer} ${bindings-name})
endif()
endif()
endif()

View File

@@ -18,15 +18,17 @@
function(generate_buildstatus)
# Build build-status.py file consumed by test.py
set(buildstatus_contents "#! /usr/bin/env python3\n\n")
string(APPEND buildstatus_contents "ns3_runnable_programs = [")
string(APPEND buildstatus_contents "ns3_runnable_programs = [")
foreach(executable ${ns3-execs})
string(APPEND buildstatus_contents "'${executable}', ")
string(APPEND buildstatus_contents "'${executable}',\n")
endforeach()
string(APPEND buildstatus_contents "]\n\n")
string(APPEND buildstatus_contents "ns3_runnable_scripts = [") # missing
# support
string(APPEND buildstatus_contents "ns3_runnable_scripts = [")
foreach(executable ${ns3-execs-py})
string(APPEND buildstatus_contents "'${executable}',\n")
endforeach()
string(APPEND buildstatus_contents "]\n\n")
file(WRITE ${CMAKE_OUTPUT_DIRECTORY}/build-status.py

View File

@@ -65,6 +65,9 @@ function(generate_c4che_cachepy)
cache_cmake_flag(NS3_BRITE "ENABLE_BRITE" cache_contents)
cache_cmake_flag(NS3_ENABLE_SUDO "ENABLE_SUDO" cache_contents)
cache_cmake_flag(NS3_PYTHON_BINDINGS "ENABLE_PYTHON_BINDINGS" cache_contents)
cache_cmake_flag(
NS3_SCAN_PYTHON_BINDINGS "ENABLE_SCAN_PYTHON_BINDINGS" cache_contents
)
string(APPEND cache_contents "EXAMPLE_DIRECTORIES = [")
foreach(example_folder ${ns3-example-folders})
@@ -75,7 +78,7 @@ function(generate_c4che_cachepy)
string(APPEND cache_contents "APPNAME = 'ns'\n")
string(APPEND cache_contents "BUILD_PROFILE = '${build_profile}'\n")
string(APPEND cache_contents "VERSION = '${NS3_VER}' \n")
string(APPEND cache_contents "PYTHON = ['${Python3_EXECUTABLE}']\n")
string(APPEND cache_contents "PYTHON = ['${Python_EXECUTABLE}']\n")
mark_as_advanced(VALGRIND)
find_program(VALGRIND valgrind)