Skip to content

Commit

Permalink
build: split macros-and-definitions.cmake
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabrielcarvfer committed Oct 27, 2023
1 parent daab1d6 commit c9016a5
Show file tree
Hide file tree
Showing 14 changed files with 1,395 additions and 1,220 deletions.
7 changes: 7 additions & 0 deletions build-support/cmake-format.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ additional_commands:
LIBRARY_NAMES : '*'
PATH_SUFFIXES : '*'
SEARCH_PATHS : '*'
check_deps:
pargs:
nargs: 1
kwargs:
CMAKE_PACKAGES : '*'
EXECUTABLES : '*'
PYTHON_PACKAGES : '*'

format:
tab_size: 2
Expand Down
61 changes: 61 additions & 0 deletions build-support/custom-modules/ns3-check-dependencies.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright (c) 2023 Universidade de Brasília
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 2 as published by the Free
# Software Foundation;
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author: Gabriel Ferreira <[email protected]>

# function used to search for package and program dependencies than store list
# of missing dependencies in the list whose name is stored in missing_deps
function(check_deps missing_deps)
set(multiValueArgs CMAKE_PACKAGES EXECUTABLES PYTHON_PACKAGES)
cmake_parse_arguments(
"DEPS" "" "${OUTPUT_VAR_NAME}" "${multiValueArgs}" ${ARGN}
)

set(local_missing_deps)
# Search for package dependencies
foreach(package ${DEPS_CMAKE_PACKAGES})
find_package(${package})
if(NOT ${${package}_FOUND})
list(APPEND local_missing_deps ${package})
endif()
endforeach()

# And for program dependencies
foreach(program ${DEPS_EXECUTABLES})
# CMake likes to cache find_* to speed things up, so we can't reuse names
# here or it won't check other dependencies
string(TOUPPER ${program} upper_${program})
mark_as_advanced(${upper_${program}})
find_program(
${upper_${program}} ${program} HINTS ${3RD_PARTY_FIND_PROGRAM_HINTS}
)
if("${${upper_${program}}}" STREQUAL "${upper_${program}}-NOTFOUND")
list(APPEND local_missing_deps ${program})
endif()
endforeach()

foreach(package ${DEPS_PYTHON_PACKAGES})
execute_process(
COMMAND ${Python3_EXECUTABLE} -c "import ${package}"
RESULT_VARIABLE return_code OUTPUT_QUIET ERROR_QUIET
)
if(NOT (${return_code} EQUAL 0))
list(APPEND local_missing_deps ${package})
endif()
endforeach()

# Store list of missing dependencies in the parent scope
set(${missing_deps} ${local_missing_deps} PARENT_SCOPE)
endfunction()
21 changes: 21 additions & 0 deletions build-support/custom-modules/ns3-cmake-package.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@
#
# Author: Gabriel Ferreira <[email protected]>

include(GNUInstallDirs)

# Set RPATH not too need LD_LIBRARY_PATH after installing
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:$ORIGIN/:$ORIGIN/../lib")

# Add the 64 suffix to the library path when manually requested with the
# -DNS3_USE_LIB64=ON flag. May be necessary depending on the target platform.
# This is used to properly build the manylinux pip wheel.
if(${NS3_USE_LIB64})
link_directories(${CMAKE_OUTPUT_DIRECTORY}/lib64)
set(CMAKE_INSTALL_RPATH
"${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib64:$ORIGIN/:$ORIGIN/../lib64"
)
endif()

# cmake-format: off
# You are a wizard, Harry!
# source: https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling
# cmake-format: on
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

function(build_required_and_libs_lists module_name visibility libraries
all_ns3_libraries
)
Expand Down
128 changes: 128 additions & 0 deletions build-support/custom-modules/ns3-compiler-and-linker-support.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Copyright (c) 2023 Universidade de Brasília
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 2 as published by the Free
# Software Foundation;
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA
#
# Author: Gabriel Ferreira <[email protected]>

# Compiler-specific version checks and flag/feature setting should be done here

# Identify compiler and check version
set(below_minimum_msg "compiler is below the minimum required version")
set(CLANG FALSE)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${AppleClang_MinVersion})
message(
FATAL_ERROR
"Apple Clang ${CMAKE_CXX_COMPILER_VERSION} ${below_minimum_msg} ${AppleClang_MinVersion}"
)
endif()
set(CLANG TRUE)
endif()

if((NOT CLANG) AND ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang"))
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${Clang_MinVersion})
message(
FATAL_ERROR
"Clang ${CMAKE_CXX_COMPILER_VERSION} ${below_minimum_msg} ${Clang_MinVersion}"
)
endif()
set(CLANG TRUE)
endif()

