Skip to content

Commit

Permalink
ENH: Provide a cmake script for build & install from source
Browse files Browse the repository at this point in the history
The cmake/TBBBuildInstallScript.cmake allows for building TBB
in a temporary build directory under the mandated TBB build
heirarchy.  From the tempory build directory the headers, libraries,
and CMake package config files are installed in relocatable directory
heirachy that mimics the common unix scheme of

{install_prefix}/lib/lib*.[so|dylib|a]
{install_prefix}/lib/cmake/TBB/*.cmake
{install_prefix}include/tbb/*.h

NOTE: The {install_prefix}/lib/cmake/TBB/*.cmake files use relative
      paths, so these files are relocatable to any {install_prefix}
      after the initial install occurs.

NOTE: The TBBConfigForSource.cmake.in and TBBConfig.cmake.in files
      were merged as they only differed in how they set the
      _tbb_release_lib_dir, _tbb_debug_lib_dir, _tbb_include_dir
      variables, so that is now managed by a simple if() statement
      where the argument of the if is hard-coded at configure time.

NOTE: A test case that builds a minimal program from the installed
      directory has been added.

NOTE: TBBBiuld now exposes options to support more flexible building
      while maintaining backwards compatiblity with the default
      settings.

NOTE: Moved platform default values to TBBPlatformDefaults.cmake
      so that they are used consistently across units.

Example invocation to configure, build, install, and test against
installed binaries.

cmake  \
     -DCMAKE_INSTALL_PREFIX=/tmp/tbbinstall                   \
     -DTBB_BUILD_DIR:PATH=/tmp/buildtbb                       \
     -DTBB_BUILD_PREFIX:STRING=unix_cmake_build               \
     -DTBB_RELATIVE_CMAKE_CONFIG_PATH:PATH=lib/cmake/TBB      \
     -DTBB_LIBDIR_NAME:STRING=lib                             \
     -DTBB_COMPILER:STRING=clang                              \
     -DTBB_BUILD_STATIC:BOOL=ON                               \
     -DTBB_BUILD_SHARED:BOOL=ON                               \
     -DTBB_DO_EXTERNAL_CMAKE_BUILD_TEST:BOOL=ON               \
     -P cmake/TBBBuildInstallScript.cmake
  • Loading branch information
hjmjohnson committed Jan 29, 2019
1 parent 010ae25 commit e873222
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 154 deletions.
58 changes: 39 additions & 19 deletions cmake/TBBBuild.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#
# Usage:
# include(TBBBuild.cmake)
# tbb_build(ROOT <tbb_root> MAKE_ARGS <arg1> [... <argN>])
# tbb_build(TBB_ROOT <tbb_root> MAKE_ARGS <arg1> [... <argN>])
# find_package(TBB <options>)
#

Expand All @@ -33,10 +33,11 @@ set(_tbb_cmake_module_path ${CMAKE_CURRENT_LIST_DIR})
# Builds Intel TBB.
#
# Parameters:
# TBB_ROOT <directory> - path to Intel TBB root directory (with sources);
# TBB_ROOT <directory> - path to Intel TBB root directory (with sources); #store <variable>-NOTFOUND otherwise.
# SYSTEM_NAME - The system name for the binaries (i.e. Darwin/Linux/Windows/Android)
# MAKE_ARGS <list> - user-defined arguments to be passed to make-tool;
# CONFIG_DIR <variable> - store location of the created TBBConfig if the build was ok, store <variable>-NOTFOUND otherwise.
#
# CONFIG_DIR <variable> - store location of the created TBBConfig if the build was ok, # store CONFIG_DIR=${TBB_DIR}/cmake
# CONFIG_FOR_INSTALL - Whether to config to point to the install directory (ON) or the source directory (OFF)
function(tbb_build)
# NOTE: internal function are used to hide them from user.

Expand Down Expand Up @@ -111,8 +112,9 @@ function(tbb_build)
# RELEASE_DIR <variable> - store normalized (CMake) path to release directory
# DEBUG_DIR <variable> - store normalized (CMake) path to debug directory
#
#
function(tbb_get_build_paths_from_make_args)
set(oneValueArgs RELEASE_DIR DEBUG_DIR)
set(oneValueArgs RELEASE_DIR DEBUG_DIR BUILD_DIR)
set(multiValueArgs MAKE_ARGS)
cmake_parse_arguments(tbb_GBPFMA "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

Expand All @@ -132,27 +134,31 @@ function(tbb_build)

set(${tbb_GBPFMA_RELEASE_DIR} ${tbb_release_dir} PARENT_SCOPE)
set(${tbb_GBPFMA_DEBUG_DIR} ${tbb_debug_dir} PARENT_SCOPE)
set(${tbb_GBPFMA_BUILD_DIR} ${tbb_build_dir} PARENT_SCOPE)
endfunction()

# -------------------- #
# Function entry point #
# -------------------- #
set(oneValueArgs TBB_ROOT CONFIG_DIR)
set(options CONFIG_FOR_INSTALL)
set(oneValueArgs TBB_ROOT SYSTEM_NAME CONFIG_DIR)
set(multiValueArgs MAKE_ARGS)
cmake_parse_arguments(tbb_build "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

if (NOT EXISTS "${tbb_build_TBB_ROOT}/Makefile" OR NOT EXISTS "${tbb_build_TBB_ROOT}/src")
message(STATUS "Intel TBB can not be built: Makefile or src directory was not found in ${tbb_build_TBB_ROOT}")
set(${tbb_build_CONFIG_DIR} ${tbb_build_CONFIG_DIR}-NOTFOUND PARENT_SCOPE)
set(${tbb_build_TBB_ROOT} ${tbb_build_TBB_ROOT}-NOTFOUND PARENT_SCOPE)
return()
endif()
if ( NOT tbb_build_CONFIG_DIR )
set(tbb_build_CONFIG_DIR ${tbb_build_TBB_ROOT}/cmake )
endif()

set(make_tool_name make)
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
set(make_tool_name gmake)
elseif (CMAKE_SYSTEM_NAME MATCHES "Android")
set(make_tool_name ndk-build)
set(tbb_system_name ${CMAKE_SYSTEM_NAME})
if (tbb_build_SYSTEM_NAME)
set(tbb_system_name ${tbb_build_SYSTEM_NAME})
endif()
include(${CMAKE_CURRENT_LIST_DIR}/TBBPlatformDefaults.cmake)

find_program(TBB_MAKE_TOOL ${make_tool_name} DOC "Make-tool to build Intel TBB.")
mark_as_advanced(TBB_MAKE_TOOL)
Expand Down Expand Up @@ -183,15 +189,29 @@ function(tbb_build)

tbb_get_build_paths_from_make_args(MAKE_ARGS ${tbb_make_args}
RELEASE_DIR tbb_release_dir
DEBUG_DIR tbb_debug_dir)
DEBUG_DIR tbb_debug_dir
BUILD_DIR tbb_build_dir)

include(${_tbb_cmake_module_path}/TBBMakeConfig.cmake)
tbb_make_config(TBB_ROOT ${tbb_build_TBB_ROOT}
SYSTEM_NAME ${CMAKE_SYSTEM_NAME}
CONFIG_DIR tbb_config_dir
CONFIG_FOR_SOURCE
if (tbb_build_CONFIG_FOR_INSTALL )
message(STATUS "Generating TBBConfig.cmake for installed reference")
tbb_make_config(TBB_ROOT ${tbb_build_TBB_ROOT}
TBB_BUILD_DIR ${tbb_build_dir}
SYSTEM_NAME ${CMAKE_SYSTEM_NAME}
CONFIG_DIR tbb_config_dir
SAVE_TO ${tbb_build_CONFIG_DIR}
)
else()
message(STATUS "Generating TBBConfig.cmake for source reference")
tbb_make_config(TBB_ROOT ${tbb_build_TBB_ROOT}
SYSTEM_NAME ${CMAKE_SYSTEM_NAME}
CONFIG_DIR tbb_config_dir
SAVE_TO ${tbb_build_CONFIG_DIR}
CONFIG_FOR_SOURCE
TBB_RELEASE_DIR ${tbb_release_dir}
TBB_DEBUG_DIR ${tbb_debug_dir})
TBB_DEBUG_DIR ${tbb_debug_dir}
)
endif()

set(${tbb_build_CONFIG_DIR} ${tbb_config_dir} PARENT_SCOPE)
set(tbb_build_CONFIG_DIR ${tbb_config_dir} PARENT_SCOPE)
endfunction()
217 changes: 217 additions & 0 deletions cmake/TBBBuildInstallScript.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# Copyright (c) 2017-2019 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# This file is a cmake wrapper around existing tools to facilitate
# building tbb in a way that installs the files
# consistent with standard directory layouts
#

#
# CMAKE_INSTALL_PREFIX <- Where the installed resources should be placed
# ${CMAKE_INSTALL_PREFIX}/lib <- The library files (both static & shared, and both release & debug)
# ${CMAKE_INSTALL_PREFIX}/lib/cmake/TBB <- Where the cmake package files should be installed
# ${CMAKE_INSTALL_PREFIX/include <- The include files
# SYSTEM_NAME <- The system name for the binaries (i.e. Darwin/Linux/Windows/Android)
# TBB_BUILD_DIR:PATH <- Where temporary object files are to be generated
# TBB_BUILD_PREFIX:STRING <- BUILDPREFIX, or os build prefix
# TBB_RELATIVE_CMAKE_CONFIG_PATH <- on installation, relative to CMAEK_INSTALL_PREFIX, where should the cmake package files be placed
# TBB_COMPILER:STRING <- (optional) clang or gcc
# TBB_BUILD_STATIC:BOOL <- (optional) By default static libs are not built.
# TBB_BUILD_SHARED:BOOL <- (optional) By default shared libs are built.
# TBB_DO_EXTERNAL_CMAKE_BUILD_TEST:BOOL <- (optional) After install, do test against the install

message( STATUS " ## Example command line usage
cmake \
-DCMAKE_INSTALL_PREFIX=/tmp/tbbinstall \
-DSYSTEM_NAME:STRING=Darwin \
-DTBB_BUILD_DIR:PATH=/tmp/tbbbuild \
-DTBB_BUILD_PREFIX:STRING=mac_OSX_BLDPRX \
-DTBB_RELATIVE_CMAKE_CONFIG_PATH:PATH=lib/dummy1/cmake/dummy2/TBB/dummy3 \
-DTBB_COMPILER:STRING=clang \
-DTBB_BUILD_STATIC:BOOL=ON \
-DTBB_BUILD_SHARED:BOOL=ON \
-DTBB_DO_EXTERNAL_CMAKE_BUILD_TEST:BOOL=ON \
-P cmake/TBBBuildInstallScript.cmake
")

get_filename_component(TBB_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../ ABSOLUTE)

if(NOT MAKE_ARGS)
set(MAKE_ARGS "")
endif()
if(TBB_COMPILER)
list(APPEND MAKE_ARGS "compiler=${TBB_COMPILER}")
endif()
if(NOT TBB_BUILD_DIR)
set(TBB_BUILD_DIR "${TBB_SOURCE_DIR}/unix_cmake_bld")
endif()
list(APPEND MAKE_ARGS "tbb_build_dir=${TBB_BUILD_DIR}")
if(NOT TBB_BUILD_PREFIX)
set(TBB_BUILD_PREFIX "BUILDPREFIX")
endif()
list(APPEND MAKE_ARGS "tbb_build_prefix=${TBB_BUILD_PREFIX}")

if(SYSTEM_NAME)
set(tbb_system_name ${SYSTEM_NAME})
else()
set(tbb_system_name ${CMAKE_SYSTEM_NAME})
endif()
include(${CMAKE_CURRENT_LIST_DIR}/TBBPlatformDefaults.cmake)

if(NOT TBB_RELATIVE_CMAKE_CONFIG_PATH)
set(TBB_RELATIVE_CMAKE_CONFIG_PATH "${TBB_SHARED_LIB_DIR}/cmake/TBB" )
endif()

# "CMAKE_SYSTEM_NAME" not defined by default in scripts executed with -P, use CMAKE_HOST_SYSTEM_NAME
set(CMAKE_SYSTEM_NAME ${CMAKE_HOST_SYSTEM_NAME})
include(${CMAKE_CURRENT_LIST_DIR}/TBBBuild.cmake)
message(STATUS "Building from source directory :${TBB_SOURCE_DIR}:")
message(STATUS "Building in temporary location: ${TBB_BUILD_DIR} under build prefix ${TBB_BUILD_PREFIX}")

if( NOT DEFINED TBB_BUILD_SHARED OR TBB_BUILD_SHARED )
message(STATUS "Building shared libs with MAKE_ARGS:${MAKE_ARGS}:")
tbb_build(TBB_ROOT ${TBB_SOURCE_DIR}
MAKE_ARGS ${MAKE_ARGS}
CONFIG_DIR ${TBB_BUILD_DIR}/${TBB_RELATIVE_CMAKE_CONFIG_PATH} )
endif()

if( TBB_BUILD_STATIC )
list(APPEND MAKE_ARGS "extra_inc=big_iron.inc") #<- big_iron.inc is included to force build of static libs
message(STATUS "Building static libs with MAKE_ARGS:${MAKE_ARGS}:")
tbb_build(TBB_ROOT ${TBB_SOURCE_DIR}
MAKE_ARGS ${MAKE_ARGS}
CONFIG_FOR_INSTALL
CONFIG_DIR ${TBB_BUILD_DIR}/${TBB_RELATIVE_CMAKE_CONFIG_PATH}
)
endif()
message(STATUS "Configured temporary cmake config files at:${tbb_build_CONFIG_DIR}:") # set from inside tbb_build

##------------------------------------- Install in standard unix directory organization --------------------------------
file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX})
file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${TBB_SHARED_LIB_DIR})
file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${TBB_RELATIVE_CMAKE_CONFIG_PATH})

## First copy the include directory
file(COPY ${TBB_SOURCE_DIR}/include
DESTINATION ${CMAKE_INSTALL_PREFIX}
FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE
DIRECTORY_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE OWNER_WRITE
)

if (CMAKE_SIZEOF_VOID_P EQUAL 8)
get_filename_component(LIB_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/${TBB_SHARED_LIB_DIR}/${TBB_X32_SUBDIR}" ABSOLUTE)
else()
get_filename_component(LIB_INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/${TBB_SHARED_LIB_DIR}/${TBB_X64_SUBDIR}" ABSOLUTE)
endif()

## Second copy the release and debug binary library files to a common lib directory
foreach( tbb_build_suffix "_release" "_debug")

file(GLOB TBB_LIB_FILES ${TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}${tbb_build_suffix}/${TBB_LIB_PREFIX}*.${TBB_LIB_EXT}
${TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}${tbb_build_suffix}/${TBB_LIB_PREFIX}*.${TBB_STATICLIB_EXT} )

message(STATUS "INSTALLING: ${TBB_LIB_FILES}, from ${TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}${tbb_build_suffix}")
file(COPY ${TBB_LIB_FILES}
DESTINATION ${LIB_INSTALL_DESTINATION}
FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE
DIRECTORY_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE OWNER_WRITE
)
endforeach()

## Third copy the cmake configuration files
file(GLOB TBB_CMAKE_CONFIG_FILES ${TBB_BUILD_DIR}/${TBB_RELATIVE_CMAKE_CONFIG_PATH}/*.cmake)
file(COPY ${TBB_CMAKE_CONFIG_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${TBB_RELATIVE_CMAKE_CONFIG_PATH}
FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE
DIRECTORY_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE OWNER_WRITE
)


####################################################
#
if( TBB_DO_EXTERNAL_CMAKE_BUILD_TEST )

message(STATUS "For cmake find_package(TBB REQUIRED)
TBB_DIR=${CMAKE_INSTALL_PREFIX}/${TBB_RELATIVE_CMAKE_CONFIG_PATH}")

set($ENV{TBB_DIR} "${CMAKE_INSTALL_PREFIX}/${TBB_RELATIVE_CMAKE_CONFIG_PATH}")
file(WRITE ${TBB_BUILD_DIR}/test_code/CMakeLists.txt
"cmake_minimum_required(VERSION 3.3.0)
set(CMAKE_CXX_STANDARD 11)
project(test_intel VERSION 0.0.1 LANGUAGES CXX)
find_package(TBB REQUIRED)
if(NOT TBB_FOUND)
message(FATAL_ERROR \"TBB not found\")
else()
message(STATUS \"TBB found at :\${TBB_DIR}\")
message(STATUS \"TBB_INTERFACE_VERSION :\${TBB_INTERFACE_VERSION}:\")
message(STATUS \"TBB_IMPORTED_TARGETS :\${TBB_IMPORTED_TARGETS}:\")
endif()
add_executable(tbb_test_application tbb_test_application.cxx)
target_link_libraries(tbb_test_application \${TBB_IMPORTED_TARGETS})
")


file(WRITE ${TBB_BUILD_DIR}/test_code/tbb_test_application.cxx
"
#include <iostream>
#include \"tbb/tbb.h\"
void ParallelApplyFoo(int a[], size_t n) {
tbb::parallel_for(size_t(0), n, size_t(1) , [=](size_t i) { a[i]++; });
}
int main()
{
tbb::tick_count t0 = tbb::tick_count::now();
const int low = tbb::task_scheduler_init::automatic;
constexpr size_t N=10000;
int a[N] = {1,2,3,4,5,6,7,8,9,10};
ParallelApplyFoo(a,N);
tbb::tick_count t1 = tbb::tick_count::now();
std::cout << \"Time Elapsed: \" << ( t1 - t0 ).seconds() << std::endl;
return EXIT_SUCCESS;
}
")
message(STATUS "TESTING INSTALL REFERENCES -- CMAKE CONFIGURE\n")
file(MAKE_DIRECTORY ${TBB_BUILD_DIR}/test_code-bld)
execute_process(COMMAND ${CMAKE_COMMAND} -DTBB_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${TBB_RELATIVE_CMAKE_CONFIG_PATH} ${TBB_BUILD_DIR}/test_code
#COMMAND make
WORKING_DIRECTORY ${TBB_BUILD_DIR}/test_code-bld
RESULT_VARIABLE TEST_CONFIG_RESULT
OUTPUT_VARIABLE TEST_CONFIG_OUTPUT
ERROR_VARIABLE TEST_CONFIG_ERROR
)
if(NOT ${TEST_CONFIG_RESULT} EQUAL 0)
message(FATAL_ERROR "${TEST_CONFIG_RESULT}\n${TEST_CONFIG_OUTPUT}\n${TEST_CONFIG_ERROR}")
else()
message(STATUS "TESTING INSTALL REFERENCES -- CMAKE BUILD\n")
execute_process(COMMAND make VERBOSE=ON
WORKING_DIRECTORY ${TBB_BUILD_DIR}/test_code-bld
RESULT_VARIABLE TEST_BUILD_RESULT
OUTPUT_VARIABLE TEST_BUILD_OUTPUT
ERROR_VARIABLE TEST_BUILD_ERROR
)
if(NOT ${TEST_BUILD_RESULT} EQUAL 0)
message(FATAL_ERROR "${TEST_BUILD_RESULT}\n${TEST_BUILD_OUTPUT}\n${TEST_BUILD_ERROR}")
else()
message(STATUS "TESTING OF EXTERNAL BUILD AGAINST INSTALLED TBB SUCCEEDED!")
endif()
endif()
message(STATUS "TESTING COMPLETE \n\n")
endif()
Loading

0 comments on commit e873222

Please sign in to comment.