if(CLANG)
if(${NS3_COLORED_OUTPUT} OR "$ENV{CLICOLOR}")
add_definitions(-fcolor-diagnostics) # colorize clang++ output
endif()
endif()

set(GCC FALSE)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${GNU_MinVersion})
message(
FATAL_ERROR
"GNU ${CMAKE_CXX_COMPILER_VERSION} ${below_minimum_msg} ${GNU_MinVersion}"
)
endif()
if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.2.0"))
# PCH causes weird errors on certain versions of GCC when C++20 is enabled
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106799
set(NS3_PRECOMPILE_HEADERS OFF
CACHE BOOL "Precompile module headers to speed up compilation" FORCE
)
endif()
if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1.0")
AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "12.3.2")
)
# Disable warnings-as-errors for certain versions of GCC when C++20 is
# enabled https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105545
add_compile_options(-Wno-restrict)
endif()
set(GCC TRUE)
add_definitions(-fno-semantic-interposition)
if(${NS3_COLORED_OUTPUT} OR "$ENV{CLICOLOR}")
add_definitions(-fdiagnostics-color=always) # colorize g++ output
endif()
endif()
unset(below_minimum_msg)

set(LIB_AS_NEEDED_PRE)
set(LIB_AS_NEEDED_POST)
set(STATIC_LINK_FLAGS -static -static-libstdc++ -static-libgcc)
if(${GCC} AND NOT APPLE)
# using GCC
set(LIB_AS_NEEDED_PRE -Wl,--no-as-needed)
set(LIB_AS_NEEDED_POST -Wl,--as-needed)
set(LIB_AS_NEEDED_PRE_STATIC -Wl,--whole-archive,-Bstatic)
set(LIB_AS_NEEDED_POST_STATIC -Wl,--no-whole-archive)
set(LIB_AS_NEEDED_POST_STATIC_DYN -Wl,-Bdynamic,--no-whole-archive)
endif()

if(${CLANG} AND APPLE)
# using Clang set(LIB_AS_NEEDED_PRE -all_load)
set(LIB_AS_NEEDED_POST)
set(LIB_AS_NEEDED_PRE_STATIC -Wl,-all_load)
set(STATIC_LINK_FLAGS)
endif()

if(${NS3_FAST_LINKERS})
# Search for faster linkers mold and lld, and use them if available
mark_as_advanced(MOLD LLD)
find_program(MOLD mold)
find_program(LLD ld.lld)

# USING_FAST_LINKER will be defined if a fast linker is being used and its
# content will correspond to the fast linker name

# Mold support was added in GCC 12.1.0
if(NOT USING_FAST_LINKER
AND NOT (${MOLD} STREQUAL "MOLD-NOTFOUND")
AND LINUX
AND ${GCC}
AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.1.0)
)
set(USING_FAST_LINKER MOLD)
add_link_options("-fuse-ld=mold")
endif()

if(NOT USING_FAST_LINKER AND NOT (${LLD} STREQUAL "LLD-NOTFOUND")
AND (${GCC} OR ${CLANG})
)
set(USING_FAST_LINKER LLD)
add_link_options("-fuse-ld=lld")
if(WIN32)
# Clear unsupported linker flags on Windows
set(LIB_AS_NEEDED_PRE)
endif()
endif()
endif()
162 changes: 162 additions & 0 deletions build-support/custom-modules/ns3-executables.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
function(set_runtime_outputdirectory target_name output_directory target_prefix)
# Prevent duplicate '/' in EXECUTABLE_DIRECTORY_PATH, since it gets translated
# to doubled underlines and will cause the ns3 script to fail
string(REPLACE "//" "/" output_directory "${output_directory}")

set(ns3-exec-outputname ns${NS3_VER}-${target_name}${build_profile_suffix})
set(ns3-execs "${output_directory}${ns3-exec-outputname};${ns3-execs}"
CACHE INTERNAL "list of c++ executables"
)
set(ns3-execs-clean "${target_prefix}${target_name};${ns3-execs-clean}"
CACHE INTERNAL
"list of c++ executables without version prefix and build suffix"
)

set_target_properties(
${target_prefix}${target_name}
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${output_directory}
RUNTIME_OUTPUT_NAME ${ns3-exec-outputname}
)
if(${XCODE})
# Is that so hard not to break people's CI, AAPL?? Why would you output the
# targets to a Debug/Release subfolder? Why?
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
set_target_properties(
${target_prefix}${target_name}
PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${output_directory}
RUNTIME_OUTPUT_NAME_${OUTPUTCONFIG} ${ns3-exec-outputname}
)
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
endif()

if(${ENABLE_TESTS})
add_dependencies(all-test-targets ${target_prefix}${target_name})
# Create a CTest entry for each executable
if(WIN32)
# Windows require this workaround to make sure the DLL files are located
add_test(
NAME ctest-${target_prefix}${target_name}
COMMAND
${CMAKE_COMMAND} -E env
"PATH=$ENV{PATH};${CMAKE_RUNTIME_OUTPUT_DIRECTORY};${CMAKE_LIBRARY_OUTPUT_DIRECTORY}"
${ns3-exec-outputname}
WORKING_DIRECTORY ${output_directory}
)
else()
add_test(NAME ctest-${target_prefix}${target_name}
COMMAND ${ns3-exec-outputname}
WORKING_DIRECTORY ${output_directory}
)
endif()
endif()

if(${NS3_CLANG_TIMETRACE})
add_dependencies(timeTraceReport ${target_prefix}${target_name})
endif()
endfunction(set_runtime_outputdirectory)

function(get_scratch_prefix prefix)
# /path/to/ns-3-dev/scratch/nested-subdir
set(temp ${CMAKE_CURRENT_SOURCE_DIR})
# remove /path/to/ns-3-dev/ to get scratch/nested-subdir
string(REPLACE "${PROJECT_SOURCE_DIR}/" "" temp "${temp}")
# replace path separators with underlines
string(REPLACE "/" "_" temp "${temp}")
# save the prefix value to the passed variable
set(${prefix} ${temp}_ PARENT_SCOPE)
endfunction()

function(build_exec)
# Argument parsing
set(options IGNORE_PCH STANDALONE)
set(oneValueArgs EXECNAME EXECNAME_PREFIX EXECUTABLE_DIRECTORY_PATH
INSTALL_DIRECTORY_PATH
)
set(multiValueArgs SOURCE_FILES HEADER_FILES LIBRARIES_TO_LINK DEFINITIONS)
cmake_parse_arguments(
"BEXEC" "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}
)

# Resolve nested scratch prefixes without user intervention
string(REPLACE "${PROJECT_SOURCE_DIR}" "" relative_path
"${CMAKE_CURRENT_SOURCE_DIR}"
)
if("${relative_path}" MATCHES "scratch" AND "${BEXEC_EXECNAME_PREFIX}"
STREQUAL ""
)
get_scratch_prefix(BEXEC_EXECNAME_PREFIX)
endif()

add_executable(
${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME} "${BEXEC_SOURCE_FILES}"
)

target_compile_definitions(
${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME} PUBLIC ${BEXEC_DEFINITIONS}
)

if(${PRECOMPILE_HEADERS_ENABLED} AND (NOT ${BEXEC_IGNORE_PCH}))
target_precompile_headers(
${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME} REUSE_FROM stdlib_pch_exec
)
endif()

if(${NS3_STATIC} AND (NOT BEXEC_STANDALONE))
target_link_libraries(
${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME} ${LIB_AS_NEEDED_PRE_STATIC}
${lib-ns3-static}
)
elseif(${NS3_MONOLIB} AND (NOT BEXEC_STANDALONE))
target_link_libraries(
${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME} ${LIB_AS_NEEDED_PRE}
${lib-ns3-monolib} ${LIB_AS_NEEDED_POST}
)
else()
target_link_libraries(
${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME} ${LIB_AS_NEEDED_PRE}
"${BEXEC_LIBRARIES_TO_LINK}" ${LIB_AS_NEEDED_POST}
)
endif()

set_runtime_outputdirectory(
"${BEXEC_EXECNAME}" "${BEXEC_EXECUTABLE_DIRECTORY_PATH}/"
"${BEXEC_EXECNAME_PREFIX}"
)

if(BEXEC_INSTALL_DIRECTORY_PATH)
install(TARGETS ${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME}
EXPORT ns3ExportTargets
RUNTIME DESTINATION ${BEXEC_INSTALL_DIRECTORY_PATH}
)
get_property(
filename TARGET ${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME}
PROPERTY RUNTIME_OUTPUT_NAME
)
add_custom_target(
uninstall_${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME}
COMMAND
rm ${CMAKE_INSTALL_PREFIX}/${BEXEC_INSTALL_DIRECTORY_PATH}/${filename}
)
add_dependencies(
uninstall uninstall_${BEXEC_EXECNAME_PREFIX}${BEXEC_EXECNAME}
)
endif()
endfunction(build_exec)

function(scan_python_examples path)
# Skip python examples search in case the bindings are disabled
if(NOT ${ENABLE_PYTHON_BINDINGS})
return()
endif()

# Search for python examples
file(GLOB_RECURSE python_examples ${path}/*.py)
foreach(python_example ${python_examples})
if(NOT (${python_example} MATCHES "examples-to-run"))
set(ns3-execs-py "${python_example};${ns3-execs-py}"
CACHE INTERNAL "list of python scripts"
)
endif()
endforeach()
endfunction()
Loading

0 comments on commit c9016a5

Please sign in to comment.