| # ********************************************************** |
| # Copyright (c) 2010-2017 Google, Inc. All rights reserved. |
| # Copyright (c) 2009-2010 VMware, Inc. All rights reserved. |
| # ********************************************************** |
| |
| # Dr. Memory: the memory debugger |
| # |
| # This library is free software; you can redistribute it and/or |
| # modify it under the terms of the GNU Lesser General Public |
| # License as published by the Free Software Foundation; |
| # version 2.1 of the License, and no later version. |
| # |
| # This library 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 |
| # Library General Public License for more details. |
| # |
| # You should have received a copy of the GNU Lesser General Public |
| # License along with this library; if not, write to the Free Software |
| # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| |
| # We need 2.8.10.1 for crbug.com/159092 |
| # (For multi-export-set support for DRMF, we also need >= 2.8.10.) |
| # (For Visual Studio generators, we also need >= 2.8.2 for output dir name control.) |
| # (For Linux, we also need 2.6.4+ for cmake bug #8639 (asm support broken).) |
| cmake_minimum_required(VERSION 2.8.10.1) |
| |
| include(make/policies.cmake NO_POLICY_SCOPE) |
| |
| # like DR, we collapse VS generator into one config since |
| # we don't have enough control over output dirs |
| # in build rules (until cmake 2.8.4). |
| # this must be prior to the project() command. |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug") |
| set(CMAKE_CONFIGURATION_TYPES "Debug" CACHE STRING "" FORCE) |
| else () |
| set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo" CACHE STRING "" FORCE) |
| endif () |
| # we want to use the _LOCATION_<config> property |
| string(TOUPPER "${CMAKE_CONFIGURATION_TYPES}" upper) |
| set(location_suffix "_${upper}") |
| else ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| set(location_suffix "") |
| endif ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| |
| # I want to override the default CMAKE_INSTALL_PREFIX, but allow it to |
| # be set (as the same var name, so CPack and other standard tools |
| # work) externally. The best solution is to check whether defined BEFORE |
| # the project() command. |
| # If we didn't use standard tools we could set CMAKE_INSTALL_PREFIX |
| # to be CACHE INTERNAL FORCE to INSTALL_PREFIX. |
| if (NOT DEFINED CMAKE_INSTALL_PREFIX) |
| set(install_override ON) |
| else (NOT DEFINED CMAKE_INSTALL_PREFIX) |
| set(install_override OFF) |
| endif (NOT DEFINED CMAKE_INSTALL_PREFIX) |
| |
| project(DrMemory NONE) |
| if (DEFINED GENERATE_PDBS AND NOT GENERATE_PDBS) |
| # support building over cygwin ssh where we cannot build pdbs. |
| # using the same solution as DynamoRIO i#310. |
| # To prevent cmake's try-compile for its working compiler test and |
| # its ABI determination test we request a Release build config |
| # via a custom Plaform/Windows-cl.cmake in our make/ dir. |
| set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/make") |
| endif () |
| enable_language(C) |
| enable_language(CXX) |
| |
| include(CheckCCompilerFlag) |
| |
| # The target OS: |
| if (APPLE) |
| set(MACOS 1) |
| elseif (UNIX) |
| set(LINUX 1) |
| endif (APPLE) |
| |
| if (CMAKE_SYSTEM_NAME MATCHES "^Android") |
| set(ANDROID 1) |
| set(DEFINES ${DEFINES} -DANDROID) |
| set(DRM_DEVICE_BASEDIR "/data/local/tmp" CACHE STRING "base dir for Android binaries") |
| option(DRM_COPY_TO_DEVICE "copy cross-compiled binaries to DRM_DEVICE_BASEDIR" OFF) |
| if (DRM_COPY_TO_DEVICE) |
| find_program(ADB adb DOC "adb Android utility") |
| if (NOT ADB) |
| message(FATAL_ERROR "Unable to find adb for DRM_COPY_TO_DEVICE") |
| else () |
| execute_process(COMMAND ${ADB} get-state |
| RESULT_VARIABLE adb_result |
| ERROR_VARIABLE adb_err |
| OUTPUT_VARIABLE adb_out OUTPUT_STRIP_TRAILING_WHITESPACE) |
| if (adb_result OR NOT adb_out STREQUAL "device") |
| message(FATAL_ERROR "Android device not connected for DRM_COPY_TO_DEVICE") |
| endif () |
| message(STATUS "Binaries will be copied to the attached Android device") |
| endif () |
| endif () |
| endif () |
| |
| # The target arch: |
| if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") |
| set(ARM 1) |
| else () |
| set(X86 1) |
| endif () |
| |
| if (UNIX) |
| set(DEFINES ${DEFINES} -DUNIX) |
| endif (UNIX) |
| |
| option(VMKERNEL "target vmkernel") |
| if (VMKERNEL) |
| # if we get enough of these, should use a configure.h, but would need to |
| # pull the ops out like DR core does to pass to options_perl below |
| set(DEFINES ${DEFINES} -DVMX86_SERVER) |
| endif (VMKERNEL) |
| |
| option(TOOL_DR_HEAPSTAT "build Dr. Heapstat instead of Dr. Memory") |
| option(USE_MD5 "use md5 instead of crc32 for callstack hashes for Dr. Heapstat") |
| if (USE_MD5) |
| set(DEFINES ${DEFINES} -DUSE_MD5) |
| endif (USE_MD5) |
| option(CHECK_WITH_MD5 "use crc32 for callstack hashes but check for collisions with md5") |
| if (CHECK_WITH_MD5) |
| set(DEFINES ${DEFINES} -DCHECK_WITH_MD5) |
| endif (CHECK_WITH_MD5) |
| option(STATIC_DRSYMS "use static drsyms library" ON) |
| if (UNIX AND NOT STATIC_DRSYMS) |
| # we could support dynamic but we'd have to copy libdrsym.so |
| message(FATAL_ERROR "non-static drsyms not supported for Linux") |
| endif () |
| |
| option(TEST_SUITE "we are running a series of builds for official purposes") |
| |
| if (TOOL_DR_HEAPSTAT) |
| # Dr. Heapstat |
| set(TOOL_DR_MEMORY OFF) |
| set(toolname drheapstat) |
| set(tooldir ${toolname}) |
| set(toolname_cap DrHeapstat) |
| set(toolname_cap_spc "Dr. Heapstat") |
| set(DEFINES ${DEFINES} -DTOOL_DR_HEAPSTAT) |
| |
| # Dr. Heapstat uses drsyms only to avoid false neg on leaks (i#762, i#292). |
| # XXX: use drsyms for leak reports (i#926) and usage (i#282). |
| set(DRSYMS_DEFAULT ON) |
| else (TOOL_DR_HEAPSTAT) |
| # Dr. Memory |
| set(TOOL_DR_MEMORY ON) |
| set(toolname drmemory) |
| set(tooldir ${toolname}) |
| set(toolname_cap DrMemory) |
| set(toolname_cap_spc "Dr. Memory") |
| set(DEFINES ${DEFINES} -DTOOL_DR_MEMORY) |
| set(DRSYMS_DEFAULT ON) |
| |
| endif (TOOL_DR_HEAPSTAT) |
| |
| # We use a monotonically increasing integer that's larger than any bugfix |
| # release version as the patchlevel ver# to distinguish |
| # We used to use the svn revision (i#83) and we leave that code in place |
| # (for now at least) for anyone building an old checkout. |
| # For git, we follow DRi#1565 and use a date. |
| set(VERSION_NUMBER_PATCHLEVEL 0) |
| if (EXISTS "${PROJECT_SOURCE_DIR}/.svn") |
| find_program(SVN svn DOC "subversion client") |
| if (SVN) |
| execute_process(COMMAND ${SVN} info |
| WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" |
| RESULT_VARIABLE svn_result |
| ERROR_VARIABLE svn_err |
| OUTPUT_VARIABLE svn_out) |
| if (svn_result OR svn_err) |
| message(FATAL_ERROR "*** ${SVN} info failed: ***\n${svn_result} ${svn_err}") |
| endif (svn_result OR svn_err) |
| string(REGEX MATCH "Revision: [0-9]+" svn_out "${svn_out}") |
| string(REGEX REPLACE "Revision: " "" svn_out "${svn_out}") |
| set(VERSION_NUMBER_PATCHLEVEL "${svn_out}") |
| endif (SVN) |
| else (EXISTS "${PROJECT_SOURCE_DIR}/.svn") |
| if (EXISTS "${PROJECT_SOURCE_DIR}/.git") |
| find_program(GIT git DOC "git client") |
| if (GIT) |
| # We want the committer date (not author date) (xref DRi#1565). We request |
| # UNIX timestamp format and then divide down to days to get a small enough |
| # number for the Windows resource limits. |
| execute_process(COMMAND ${GIT} log -n 1 --format=%ct |
| WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" |
| RESULT_VARIABLE git_result |
| ERROR_VARIABLE git_err |
| OUTPUT_VARIABLE git_out) |
| if (git_result OR git_err) |
| message("*** ${GIT} log failed: ***\n${git_err}") |
| else (git_result OR git_err) |
| math(EXPR daycount "${git_out} / (60*60*24)") |
| endif (git_result OR git_err) |
| endif (GIT) |
| if (NOT daycount) |
| # XXX DRi#1565: to support building when not in a git repo (e.g., from a source |
| # tarball) we use date to get current time for timestamp. |
| # This is not ideal as it confuses the build timestamp with the commit |
| # timestamp. We should add support for a local file holding the version. |
| find_program(DATE date DOC "system date") |
| if (DATE) |
| execute_process(COMMAND ${DATE} +%s |
| RESULT_VARIABLE date_result |
| ERROR_VARIABLE date_err |
| OUTPUT_VARIABLE date_out) |
| if (date_result OR date_err) |
| message("*** ${DATE} failed: ***\n${date_err}") |
| else (date_result OR date_err) |
| math(EXPR daycount "${date_out} / (60*60*24)") |
| endif (date_result OR date_err) |
| endif (DATE) |
| endif (NOT daycount) |
| if (NOT daycount) |
| # set a much further date in the future to avoid confusing |
| # this fake date with the real date from git log |
| set(daycount 33333) |
| endif (NOT daycount) |
| set(VERSION_NUMBER_PATCHLEVEL "${daycount}") |
| endif (EXISTS "${PROJECT_SOURCE_DIR}/.git") |
| endif (EXISTS "${PROJECT_SOURCE_DIR}/.svn") |
| |
| if (APPLE) |
| # clang linker disallows any but major # being >= 256 (1024 for x64) so we do |
| # mod 200 (we assume we'll never confuse versions 200 apart) and add 56 (to |
| # distinguish from real releases). |
| math(EXPR VERSION_NUMBER_PATCHLEVEL "(${VERSION_NUMBER_PATCHLEVEL} % 200) + 56") |
| endif (APPLE) |
| |
| set(VERSION_NUMBER_DEFAULT "1.11.${VERSION_NUMBER_PATCHLEVEL}") |
| # do not store the default TOOL_VERSION_NUMBER in the cache to prevent a stale one |
| # from preventing future version updates in a pre-existing build dir. |
| # avoid "VERSION_NUMBER" name since conflics w/ DR's var |
| set(TOOL_VERSION_NUMBER "" CACHE STRING "Version number: leave empty for default") |
| if ("${TOOL_VERSION_NUMBER}" STREQUAL "") |
| set(TOOL_VERSION_NUMBER ${VERSION_NUMBER_DEFAULT}) |
| endif() |
| message(STATUS "Dr. Memory version number: ${TOOL_VERSION_NUMBER}") |
| |
| # Avoid "BUILD_NUMBER" name since conflics w/ DR's var |
| set(TOOL_BUILD_NUMBER "1" CACHE STRING "Build number (must be <64K)") |
| # However, we do want to set it to avoid "custom build" in messages |
| # from embedded DR when run alone (i#1717's dr_set_client_version_string() has |
| # already solved this for messages for DrMem on DR). To make it easy to |
| # correlate, we set it to a formula computed from the DrMem ver. |
| string(REPLACE "." ";" ver_list ${TOOL_VERSION_NUMBER}) |
| list(GET ver_list 0 TOOL_VERSION_MAJOR) |
| list(GET ver_list 1 TOOL_VERSION_MINOR) |
| math(EXPR BUILD_NUMBER |
| "${TOOL_VERSION_MAJOR}*100 + ${TOOL_VERSION_MINOR}*10 + ${VERSION_NUMBER_PATCHLEVEL}") |
| |
| string(REGEX REPLACE "\\." "," TOOL_VERSION_COMMAS "${TOOL_VERSION_NUMBER}") |
| |
| set(DEFINES ${DEFINES} |
| -DBUILD_NUMBER=${TOOL_BUILD_NUMBER} |
| -DVERSION_NUMBER=${TOOL_VERSION_NUMBER} |
| -DVERSION_STRING="${TOOL_VERSION_NUMBER}" |
| -DVERSION_COMMAS=${TOOL_VERSION_COMMAS}) |
| |
| # i#44/PR 243532: online symbol access |
| option(USE_DRSYMS "use drsyms DR Extension online symbols instead of post-processing" |
| ${DRSYMS_DEFAULT}) |
| if (USE_DRSYMS) |
| set(DEFINES ${DEFINES} -DUSE_DRSYMS) |
| endif (USE_DRSYMS) |
| |
| if (WIN32) |
| # With the new drinjectlib-based front end we do not use perl or perl2exe |
| # at all on Windows (xref i#265/PR 486139) |
| if (OFF) # disabling |
| # For portability we convert our perl scripts to executables, |
| # if the 'pp' tool is available. |
| # For most portable results, use a native windows perl (e.g., |
| # strawberry perl) rather than cygwin perl. |
| set(PERL_PATH "" CACHE PATH "directory where perl binaries are located") |
| if (PERL_PATH AND EXISTS "${PERL_PATH}/perl.exe") |
| set(PERL_EXECUTABLE "${PERL_PATH}/perl.exe") |
| else () |
| # we only look for perl if user doesn't specify (on windows it's common |
| # to have several perls installed) |
| include(FindPerl) |
| if (PERL_FOUND) |
| get_filename_component(PERL_PATH "${PERL_EXECUTABLE}" PATH) |
| endif (PERL_FOUND) |
| endif () |
| |
| if (EXISTS "${PERL_PATH}/pp") |
| set(PERL_PP "${PERL_PATH}/pp" CACHE FILEPATH |
| "Path to perl PAR module's perl-to-executable tool 'pp'") |
| else () |
| find_file(PERL_PP pp HINTS "${PERL_PATH}" |
| DOC "Path to perl PAR module's perl-to-executable tool 'pp'") |
| endif () |
| if (PERL_PP-NOTFOUND OR NOT EXISTS "${PERL_PP}") |
| message(STATUS "Did not find pp: will not convert perl scripts to executables") |
| set(PERL_TO_EXE OFF) |
| else (PERL_PP-NOTFOUND OR NOT EXISTS "${PERL_PP}") |
| message(STATUS "Found pp: ${PERL_PP}") |
| set(PERL_TO_EXE ON) |
| endif (PERL_PP-NOTFOUND OR NOT EXISTS "${PERL_PP}") |
| else (OFF) |
| set(PERL_TO_EXE OFF) |
| endif (OFF) |
| endif (WIN32) |
| |
| if (CMAKE_C_SIZEOF_DATA_PTR EQUAL 8 OR CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8) |
| set(X64 ON) |
| set(LIB_ARCH "lib64") |
| set(BIN_ARCH "bin64") |
| set(DEFINES ${DEFINES} -DX64) |
| else() |
| set(X64 OFF) |
| set(LIB_ARCH "lib32") |
| set(BIN_ARCH "bin32") |
| endif () |
| |
| if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug") |
| # FIXME: use a configure.h |
| set(DEFINES ${DEFINES} -DDEBUG -DSTATISTICS) |
| set(DEBUG_BUILD ON) # "DEBUG" conflicts w/ DR |
| else () |
| # We want Windows pdb and Unix line #s for release build. |
| # We make separate debug info for Unix, and are fine shipping it to users |
| # in any case as we're open-source. |
| set(CMAKE_BUILD_TYPE "RelWithDebInfo") |
| set(DEBUG_BUILD OFF) |
| endif () |
| |
| string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER) |
| |
| # i#1781: cmake 2.8.12+ fails to create static lib pdb by default |
| # XXX: we should share this with DR's copy |
| macro(add_static_lib_debug_info target dest_dir) |
| if (WIN32) |
| if ("${CMAKE_VERSION}" VERSION_EQUAL "3.1" OR |
| "${CMAKE_VERSION}" VERSION_GREATER "3.1") |
| append_property_string(TARGET ${target} |
| COMPILE_PDB_NAME${location_suffix} "${target}" |
| COMPILE_PDB_OUTPUT_DIRECTORY{location_suffix} "${dest_dir}") |
| else () |
| # We just don't support it for < 3.1 |
| endif () |
| endif () |
| endmacro() |
| |
| if (UNIX) |
| # there's no cmake warning control so we hardcode it |
| # disabling strict aliasing since giving weird warning I'm not sure how to fix: |
| # alloc.c:716: warning: dereferencing type-punned pointer will break strict-aliasing rules |
| set(WARN "-Wall -Werror -Wno-strict-aliasing") |
| if (CMAKE_C_COMPILER MATCHES "/build/toolchain") |
| # needed for linux/ipmi.h (PR 531644) |
| set(EXTRA_FLAGS "-idirafter /build/toolchain/lin32/glibc-2007q3-51/usr/include") |
| else () |
| if (APPLE AND NOT CMAKE_COMPILER_IS_GNUCC) |
| # Ensure our binaries can run on older OSX |
| set(EXTRA_FLAGS "-mmacosx-version-min=10.9") |
| else () |
| set(EXTRA_FLAGS "") |
| endif () |
| endif () |
| if (ARM) |
| set(EXTRA_FLAGS "${EXTRA_FLAGS} -mthumb -march=armv7-a") |
| if (ANDROID OR CMAKE_C_LIBRARY_ARCHITECTURE MATCHES "gnueabi$") |
| set(EXTRA_FLAGS "${EXTRA_FLAGS} -mfloat-abi=softfp") |
| # Android requires PIE. We export symbols to match our test assumptions. |
| set(CMAKE_EXE_LINKER_FLAGS |
| "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie -Wl,--export-dynamic") |
| endif () |
| endif () |
| set(CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER} |
| "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} ${ARCH_CFLAGS} ${WARN} ${EXTRA_FLAGS}") |
| set(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER} |
| "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} ${ARCH_CFLAGS} ${WARN} ${EXTRA_FLAGS}") |
| else (UNIX) |
| # FIXME i#1204: fix warnings and up to /W4 |
| set(WARN "/W2 /WX") |
| # update flags for our types and Debug (tests always use Debug). |
| # ok to double-update b/c these are are regex-replace. |
| foreach (config ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES} Debug) |
| string(TOUPPER "${config}" config_upper) |
| foreach (var CMAKE_C_FLAGS;CMAKE_CXX_FLAGS; |
| CMAKE_C_FLAGS_${config_upper}; |
| CMAKE_CXX_FLAGS_${config_upper}) |
| # default from cmake has /W3 so remove to avoid warning about overriding |
| string(REGEX REPLACE "/W[0-9]" "" ${var} "${${var}}") |
| # /GZ requires RTC runtime support which we don't want (i#925) |
| string(REGEX REPLACE "/GZ" "" ${var} "${${var}}") |
| # avoid warnings (i#925) |
| string(REGEX REPLACE "/GX" "/EHsc" ${var} "${${var}}") |
| if (NOT DEBUG_BUILD) |
| # RelWithDebInfo asks for /Ob1 but we want full inlining |
| string(REGEX REPLACE "/Ob1" "/Ob2" ${var} "${${var}}") |
| endif () |
| endforeach () |
| endforeach () |
| # disable stack protection: "unresolved external symbol ___security_cookie" |
| set(CL_CFLAGS "/GS-") |
| # build in parallel, always. |
| # note that /MP is not officially supported on VS 2005 and others |
| # have seen occasional problems: we'll risk it. we could check for |
| # "MSVC10 OR MSVC90". |
| set(CL_CFLAGS "${CL_CFLAGS} /MP") |
| if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0) |
| # i#1376: VS2013 requires /FS w/ multiple cl.exe in parallel (which Ninja |
| # uses). While /MP is supposed to enable it, it doesn't seem to. |
| # This is recommended after /Fd but it seems to work here. |
| set(CL_CFLAGS "${CL_CFLAGS} /FS") |
| endif() |
| set(CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER} "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} ${WARN} ${CL_CFLAGS}") |
| endif (UNIX) |
| set(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER} "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} ${ARCH_CFLAGS} ${WARN}") |
| string(STRIP "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}}" |
| CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}) |
| string(STRIP "${CMAKE_CXX_FLAGS}" CMAKE_CXX_FLAGS) |
| |
| if (WIN32) |
| # DRi#1424: target the oldest possible platform we can |
| if (X64) |
| set(os_target "5.02") # Win2003x64/WinXPx64 |
| else (X64) |
| if (CMAKE_C_COMPILER_VERSION VERSION_LESS 17.0) # up to and including VS2010 |
| set(os_target "5.00") # Win2K |
| else () # VS2012, VS2013 |
| set(os_target "5.01") # WinXP |
| endif () |
| endif (X64) |
| foreach (lflags CMAKE_EXE_LINKER_FLAGS |
| CMAKE_MODULE_LINKER_FLAGS |
| CMAKE_SHARED_LINKER_FLAGS) |
| set(${lflags} "${${lflags}} /subsystem:console,${os_target}") |
| endforeach() |
| message(STATUS "Targeting subsystem ${os_target}") |
| endif (WIN32) |
| |
| if (UNIX) |
| include(CheckIncludeFiles) |
| check_include_files("asm-i386/stat.h" HAVE_ASM_I386) |
| if (HAVE_ASM_I386) |
| # see comments above about adding configure.h |
| set(DEFINES ${DEFINES} -DHAVE_ASM_I386) |
| endif (HAVE_ASM_I386) |
| endif (UNIX) |
| |
| if (UNIX) |
| # We don't want our instrument_init() pre-empted by debug-internal DynamoRIO |
| # that has visible internal routines. |
| CHECK_C_COMPILER_FLAG("-fvisibility=internal" HAVE_FVISIBILITY_INTERNAL) |
| CHECK_C_COMPILER_FLAG("-fvisibility=hidden" HAVE_FVISIBILITY_HIDDEN) |
| # Mac accepts internal but warns about it so we avoid it there. |
| if (HAVE_FVISIBILITY_INTERNAL AND NOT APPLE) |
| set(VISIBILITY "internal") |
| elseif (HAVE_FVISIBILITY_HIDDEN) |
| set(VISIBILITY "hidden") |
| else () |
| message("${CMAKE_C_COMPILER} missing flag -fvisibility, using linker " |
| "script instead") |
| set(VISIBILITY " ") |
| endif () |
| if (HAVE_FVISIBILITY_INTERNAL OR HAVE_FVISIBILITY_HIDDEN) |
| set(CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER} |
| "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}} -fvisibility=${VISIBILITY}") |
| endif () |
| |
| if (APPLE) |
| # Incredibly, for both clang and g++, while a single compile-and-link |
| # invocation will create an executable.dSYM/ dir with debug info, |
| # with separate compilation the final link does NOT create the |
| # dSYM dir. |
| # The "dsymutil" program will create the dSYM dir for us. |
| # Strangely it takes in the executable and not the object |
| # files even though it's the latter that contain the debug info. |
| # Thus it will only work if the object files are still sitting around. |
| find_program(DSYMUTIL_PROGRAM dsymutil) |
| if (DSYMUTIL_PROGRAM) |
| set(CMAKE_C_LINK_EXECUTABLE |
| "${CMAKE_C_LINK_EXECUTABLE}" |
| "${DSYMUTIL_PROGRAM} <TARGET>") |
| set(CMAKE_C_CREATE_SHARED_LIBRARY |
| "${CMAKE_C_CREATE_SHARED_LIBRARY}" |
| "${DSYMUTIL_PROGRAM} <TARGET>") |
| set(CMAKE_CXX_LINK_EXECUTABLE |
| "${CMAKE_CXX_LINK_EXECUTABLE}" |
| "${DSYMUTIL_PROGRAM} <TARGET>") |
| set(CMAKE_CXX_CREATE_SHARED_LIBRARY |
| "${CMAKE_CXX_CREATE_SHARED_LIBRARY}" |
| "${DSYMUTIL_PROGRAM} <TARGET>") |
| endif () |
| endif () |
| endif (UNIX) |
| |
| if (WIN32) |
| # Use convention of DynamoRIO sources: DDKROOT env var (or DDK_ROOT cmake var). |
| # We don't require the DDK as dbghelp and symsrv are in the SDK as well, and |
| # we get ntdll_imports.lib from DR. |
| set(DDK_ROOT "$ENV{DDKROOT}" CACHE PATH "Path to DDK or WDK.") |
| if ("${DDK_ROOT}" STREQUAL "") |
| # Check default install path |
| if (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") |
| set(DDK_ROOT "$ENV{SYSTEMDRIVE}/WINDDK/3790.1830/") |
| elseif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/6000/") |
| set(DDK_ROOT "$ENV{SYSTEMDRIVE}/WINDDK/6000/") |
| elseif (EXISTS "$ENV{SYSTEMDRIVE}/WINDDK/7600.16385.1/") |
| set(DDK_ROOT "$ENV{SYSTEMDRIVE}/WINDDK/7600.16385.1/") |
| endif () |
| endif ("${DDK_ROOT}" STREQUAL "") |
| |
| # We can't include directly from DDK b/c the DDK include dir and VS include |
| # dirs are incompatible, so we have our own copies of the headers we need. |
| include_directories(wininc/psdk wininc/dxsdk) |
| |
| # We need a newer version of dbghelp.dll than is in system32/ on 2K or XP. |
| # The versions that come with Debugging Tools for Windows are redistributable: |
| # "you can distribute the DLL with your application". |
| # The dbghelp.dll that comes in system32/ is not redistributable. |
| # We want 6.3+ for full drsyms features. |
| # 5.2 does not work (it's not just slower w/o SymSearch: it fails). |
| # Haven't tested in between. |
| # WINDDK/3790.1830/bin/x86/dbghelp.dll is 6.3. |
| # Older CMake binaries are 32-bit but newer ones can be 64-bit so we |
| # cannot rely on one or the other. |
| if ("$ENV{PROGRAMW6432}" STREQUAL "") |
| if (X64) |
| message(FATAL_ERROR "On 32-bit Windows: 64-bit build not supported") |
| endif () |
| set(PROGFILES "$ENV{PROGRAMFILES}") |
| set(PROGFILES32 "$ENV{PROGRAMFILES}") |
| set(ARCH_SFX "x86") |
| set(DDK_SFX "i386") |
| else () |
| set(PROGFILES "$ENV{PROGRAMW6432}") |
| set(PROGFILES32 "$ENV{PROGRAMFILES(x86)}") |
| if (X64) |
| set(ARCH_SFX "x64") |
| set(DDK_SFX "amd64") |
| else (X64) |
| set(ARCH_SFX "x86") |
| set(DDK_SFX "i386") |
| endif (X64) |
| endif () |
| # Even the VS2005 copy is 6.5 (despite its headers being < 6.3) so we can |
| # use those as well as the later SDK and standalone DTFW versions. |
| set(dbghelp_paths |
| "${DDK_ROOT}/bin/${ARCH_SFX}/dbghelp.dll" |
| "${DDK_ROOT}/tools/tracing/${DDK_SFX}/dbghelp.dll" |
| "${PROGFILES32}/Windows Kits/*/Debuggers/${ARCH_SFX}/dbghelp.dll" |
| # In case if SDK is not installed and we have Visual Studio, dbghelp.dll may be found in the |
| # Visual Studio's directory in subfolders Remote Debugger/x86 or Remote Debugger/x64 (xref i#1956). |
| # We look in both paths (Program Files and Program Files (x86)) because some versions of |
| # Visual Studio put dbghelp.dll in progfiles (especially 2008) and some in progfiles32. |
| "${PROGFILES}/Microsoft Visual Studio */Common7/IDE/Remote Debugger/${ARCH_SFX}/dbghelp.dll" |
| "${PROGFILES32}/Microsoft Visual Studio */Common7/IDE/Remote Debugger/${ARCH_SFX}/dbghelp.dll") |
| if (X64) |
| set(dbghelp_paths ${dbghelp_paths} |
| # For older versions of windbg, x64 dbghelp.dll resides here. |
| "${PROGFILES}/Debugging Tools for Windows (x64)/dbghelp.dll") |
| else (X64) |
| set(dbghelp_paths ${dbghelp_paths} |
| "${PROGFILES}/Microsoft Visual Studio */Common7/IDE/dbghelp.dll" |
| # Putting this last mainly b/c only older versions (like my 6.3) are here. |
| "${PROGFILES}/Debugging Tools for Windows/dbghelp.dll") |
| endif (X64) |
| file(GLOB dbghelp_hint ${dbghelp_paths}) |
| # XXX i#908: it seems cmake has trouble to lookup dbghelp.dll in |
| # 64-bit directory, so we just explicitly check several possible locations. |
| # Plus, we don't want system32, but NO_SYSTEM_ENVIRONMENT_PATH also |
| # excludes Program Files, so we avoid find_file() in general. |
| if (dbghelp_hint) |
| # DRi#1219: exclude VS2005 x64 dbghelp as it is buggy |
| list(LENGTH dbghelp_hint dbghelp_max) |
| math(EXPR dbghelp_max "${dbghelp_max} - 1") |
| set(dbghelp_index 0) |
| list(GET dbghelp_hint 0 dbghelp_default) |
| while (X64 AND dbghelp_default MATCHES "Visual Studio 8" AND |
| ${dbghelp_index} LESS ${dbghelp_max}) |
| math(EXPR dbghelp_index "${dbghelp_index} + 1") |
| list(GET dbghelp_hint ${dbghelp_index} dbghelp_default) |
| endwhile() |
| if (X64 AND dbghelp_default MATCHES "Visual Studio 8") |
| message(STATUS "Unable to find non-VS2005 dbghelp.dll") |
| set(dbghelp_default "DBGHELP_DLL-NOTFOUND") |
| endif () |
| else () |
| set(dbghelp_default "DBGHELP_DLL-NOTFOUND") |
| endif () |
| set(DBGHELP_DLL "" CACHE STRING |
| "location of dbghelp.dll from recent Debugging Tools for Windows") |
| if ("${DBGHELP_DLL}" STREQUAL "") |
| set(DBGHELP_DLL ${dbghelp_default}) |
| endif() |
| if (DBGHELP_DLL-NOTFOUND OR NOT EXISTS "${DBGHELP_DLL}") |
| message(FATAL_ERROR "dbghelp.dll required and not found") |
| else () |
| message(STATUS "Using ${DBGHELP_DLL}") |
| endif () |
| set(symsrv_paths |
| "${PROGFILES32}/Windows Kits/*/Debuggers/${ARCH_SFX}/symsrv.dll" |
| # In case if SDK is not installed and we have Visual Studio, symsrv.dll may be found in the |
| # same place as dbghelp.dll (see comment for dbghelp.dll) (xref i#1956). |
| "${PROGFILES}/Microsoft Visual Studio */Common7/IDE/Remote Debugger/${ARCH_SFX}/symsrv.dll" |
| "${PROGFILES32}/Microsoft Visual Studio */Common7/IDE/Remote Debugger/${ARCH_SFX}/symsrv.dll") |
| if (X64) |
| set(symsrv_paths ${symsrv_paths} |
| # For older versions of windbg, x64 symsrv.dll resides here. |
| "${PROGFILES}/Debugging Tools for Windows (x64)/symsrv.dll") |
| else (X64) |
| set(symsrv_paths ${symsrv_paths} |
| "${PROGFILES}/Microsoft Visual Studio */Common7/IDE/symsrv.dll" |
| # Putting this last mainly b/c only older versions (like my 6.3) are here. |
| "${PROGFILES}/Debugging Tools for Windows/symsrv.dll") |
| endif (X64) |
| file(GLOB symsrv_hint ${symsrv_paths}) |
| if (symsrv_hint) |
| list(GET symsrv_hint 0 symsrv_default) |
| else () |
| set(symsrv_default "SYMSRV_DLL-NOTFOUND") |
| endif () |
| set(SYMSRV_DLL "" CACHE STRING |
| "location of symsrv.dll from recent Debugging Tools for Windows") |
| if ("${SYMSRV_DLL}" STREQUAL "") |
| set(SYMSRV_DLL ${symsrv_default}) |
| endif() |
| if (SYMSRV_DLL-NOTFOUND OR NOT EXISTS "${SYMSRV_DLL}") |
| message(FATAL_ERROR "symsrv.dll required and not found") |
| else () |
| message(STATUS "Using ${SYMSRV_DLL}") |
| endif () |
| |
| endif (WIN32) |
| |
| if (BUILDING_SUB_PACKAGE) |
| set(INSTALL_PREFIX "drmemory/") |
| else () |
| set(INSTALL_PREFIX "") |
| endif() |
| |
| # To run out of build dir we put libs and scripts in dirs that match install layout |
| # except minus the toolname prefix dir. |
| # The CPack NSIS interface requires a bin/ dir, so for the Windows package |
| # we prefix bin/ |
| # XXX: should clean all this up and normalize across platforms now |
| # that we have drsyms on Linux and once we're sure we don't need to |
| # support the old layout. |
| if (WIN32 AND USE_DRSYMS AND TOOL_DR_MEMORY) |
| set(INSTALL_BIN_PREFIX "${INSTALL_PREFIX}.") |
| set(BUILD_BIN_PREFIX ".") |
| elseif (PERL_TO_EXE) |
| # We are only releasing Dr. Memory so no toolnames: would need to create |
| # shortcut or .bat file to run from right dir |
| if (X64) |
| set(INSTALL_BIN_PREFIX "${INSTALL_PREFIX}bin64") |
| set(BUILD_BIN_PREFIX "bin64") |
| else (X64) |
| set(INSTALL_BIN_PREFIX "${INSTALL_PREFIX}bin") |
| set(BUILD_BIN_PREFIX "bin") |
| endif (X64) |
| else (PERL_TO_EXE) |
| # Unified layout: match Windows since we're moving toward C-based frontends |
| # that won't have auxiliary scripts we want to hide. |
| set(INSTALL_BIN_PREFIX "${INSTALL_PREFIX}.") |
| set(BUILD_BIN_PREFIX ".") |
| endif (WIN32 AND USE_DRSYMS AND TOOL_DR_MEMORY) |
| # For NSIS we have everything in top-level bin/ |
| # Once we have x64 we'll need to address: fix CPack? |
| if (X64) |
| set(INSTALL_BIN "${INSTALL_BIN_PREFIX}/bin64") |
| set(BUILD_BIN "${BUILD_BIN_PREFIX}/bin64") |
| else (X64) |
| set(INSTALL_BIN "${INSTALL_BIN_PREFIX}/bin") |
| set(BUILD_BIN "${BUILD_BIN_PREFIX}/bin") |
| endif (X64) |
| if (DEBUG_BUILD) |
| set(build_type "debug") |
| else (DEBUG_BUILD) |
| set(build_type "release") |
| endif (DEBUG_BUILD) |
| set(INSTALL_LIB "${INSTALL_BIN}/${build_type}") |
| set(BUILD_LIB "${BUILD_BIN}/${build_type}") |
| |
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${BUILD_LIB}") |
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") |
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${BUILD_BIN}") |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # we don't support the Debug and Release subdirs |
| foreach (config ${CMAKE_CONFIGURATION_TYPES}) |
| string(TOUPPER "${config}" config_upper) |
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config_upper} |
| "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") |
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config_upper} |
| "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}") |
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${config_upper} |
| "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") |
| endforeach () |
| endif () |
| |
| ################################################## |
| # option sharing (PR 478146) |
| |
| set(CPP_IGNORE_EMPTY "") |
| if (UNIX) |
| if (APPLE) |
| # /usr/bin/cpp is broken and won't honor -B flags |
| set(CMAKE_CPP_FOR_OPS ${CMAKE_C_COMPILER}) |
| set(CPP_INC -Wp,-I,) |
| # Avoid clang warning on perl '' |
| set(CPP_IGNORE_EMPTY -Wno-invalid-pp-token) |
| else (APPLE) |
| # "gcc -E" on a non-.c-extension file gives message: |
| # "linker input file unused because linking not done" |
| # and doesn't produce any output, so we must use cpp for our .asm files. |
| # we assume it's in the same dir. |
| get_filename_component(compiler_path ${CMAKE_C_COMPILER} PATH) |
| find_program(CMAKE_CPP_FOR_OPS cpp HINTS "${compiler_path}" |
| DOC "path to C preprocessor") |
| if (cpp-NOTFOUND OR NOT EXISTS "${CMAKE_CPP_FOR_OPS}") |
| message(FATAL_ERROR "cpp is required to build") |
| endif (cpp-NOTFOUND OR NOT EXISTS "${CMAKE_CPP_FOR_OPS}") |
| mark_as_advanced(CMAKE_CPP_FOR_OPS) |
| set(CPP_INC -I) |
| endif (APPLE) |
| set(CPP_NO_LINENUM -P) |
| else (UNIX) |
| set(CMAKE_CPP_FOR_OPS ${CMAKE_C_COMPILER}) |
| set(CPP_NO_LINENUM /EP) |
| set(CPP_INC /I) |
| endif (UNIX) |
| |
| # I would share this name w/ drmemory.pl but it's a pain to configure_file |
| # or generate the perl script as we also have to compile it for pp. |
| set(options_for_perl "${PROJECT_BINARY_DIR}/${BUILD_BIN}/options-perl.pl") |
| add_custom_target(options_perl ALL DEPENDS "${options_for_perl}") |
| add_custom_command( |
| OUTPUT "${options_for_perl}" |
| DEPENDS "${PROJECT_SOURCE_DIR}/common/options-perl.c" |
| "${PROJECT_SOURCE_DIR}/${tooldir}/optionsx.h" |
| COMMAND ${CMAKE_CPP_FOR_OPS} |
| ARGS -E ${CPP_NO_LINENUM} "${PROJECT_SOURCE_DIR}/common/options-perl.c" |
| ${CPP_INC}${PROJECT_SOURCE_DIR}/${tooldir} ${DEFINES} |
| ${CPP_IGNORE_EMPTY} > "${options_for_perl}" |
| VERBATIM) |
| |
| # options_for_docs is built in docs/CMakeLists.txt since custom commands |
| # are directory-local |
| |
| ################################################## |
| # utility functions |
| |
| function (append_property_string type target name value) |
| # XXX: if we require cmake 2.8.6 we can simply use APPEND_STRING |
| get_property(cur ${type} ${target} PROPERTY ${name}) |
| if (cur) |
| set(value "${cur} ${value}") |
| endif (cur) |
| set_property(${type} ${target} PROPERTY ${name} "${value}") |
| endfunction (append_property_string) |
| |
| function (set_output_dirs dir) |
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${dir}" PARENT_SCOPE) |
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${dir}" PARENT_SCOPE) |
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${dir}" PARENT_SCOPE) |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # we don't support the Debug and Release subdirs |
| foreach (config ${CMAKE_CONFIGURATION_TYPES}) |
| string(TOUPPER "${config}" config_upper) |
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config_upper} |
| "${dir}" PARENT_SCOPE) |
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config_upper} |
| "${dir}" PARENT_SCOPE) |
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${config_upper} |
| "${dir}" PARENT_SCOPE) |
| endforeach () |
| endif () |
| endfunction (set_output_dirs) |
| |
| ################################################## |
| # find DynamoRIO so tests has its path, but don't include it or run |
| # its configure commands to avoid changing cflags: |
| |
| # DR clobbers the global cflags, so we save and then restore them for |
| # our tests (and ourselves for non-pre-built DR). |
| # configure_DynamoRIO_client() also does so we do this even for pre-built DR |
| # for tests. |
| foreach (config "" ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES}) |
| if ("${config}" STREQUAL "") |
| set(config_upper "") |
| else ("${config}" STREQUAL "") |
| string(TOUPPER "_${config}" config_upper) |
| endif ("${config}" STREQUAL "") |
| foreach (var CMAKE_C_FLAGS${config_upper};CMAKE_CXX_FLAGS${config_upper}) |
| set(SAVE_${var} "${${var}}") |
| endforeach (var) |
| endforeach (config) |
| |
| # we write DynamoRIO_DIR to the cache, so on re-interpreting the file later |
| # we can't tell whether the user set a value or not. we could |
| # use a differently-named var for the user but instead we check vs |
| # the local build path to avoid breaking existing scripts. |
| set(LOCAL_DynamoRIO_DIR "${PROJECT_BINARY_DIR}/dynamorio/cmake") |
| if (DEFINED DynamoRIO_DIR AND NOT "${DynamoRIO_DIR}" STREQUAL "${LOCAL_DynamoRIO_DIR}") |
| set(USER_SPECIFIED_DynamoRIO_DIR ON) |
| else () |
| set(USER_SPECIFIED_DynamoRIO_DIR OFF) |
| endif () |
| |
| # when updating this, also update the git submodule |
| set(DynamoRIO_VERSION_REQUIRED "6.2.17499") |
| |
| set(DR_install_dir "dynamorio") |
| |
| if (USER_SPECIFIED_DynamoRIO_DIR) |
| # i#67: relative dirs are not really supported in find_package: they're |
| # relative to source dir not build dir, so we change that here. |
| # we can't do get_filename_component(... ABSOLUTE) b/c it's relative to |
| # source dir as well. |
| if ("${DynamoRIO_DIR}" MATCHES "^\\.\\.") |
| get_filename_component(DynamoRIO_DIR "${PROJECT_BINARY_DIR}/${DynamoRIO_DIR}" ABSOLUTE) |
| endif () |
| # exit if it doesn't exist since very misleading if find_package() goes |
| # and finds some other version from what was requested |
| if (NOT EXISTS "${DynamoRIO_DIR}/DynamoRIOConfig.cmake") |
| message(FATAL_ERROR "${DynamoRIO_DIR}/DynamoRIOConfig.cmake does not exist: invalid DynamoRIO_DIR") |
| endif () |
| |
| if (BUILDING_SUB_PACKAGE) |
| message(FATAL_ERROR "Sub-package not supported with pre-built DR") |
| endif () |
| |
| message(STATUS "Attempting to use pre-built DynamoRIO: ${DynamoRIO_DIR}") |
| find_package(DynamoRIO ${DynamoRIO_VERSION_REQUIRED}) |
| if (NOT DynamoRIO_FOUND) |
| message(FATAL_ERROR "DynamoRIO package required to build") |
| endif(NOT DynamoRIO_FOUND) |
| # from here on use what was found, not what was passed in |
| get_filename_component(DynamoRIO_DIR "${DynamoRIO_CONFIG}" PATH) |
| # preserve real value in the cache so it's easy to tell |
| set(DynamoRIO_DIR "${DynamoRIO_DIR}" CACHE PATH "Path to DynamoRIO.") |
| message(STATUS "DynamoRIO that matches: ${DynamoRIO_VERSION} in ${DynamoRIO_DIR}") |
| else (USER_SPECIFIED_DynamoRIO_DIR) |
| # Build from our local copy of the sources, coming from a git submodule: i#74. |
| set(DynamoRIO_DIR "${LOCAL_DynamoRIO_DIR}" CACHE PATH "Path to DynamoRIO.") |
| message(STATUS "Building DynamoRIO from local sources ${DynamoRIO_DIR}") |
| |
| # We include DynamoRIO as a subdir here to make it easy to use the |
| # DynamoRIOConfig.cmake at configure time: however, that also means we have |
| # potential conflicts in CMake's global option and target space. |
| # Ideally, DynamoRIO would prefix all its options and targets with "DR_" |
| # or something. For now we live w/ the ugliness. |
| # (An alternative would be to use the ExternalProject feature: but |
| # then we don't have DynamoRIOConfig.cmake at config time and we'd |
| # either need a parent build project or to hack our find_package().) |
| |
| # it seems that we must set these in the cache for the subproj to see them: |
| set(BUILD_DOCS OFF CACHE BOOL "DynamoRIO option: build client samples") |
| set(BUILD_SAMPLES OFF CACHE BOOL "DynamoRIO option: build documentation") |
| # our local DR build matches our own build type |
| if ("${CMAKE_BUILD_TYPE}" MATCHES "Debug") |
| set(DEBUG ON CACHE BOOL "DynamoRIO option: debug build") |
| set(INTERNAL ON CACHE BOOL "DynamoRIO option: internal build") |
| endif ("${CMAKE_BUILD_TYPE}" MATCHES "Debug") |
| if (DRM_COPY_TO_DEVICE) |
| set(DR_COPY_TO_DEVICE ON CACHE BOOL "DynamoRIO option: copy to Android") |
| get_filename_component(builddir ${PROJECT_BINARY_DIR} NAME) |
| set(DR_DEVICE_BASEDIR "${DRM_DEVICE_BASEDIR}/${builddir}" CACHE STRING |
| "DynamoRIO option: Android path") |
| endif () |
| # We do not want DR install, except for the targets we need for our |
| # multi-export-set install of the DRMF. We need those targets |
| # even for BUILDING_SUB_PACKAGE. |
| set(DO_DR_INSTALL OFF) |
| set(DO_DR_INSTALL_TARGETS ON) |
| # Stick the binaries somewhere outside of the install dir. |
| # However, NSIS won't allow an absolute path (i#1099). |
| # So for an automated package.cmake build via cpack, we use .. which |
| # is fine in the package dir structure. We don't want .. for a |
| # user-specified destination of course. We simply don't |
| # support creating a package manually outside of package.cmake. |
| if (BUILDING_PACKAGE) |
| set(DR_INSTALL_TARGETS_DEST ../ignored-installs) |
| else () |
| set(DR_INSTALL_TARGETS_DEST ${PROJECT_BINARY_DIR}/dynamorio/installs) |
| endif () |
| # i#1449: we need cmake to remove the absolute path from the LC_LOAD_DYLIB |
| # entries, which only happens on install. We can't easily do a two-step |
| # install b/c subdirs go after the main dir -- so we have DR cooperation. |
| set(DR_INSTALL_DEPLOY_BIN_DEST ${DR_install_dir}/${BIN_ARCH}) |
| |
| add_subdirectory(dynamorio) |
| |
| # don't show DR options in drmem cmake list |
| # to really hide we should mark as INTERNAL but not worth it since would |
| # have to do for all of DR's many options. |
| # see comment above about DR prefixing its options. |
| mark_as_advanced(BUILD_CORE BUILD_DOCS BUILD_SAMPLES BUILD_EXT BUILD_TESTS |
| BUILD_TOOLS DEBUG INTERNAL) |
| |
| # do not import dynamorio lib target: we'd end up w/ duplicate |
| # dynamorio targets |
| set(DynamoRIO_INTERNAL ON) |
| # our included DynamoRIO project will set DynamoRIO_SOURCE_DIR in cache |
| # for us so we'll get proper include dirs for extensions. |
| |
| find_package(DynamoRIO ${DynamoRIO_VERSION_REQUIRED}) |
| if (NOT DynamoRIO_FOUND OR |
| # make sure it didn't go find some other pre-built version after |
| # seeing that the local one is somehow not suitable |
| NOT "${DynamoRIO_CONFIG}" STREQUAL "${DynamoRIO_DIR}/DynamoRIOConfig.cmake") |
| message(FATAL_ERROR "Local DynamoRIO mis-configured") |
| endif () |
| |
| # Restore global flags |
| foreach (config "" ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES}) |
| if ("${config}" STREQUAL "") |
| set(config_upper "") |
| else ("${config}" STREQUAL "") |
| string(TOUPPER "_${config}" config_upper) |
| endif ("${config}" STREQUAL "") |
| foreach (var CMAKE_C_FLAGS${config_upper};CMAKE_CXX_FLAGS${config_upper}) |
| set(${var} "${SAVE_${var}}") |
| endforeach (var) |
| endforeach (config) |
| endif (USER_SPECIFIED_DynamoRIO_DIR) |
| |
| if (USER_SPECIFIED_DynamoRIO_DIR) |
| # if we're building from our own DR, DR adds this option for us |
| option(GENERATE_PDBS "generate Windows debug information" ON) |
| mark_as_advanced(GENERATE_PDBS) |
| endif (USER_SPECIFIED_DynamoRIO_DIR) |
| |
| # This must be before any add_library() or add_executable() |
| # but that means for local DR sources we haven't yet included |
| # DR's option(), so we check whether defined. |
| if (DEFINED GENERATE_PDBS AND NOT GENERATE_PDBS) |
| # Default from cmake in DEBUG and RELWITHDEBINFO has /debug |
| foreach (var CMAKE_C_FLAGS;CMAKE_CXX_FLAGS; |
| CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}; |
| CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UPPER}; |
| # tests are always built as Debug |
| CMAKE_C_FLAGS_DEBUG;CMAKE_CXX_FLAGS_DEBUG) |
| string(REGEX REPLACE "/Zi" "" ${var} "${${var}}") |
| endforeach () |
| foreach (var CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UPPER}; |
| CMAKE_MODULE_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UPPER}; |
| CMAKE_SHARED_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UPPER}; |
| # tests are always built as Debug |
| CMAKE_EXE_LINKER_FLAGS_DEBUG; |
| CMAKE_MODULE_LINKER_FLAGS_DEBUG; |
| CMAKE_SHARED_LINKER_FLAGS_DEBUG) |
| string(REGEX REPLACE "/debug" "" ${var} "${${var}}") |
| endforeach () |
| endif (DEFINED GENERATE_PDBS AND NOT GENERATE_PDBS) |
| |
| # Shrink binaries and pdbs (/Gy should already be there) |
| if (WIN32) |
| foreach (var CMAKE_EXE_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UPPER}; |
| CMAKE_MODULE_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UPPER}; |
| CMAKE_SHARED_LINKER_FLAGS_${CMAKE_BUILD_TYPE_UPPER}) |
| set(${var} "${${var}} /opt:ref /opt:icf /pdbcompress") |
| endforeach () |
| endif () |
| |
| if (APPLE) |
| # install_name_tool needs write access (i#1372) |
| set(owner_access OWNER_READ OWNER_WRITE) |
| else (APPLE) |
| set(owner_access OWNER_READ) |
| endif (APPLE) |
| |
| ################################################## |
| # now that we have ${DynamoRIO_DIR} we can configure docs |
| |
| find_package(Doxygen) |
| if (NOT DOXYGEN_FOUND) |
| # We'd like to require doxygen for Windows pre-commit suite but it's not |
| # installed on our bots so we live with just Linux catching docs errors. |
| # Ditto for Mac. |
| if (TEST_SUITE AND UNIX AND NOT APPLE) |
| message(FATAL_ERROR "doxygen is required to build the documentation") |
| else () |
| # Non-fatal for a single, un-official build, or on Windows |
| message(WARNING "doxygen not found: documentation will NOT be built") |
| endif () |
| else () |
| add_subdirectory(docs) |
| endif () |
| |
| ################################################## |
| # assembly support |
| |
| # set up assembly support and CMAKE_CPP |
| set(old_debug ${DEBUG}) |
| set(DEBUG ON) # ensure we get debug info |
| include(${DynamoRIO_DIR}/cpp2asm_support.cmake) |
| set(DEBUG ${old_debug}) |
| |
| if (UNIX) |
| if (NOT CMAKE_ASM_SUPPORTS_INTEL_SYNTAX) |
| message(FATAL_ERROR "${CMAKE_ASM_COMPILER} does not support required flags") |
| endif (NOT CMAKE_ASM_SUPPORTS_INTEL_SYNTAX) |
| endif (UNIX) |
| # for cpp2asm_defines.h |
| include_directories(${DynamoRIO_DIR}) |
| |
| # XXX: even if we went to a configure.h, we wouldn't have the DR platform |
| # defines there unless we duplicated them. |
| if (UNIX) |
| if (APPLE) |
| set(DEFINES ${DEFINES} -DASSEMBLE_WITH_NASM) |
| else (APPLE) |
| set(DEFINES ${DEFINES} -DASSEMBLE_WITH_GAS) |
| endif (APPLE) |
| else (UNIX) |
| set(DEFINES ${DEFINES} -DASSEMBLE_WITH_MASM) |
| endif (UNIX) |
| get_DynamoRIO_defines(DR_DEFINES OFF) |
| # We need defines to be a list to pass as separate args to custom command. |
| # We assume none have spaces inside them which seems reasonable. |
| string(REPLACE " " ";" DR_DEFINES "${DR_DEFINES}") |
| set(asm_defs ${DR_DEFINES} ${DEFINES} -I "${DynamoRIO_DIR}") |
| |
| set(asm_deps "${DynamoRIO_DIR}/cpp2asm_defines.h") |
| |
| if (ARM) |
| set(asm_file "asm_utils_arm.asm") |
| else () |
| set(asm_file "asm_utils_x86.asm") |
| endif () |
| add_asm_target(common/${asm_file} asm_utils_src asm_utils_tgt "" |
| "${asm_defs}" "${asm_deps}") |
| |
| ################################################## |
| |
| if (ANDROID) |
| # We cache this for us in sub-projects like framework/samples/ |
| set(TOP_BINARY_DIR ${PROJECT_BINARY_DIR}) |
| get_filename_component(builddir ${TOP_BINARY_DIR} NAME) |
| set(DRM_DEVICE_BINARY_DIR ${DRM_DEVICE_BASEDIR}/${builddir}) |
| endif () |
| |
| function (copy_target_to_device target) |
| if (DRM_COPY_TO_DEVICE) |
| DynamoRIO_copy_target_to_device(${target} ${DRM_DEVICE_BASEDIR}) |
| endif () |
| endfunction (copy_target_to_device) |
| |
| function (copy_file_to_device local_path) |
| if (DRM_COPY_TO_DEVICE) |
| file(RELATIVE_PATH relpath "${TOP_BINARY_DIR}" "${local_path}") |
| execute_process( |
| COMMAND ${ADB} push ${local_path} ${DRM_DEVICE_BINARY_DIR}/${relpath} |
| RESULT_VARIABLE adb_result ERROR_VARIABLE adb_err OUTPUT_QUIET) |
| if (adb_result) |
| message(FATAL_ERROR "*** Failed to adb push ${local_path}: ${adb_err} ***\n") |
| endif () |
| endif () |
| endfunction (copy_file_to_device) |
| |
| function (get_target_path_for_execution out target) |
| if (ANDROID) |
| DynamoRIO_get_target_path_for_execution(local ${target} ${DRM_DEVICE_BASEDIR}) |
| else () |
| DynamoRIO_get_target_path_for_execution(local ${target} "") |
| endif () |
| set(${out} ${local} PARENT_SCOPE) |
| endfunction (get_target_path_for_execution) |
| |
| function (convert_local_path_to_device_path out local_path) |
| if (ANDROID) |
| file(RELATIVE_PATH relpath "${TOP_BINARY_DIR}" "${local_path}") |
| set(local ${DRM_DEVICE_BINARY_DIR}/${relpath}) |
| else () |
| set(local ${local_path}) |
| endif () |
| set(${out} ${local} PARENT_SCOPE) |
| endfunction (convert_local_path_to_device_path) |
| |
| function (prefix_cmd_if_necessary cmd_out use_ats cmd_in) |
| DynamoRIO_prefix_cmd_if_necessary(local ${use_ats} ${cmd_in} ${ARGN}) |
| set(${cmd_out} ${local} PARENT_SCOPE) |
| endfunction (prefix_cmd_if_necessary) |
| |
| function (copy_and_adjust_drpaths basedir target) |
| if (ANDROID AND DRM_COPY_TO_DEVICE) |
| file(GLOB drpaths ${target}/*${target}*.drpath) |
| foreach(drpath ${drpaths}) # we only expect one though |
| file(READ ${drpath} contents) |
| string(REPLACE "${PROJECT_BINARY_DIR}" "${DRM_DEVICE_BINARY_DIR}" |
| contents ${contents}) |
| file(WRITE ${drpath} ${contents}) |
| copy_file_to_device(${drpath}) |
| endforeach () |
| endif () |
| endfunction () |
| |
| if (WIN32) |
| set(FLAG_DISABLE_FPO "/Oy-") |
| else (WIN32) |
| set(FLAG_DISABLE_FPO "-fno-omit-frame-pointer") |
| endif (WIN32) |
| |
| function(append_src_compile_flags srcfile new_flags) |
| get_source_file_property(cur_flags ${srcfile} COMPILE_FLAGS) |
| # XXX: if we require cmake 2.8.6 we can simply use APPEND_STRING |
| if (NOT cur_flags) |
| set(cur_flags "") |
| endif (NOT cur_flags) |
| set_source_files_properties(${srcfile} PROPERTIES |
| COMPILE_FLAGS "${cur_flags} ${new_flags}") |
| endfunction(append_src_compile_flags) |
| |
| # new set_property() doesn't want -D but our cpp invocation above does |
| string(REGEX REPLACE "-D" "" DEFINES_NO_D "${DEFINES}") |
| string(REGEX REPLACE "-D" "" DR_DEFINES_NO_D "${DR_DEFINES}") |
| |
| option(BUILD_TOOL_TESTS "build Dr. Memory/Dr. Heapstat tests" ON) |
| |
| if (TOOL_DR_HEAPSTAT) |
| # Dr. Heapstat |
| set(srcs |
| drheapstat/drheapstat.c |
| drheapstat/staleness.c |
| common/alloc.c |
| common/alloc_unopt.c |
| common/alloc_replace.c |
| common/heap.c |
| common/callstack.c |
| common/utils.c |
| common/utils_shared.c |
| ${asm_utils_src} |
| common/redblack.c |
| common/crypto.c |
| # For leak checking we need stack.c but it pulls in the inter-dependent |
| # slowpath, fastpath, and shadow: we'll want those for staleness anyway. |
| # Looking more and more like Dr. Memory! |
| drmemory/annotations.c |
| drmemory/leak.c |
| drmemory/options.c |
| drmemory/stack.c |
| drmemory/instru.c |
| drmemory/spill.c |
| drmemory/slowpath.c |
| drmemory/fastpath.c |
| drmemory/shadow.c |
| drmemory/perturb.c) |
| else (TOOL_DR_HEAPSTAT) |
| # Dr. Memory |
| set(srcs |
| drmemory/annotations.c |
| drmemory/drmemory.c |
| drmemory/instru.c |
| drmemory/spill.c |
| drmemory/slowpath.c |
| drmemory/fastpath.c |
| drmemory/stack.c |
| drmemory/shadow.c |
| drmemory/options.c |
| drmemory/pattern.c |
| common/alloc.c |
| common/alloc_unopt.c |
| common/alloc_replace.c |
| common/heap.c |
| common/callstack.c |
| drmemory/alloc_drmem.c |
| drmemory/syscall.c |
| drmemory/report.c |
| drmemory/replace.c |
| drmemory/leak.c |
| drmemory/perturb.c |
| common/utils.c |
| common/utils_shared.c |
| ${asm_utils_src} |
| common/redblack.c |
| common/crypto.c |
| drmemory/fuzzer.c) |
| if (UNIX) |
| if (APPLE) |
| set(srcs ${srcs} drmemory/syscall_macos.c) |
| else (APPLE) |
| set(srcs ${srcs} drmemory/syscall_linux.c) |
| endif (APPLE) |
| else (UNIX) |
| set(srcs ${srcs} drmemory/syscall_windows.c) |
| set(srcs ${srcs} drmemory/syscall_wingdi.c) |
| set(srcs ${srcs} drmemory/gdicheck.c) |
| set(srcs ${srcs} drmemory/handlecheck.c) |
| endif (UNIX) |
| set(scripts ${toolname}.pl) |
| endif (TOOL_DR_HEAPSTAT) |
| |
| if (X86) |
| set(srcs ${srcs} drmemory/slowpath_x86.c) |
| set(srcs ${srcs} drmemory/stack_x86.c) |
| set(srcs ${srcs} drmemory/fastpath_x86.c) |
| else () |
| set(srcs ${srcs} drmemory/slowpath_arm.c) |
| set(srcs ${srcs} drmemory/stack_arm.c) |
| set(srcs ${srcs} drmemory/fastpath_arm.c) |
| endif () |
| |
| if (WIN32) |
| set(srcs ${srcs} make/resources.rc) |
| endif () |
| |
| if (NOT USE_DRSYMS) |
| set(scripts ${scripts} postprocess.pl) |
| endif (NOT USE_DRSYMS) |
| |
| if (USE_DRSYMS) |
| # front-end needs to be named ${toolname}.exe and thus has ${toolsname}.pdb, so |
| # we rename client lib (plus cmake best w/o same-name targets) |
| set(client_target "${toolname}lib") |
| if (TOOL_DR_MEMORY) |
| set(frontend_srcs drmemory/frontend.c drmemory/options.c) |
| else (TOOL_DR_MEMORY) |
| set(frontend_srcs drheapstat/drheapstat_frontend.c) |
| endif (TOOL_DR_MEMORY) |
| if (WIN32) |
| set(frontend_srcs ${frontend_srcs} make/resources.rc) |
| endif () |
| add_executable(${toolname} ${frontend_srcs}) |
| if (ANDROID AND TOOL_DR_MEMORY) |
| # There's no DT_RPATH support so we have a script set the load path. |
| # To avoid confusion we rename the exe. |
| set(frontend_name "launcher") |
| set_target_properties(${toolname} PROPERTIES OUTPUT_NAME "${frontend_name}") |
| configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${tooldir}/launcher_android.sh" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/${toolname}" @ONLY) |
| copy_file_to_device("${PROJECT_BINARY_DIR}/${BUILD_BIN}/${toolname}") |
| endif () |
| if (WIN32) |
| target_link_libraries(${toolname} dbghelp) |
| endif (WIN32) |
| copy_target_to_device(${toolname}) |
| else (USE_DRSYMS) |
| set(client_target ${toolname}) |
| endif (USE_DRSYMS) |
| |
| macro(set_library_version target number) |
| # We only set the version/soversion on Windows to avoid many |
| # negatives (DRi#1374, DRi#2127, Android "adb push" not supporting |
| # symlinks, etc.) and very few positives on UNIX platforms. DR's |
| # loader and the DRMF init code perform their own version checks for |
| # client compatibility. |
| if (WINDOWS) |
| set_target_properties(${target} PROPERTIES VERSION ${number}) |
| endif () |
| endmacro() |
| |
| add_library(${client_target} SHARED ${srcs}) |
| set_library_version(${client_target} ${TOOL_VERSION_NUMBER}) |
| set_property(TARGET ${client_target} PROPERTY COMPILE_DEFINITIONS |
| # If we end up wanting this for other DEFINES uses above we'll have to set |
| # client_target earlier. For now we only need for the C code. |
| "${DEFINES_NO_D};CLIENT_LIBNAME=${client_target};RC_IS_TOOLLIB") |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # ensure race-free parallel builds |
| add_dependencies(${client_target} ${asm_utils_tgt}) |
| endif ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| copy_target_to_device(${client_target}) |
| |
| # We require frames in our replacement routines in order to reliably include |
| # the allocator routines in the callstack for i#639. Xref i#958. |
| append_src_compile_flags(common/alloc_replace.c ${FLAG_DISABLE_FPO}) |
| |
| if (WIN32) |
| # our addr2line for Windows |
| add_executable(winsyms tools/winsyms.c make/resources.rc) |
| target_link_libraries(winsyms dbghelp) |
| set_property(TARGET winsyms PROPERTY COMPILE_DEFINITIONS |
| # We need full defines to get version values for resources |
| "${DEFINES_NO_D};RC_IS_WINSYMS") |
| # configure_DynamoRIO_client clears global flags so add as additional |
| # request static libc to avoid manifest files and libc portability issues |
| string(REGEX REPLACE "/MD" "/MT" CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER} |
| "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}}") |
| set_source_files_properties(tools/winsyms.c PROPERTIES |
| COMPILE_FLAGS "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER}}") |
| |
| # Helper tool to ensure we have version info in our binaries: |
| add_executable(verinfo tools/verinfo.c make/resources.rc) |
| target_link_libraries(verinfo version) |
| set_property(TARGET verinfo PROPERTY COMPILE_DEFINITIONS |
| "${DEFINES_NO_D};RC_IS_VERINFO") |
| |
| # i#1009c#4: auto-register Dr. Memory as a Visual Studio External Tool |
| add_executable(vs_external_tool tools/vs_external_tool.c make/resources.rc) |
| set_property(TARGET vs_external_tool PROPERTY COMPILE_DEFINITIONS |
| "${DEFINES_NO_D};RC_IS_VS_EXTERNAL_TOOL") |
| endif (WIN32) |
| |
| # we want a preferred base to avoid patching pcaches |
| set(DynamoRIO_SET_PREFERRED_BASE ON) |
| if (ANDROID) |
| # i#1881: 0x73800000 seems to conflict w/ hardcoded Android mmaps. |
| set(PREFERRED_BASE 0x17000000) |
| else () |
| set(PREFERRED_BASE 0x73800000) |
| endif () |
| |
| # we can handle being tied to a particular DR version (we already are) |
| set(DynamoRIO_FAST_IR ON) |
| |
| set(DynamoRIO_REG_COMPATIBILITY ON) |
| if (NOT STATIC_DRSYMS) |
| set(DynamoRIO_USE_LIBC OFF) |
| endif (NOT STATIC_DRSYMS) |
| configure_DynamoRIO_client(${client_target}) |
| # i#277/PR 540817: features split into DynamoRIO Extensions |
| use_DynamoRIO_extension(${client_target} drcontainers) |
| # For efficiency, we use the static versions of DR's extensions. We have the same |
| # LGPL license as drutil and drwrap so it works out. |
| use_DynamoRIO_extension(${client_target} drmgr_static) |
| use_DynamoRIO_extension(${client_target} drx_static) |
| use_DynamoRIO_extension(${client_target} drutil_static) |
| use_DynamoRIO_extension(${client_target} drwrap_static) |
| use_DynamoRIO_extension(${client_target} drreg_static) |
| # DRi#1829: we discussed invoking drcov as a separate client, which would require using |
| # all shared ext libs. We ended up making drcovlib. |
| use_DynamoRIO_extension(${client_target} drcovlib_static) |
| set_target_properties(${client_target} PROPERTIES |
| # dlls are put in runtime dir but we want lib dir |
| RUNTIME_OUTPUT_DIRECTORY${location_suffix} "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") |
| if (WIN32) |
| # annoying to have ASLR and not on module list |
| # plus, now we require the same base for pcache |
| set(new_flags "/dynamicbase:no") |
| |
| # This flag is added by VS generators so we may as well add for Ninja |
| set(new_flags "/nxcompat") |
| |
| # Reduce size by stripping out unused code (we don't seem to need /Gy for this, |
| # and VS generators seem to set it already, so we add here for Ninja). |
| # XXX: DRi#2167 is adding this for all clients so we can remove this once |
| # we update to a recent DR. |
| set(new_flags "${new_flags} /opt:ref") |
| if (NOT DEBUG_BUILD) |
| # Match DR's settings, though again it's not clear the benefit w/o /Gy. |
| set(new_flags "${new_flags} /opt:icf") |
| endif() |
| |
| if (NOT DEFINED GENERATE_PDBS OR GENERATE_PDBS) |
| set(new_flags "${new_flags} /debug") |
| endif () |
| get_target_property(cur_flags ${client_target} LINK_FLAGS) |
| if (NOT cur_flags) |
| set(cur_flags "") |
| endif (NOT cur_flags) |
| set_target_properties(${client_target} PROPERTIES |
| LINK_FLAGS "${cur_flags} ${new_flags}") |
| endif (WIN32) |
| if (USE_DRSYMS) |
| if (DEFINED DynamoRIO_RPATH) |
| set(old_rpath ${DynamoRIO_RPATH}) |
| else () |
| set(old_rpath OFF) |
| endif () |
| set(DynamoRIO_RPATH ON) |
| configure_DynamoRIO_standalone(${toolname}) |
| set(DynamoRIO_RPATH ${old_rpath}) |
| target_link_libraries(${toolname} drinjectlib drconfiglib drfrontendlib) |
| if (WIN32) |
| set_target_properties(${toolname} PROPERTIES |
| VERSION ${TOOL_VERSION_NUMBER} |
| COMPILE_DEFINITIONS "${DEFINES_NO_D};RC_IS_FRONTEND") |
| else (WIN32) |
| DynamoRIO_add_rel_rpaths(${toolname} drinjectlib) |
| DynamoRIO_add_rel_rpaths(${toolname} drconfiglib) |
| set_property(TARGET ${toolname} PROPERTY COMPILE_DEFINITIONS ${DEFINES_NO_D}) |
| endif (WIN32) |
| if (STATIC_DRSYMS) |
| use_DynamoRIO_extension(${client_target} drsyms_static) |
| else () |
| # N.B.: static drsyms gives us kernel32 imports from elftoolchain |
| # libc use. If we end up needing late kernel32 use for early |
| # injection we may want to go back to dynamic drsyms (and delayed |
| # dr_enable_console_printing()). |
| use_DynamoRIO_extension(${client_target} drsyms) |
| endif () |
| endif (USE_DRSYMS) |
| if (WIN32) |
| # We need to link with ntdll.lib and dbghelp.lib which we get from DR |
| if (USER_SPECIFIED_DynamoRIO_DIR) |
| get_target_property(libbase drinjectlib LOCATION) |
| get_filename_component(libpath ${libbase} PATH) |
| set(ntimp_lib "${libpath}/ntdll_imports.lib") |
| set(dbghelp_lib "${libpath}/dbghelp_imports.lib") |
| else () |
| # DR now has ntdll_imports as a normal lib target |
| set(ntimp_lib ntdll_imports) |
| # XXX: This relies on knowing where DR puts it. |
| # One option is ExternalProject to install the local DR first: xref i#1061. |
| set(dbghelp_lib "${PROJECT_BINARY_DIR}/dynamorio/ext/drsyms/dbghelp_imports.lib") |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # for parallel build correctness we need a target dependence |
| add_dependencies(${client_target} ntdll_imports) |
| if (TOOL_DR_MEMORY) |
| add_dependencies(${toolname} dbghelp_tgt) |
| endif () |
| endif () |
| endif () |
| |
| # Front-end uses dbghelp routines not in VS2005 so we link w/ DR's import lib. |
| target_link_libraries(${toolname} ${dbghelp_lib}) |
| |
| # we have to link with ntdll AFTER any libcmt.lib from configure_DynamoRIO_client |
| # or use_DynamoRIO_extension (w/ static libs) |
| target_link_libraries(${client_target} ${ntimp_lib}) |
| # we used to statically link with msvcrt.lib for vc /O2's use of __aulldvrm, |
| # and it didn't add any dynamic dependence on libc, except now that we |
| # use static extension libraries it does add msvcr*.dll imports! |
| # so I removed "msvcrt" from target_link_libraries() and so far haven't |
| # hit the __aulldvrm issue. |
| endif (WIN32) |
| |
| # Build Qt Visualizer |
| if (TOOL_DR_HEAPSTAT) |
| find_package(Qt5Widgets QUIET) |
| if (NOT Qt5Widgets_FOUND) |
| message(STATUS "Could NOT find Qt 5: Dr. Heapstat visualizer will not be built") |
| message(STATUS |
| "Point CMake variable Qt5Widgets_DIR at the Qt5WidgetsConfig.cmake directory") |
| else (NOT Qt5Widgets_FOUND) |
| message(STATUS "Found Qt 5: Dr. Heapstat visualizer will be built") |
| add_subdirectory(drheapstat/visualizer) |
| endif (NOT Qt5Widgets_FOUND) |
| endif (TOOL_DR_HEAPSTAT) |
| |
| # |
| ################################################## |
| |
| # must be AFTER DR local build since affects subdirs |
| include_directories(common ${tooldir} "third_party/valgrind") |
| |
| if (UNIX) |
| set(DISABLE_OPTS "-O0") |
| else (UNIX) |
| set(DISABLE_OPTS "/Od") |
| endif (UNIX) |
| append_src_compile_flags(common/alloc_unopt.c "${DISABLE_OPTS}") |
| if (UNIX) |
| # i#1776: avoid an infinite loop in replace_memset. |
| # We have no per-function optimization so we apply to the whole file. |
| append_src_compile_flags(drmemory/replace.c "${DISABLE_OPTS}") |
| endif () |
| |
| # symbol query tool |
| set(symquery_srcs tools/symquery.c) |
| if (WIN32) |
| set(symquery_srcs ${symquery_srcs} make/resources.rc) |
| endif () |
| add_executable(symquery ${symquery_srcs}) |
| if (DEFINED DynamoRIO_RPATH) |
| set(old_rpath ${DynamoRIO_RPATH}) |
| else () |
| set(old_rpath OFF) |
| endif () |
| set(DynamoRIO_RPATH ON) |
| configure_DynamoRIO_standalone(symquery) |
| use_DynamoRIO_extension(symquery drsyms_static) |
| set(DynamoRIO_RPATH ${old_rpath}) |
| # drfrontendlib depends on drinjectlib, DR-i#1409 should be the solution |
| target_link_libraries(symquery drinjectlib drfrontendlib) |
| if (WIN32) |
| set_target_properties(symquery PROPERTIES VERSION ${TOOL_VERSION_NUMBER} |
| COMPILE_DEFINITIONS |
| # We need full defines to get version values for resources |
| "${DEFINES_NO_D};RC_IS_SYMQUERY") |
| else (WIN32) |
| DynamoRIO_add_rel_rpaths(symquery drinjectlib) |
| endif (WIN32) |
| |
| # should go into a configure.h if we get enough of these |
| set(script_aux "") |
| if (PERL_TO_EXE) |
| foreach (pl ${scripts}) |
| get_filename_component(base ${pl} NAME_WE) |
| if ("${pl}" MATCHES "${toolname}.pl") |
| set(EXE_DEST "${PROJECT_BINARY_DIR}/${BUILD_BIN_PREFIX}") |
| set(script_main ${EXE_DEST}/${base}.exe) |
| else () |
| set(EXE_DEST "${PROJECT_BINARY_DIR}/${BUILD_BIN}") |
| set(script_aux ${script_aux} ${EXE_DEST}/${base}.exe) |
| endif () |
| add_custom_target(${base}_exe ALL DEPENDS ${EXE_DEST}/${base}.exe) |
| add_custom_command( |
| OUTPUT ${EXE_DEST}/${base}.exe |
| DEPENDS ${PROJECT_SOURCE_DIR}/${tooldir}/${pl} |
| COMMAND ${PERL_EXECUTABLE} |
| # If do glob() w/ spaces in path, need Text::ParseWords, but pp |
| # doesn't find it as a dependence automatically. |
| # FIXME: use --gui? |
| ARGS ${PERL_PP} -M Text::ParseWords -o ${EXE_DEST}/${base}.exe |
| ${PROJECT_SOURCE_DIR}/${tooldir}/${pl} ${options_for_perl} |
| VERBATIM) |
| endforeach (pl) |
| endif (PERL_TO_EXE) |
| |
| # support running out of build dir |
| file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/logs") |
| file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/logs/codecache") |
| file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/logs/dynamorio") |
| file(WRITE "${PROJECT_BINARY_DIR}/logs/README" "Directory for logs") # for adb push |
| copy_file_to_device("${PROJECT_BINARY_DIR}/logs") |
| if (NOT PERL_TO_EXE AND NOT USE_DRSYMS) |
| configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${tooldir}/${toolname}.pl" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/${toolname}.pl" @ONLY) |
| if (NOT USE_DRSYMS) |
| configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${tooldir}/postprocess.pl" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/postprocess.pl" COPYONLY) |
| set(script_aux "${CMAKE_CURRENT_SOURCE_DIR}/${tooldir}/postprocess.pl") |
| endif () |
| set(script_main "${PROJECT_BINARY_DIR}/${BUILD_BIN}/${toolname}.pl" |
| "${options_for_perl}") |
| endif () |
| if (WIN32) |
| # copy for winsyms and symquery |
| configure_file("${DBGHELP_DLL}" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/dbghelp.dll" COPYONLY) |
| # Copy symsrv.dll so we can fetch files from the frontend. |
| configure_file("${SYMSRV_DLL}" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/symsrv.dll" COPYONLY) |
| # Create symsrv.yes to avoid the EULA dialog. |
| file(WRITE "${PROJECT_BINARY_DIR}/${BUILD_BIN}/symsrv.yes" "") |
| if (USER_SPECIFIED_DynamoRIO_DIR) |
| # already built so we can copy at config time |
| configure_file("${DynamoRIO_DIR}/../${LIB_ARCH}/drconfiglib.dll" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfiglib.dll" COPYONLY) |
| configure_file("${DynamoRIO_DIR}/../${LIB_ARCH}/drinjectlib.dll" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drinjectlib.dll" COPYONLY) |
| if (USE_DRSYMS) |
| configure_file("${DynamoRIO_DIR}/../${BIN_ARCH}/drconfig.exe" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfig.exe" COPYONLY) |
| if (NOT STATIC_DRSYMS AND TOOL_DR_MEMORY) |
| # symquery needs drsyms.dll in same dir |
| configure_file("${DynamoRIO_DIR}/../ext/${LIB_ARCH}/${build_type}/drsyms.dll" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drsyms.dll" COPYONLY) |
| endif (NOT STATIC_DRSYMS AND TOOL_DR_MEMORY) |
| # symquery needs dynamorio.dll in same dir |
| # frontend now imports from DR (i#885) |
| configure_file("${DynamoRIO_DIR}/../${LIB_ARCH}/${build_type}/dynamorio.dll" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/dynamorio.dll" COPYONLY) |
| endif (USE_DRSYMS) |
| else (USER_SPECIFIED_DynamoRIO_DIR) |
| # XXX: I can't get "TARGET drconfiglib POST_BUILD" to work, maybe b/c |
| # the target is in a subdir? |
| set(drconfiglib_copy "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfiglib.dll") |
| add_custom_target(drconfiglib_copy_tgt ALL DEPENDS "${drconfiglib_copy}") |
| add_custom_command(OUTPUT "${drconfiglib_copy}" DEPENDS drconfiglib |
| COMMAND ${CMAKE_COMMAND} |
| ARGS -E copy "${DynamoRIO_DIR}/../${LIB_ARCH}/drconfiglib.dll" |
| "${drconfiglib_copy}" VERBATIM) |
| set(drinjectlib_copy "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drinjectlib.dll") |
| add_custom_target(drinjectlib_copy_tgt ALL DEPENDS "${drinjectlib_copy}") |
| add_custom_command(OUTPUT "${drinjectlib_copy}" DEPENDS drinjectlib |
| COMMAND ${CMAKE_COMMAND} |
| ARGS -E copy "${DynamoRIO_DIR}/../${LIB_ARCH}/drinjectlib.dll" |
| "${drinjectlib_copy}" VERBATIM) |
| if (USE_DRSYMS) |
| set(drconfigexe_copy "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfig.exe") |
| add_custom_target(drconfigexe_copy_tgt ALL DEPENDS "${drconfigexe_copy}") |
| add_custom_command(OUTPUT "${drconfigexe_copy}" DEPENDS drconfig |
| COMMAND ${CMAKE_COMMAND} |
| ARGS -E copy "${DynamoRIO_DIR}/../${BIN_ARCH}/drconfig.exe" |
| "${drconfigexe_copy}" VERBATIM) |
| if (NOT STATIC_DRSYMS AND TOOL_DR_MEMORY) |
| # symquery needs drsyms.dll in same dir |
| set(drsymsdll_copy "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drsyms.dll") |
| add_custom_target(drsymsdll_copy_tgt ALL DEPENDS "${drsymsdll_copy}") |
| add_custom_command(OUTPUT "${drsymsdll_copy}" DEPENDS drsyms |
| COMMAND ${CMAKE_COMMAND} |
| ARGS -E copy "${DynamoRIO_DIR}/../ext/${LIB_ARCH}/${build_type}/drsyms.dll" |
| "${drsymsdll_copy}" VERBATIM) |
| endif (NOT STATIC_DRSYMS AND TOOL_DR_MEMORY) |
| # symquery needs dynamorio.dll in same dir |
| # frontend now imports from DR (i#885) |
| set(drdll_copy "${PROJECT_BINARY_DIR}/${BUILD_BIN}/dynamorio.dll") |
| add_custom_target(drdll_copy_tgt ALL DEPENDS "${drdll_copy}") |
| add_custom_command(OUTPUT "${drdll_copy}" DEPENDS dynamorio |
| COMMAND ${CMAKE_COMMAND} |
| ARGS -E copy "${DynamoRIO_DIR}/../${LIB_ARCH}/${build_type}/dynamorio.dll" |
| "${drdll_copy}" VERBATIM) |
| endif (USE_DRSYMS) |
| endif (USER_SPECIFIED_DynamoRIO_DIR) |
| if (USE_DRSYMS) |
| # above copy is for winsyms and symquery, this is for drmemorylib |
| configure_file("${DBGHELP_DLL}" |
| "${PROJECT_BINARY_DIR}/${BUILD_LIB}/dbghelp.dll" COPYONLY) |
| # We don't need to copy symsrv.dll because only the frontend uses it. |
| endif (USE_DRSYMS) |
| else (WIN32) |
| if (USER_SPECIFIED_DynamoRIO_DIR) |
| # already built so we can copy at config time |
| configure_file("${DynamoRIO_DIR}/../${BIN_ARCH}/drconfig" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfig" COPYONLY) |
| else (USER_SPECIFIED_DynamoRIO_DIR) |
| set(drconfig_copy "${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfig") |
| add_custom_target(drconfig_copy_tgt ALL DEPENDS "${drconfig_copy}") |
| add_custom_command(OUTPUT "${drconfig_copy}" |
| DEPENDS drconfig |
| COMMAND ${CMAKE_COMMAND} |
| ARGS -E copy "${DynamoRIO_DIR}/../${BIN_ARCH}/drconfig" |
| "${drconfig_copy}" VERBATIM) |
| endif (USER_SPECIFIED_DynamoRIO_DIR) |
| if (TOOL_DR_MEMORY) |
| configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/valgrind2drmemory.pl" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/valgrind2drmemory.pl" COPYONLY) |
| endif (TOOL_DR_MEMORY) |
| endif (WIN32) |
| if (TOOL_DR_HEAPSTAT) |
| # we need a copy of Dr. Memory's postprocess for leaks (PR 536878) |
| if (PERL_TO_EXE) |
| message(FATAL_ERROR "perl2exe for Dr. Heapstat not supported") |
| endif (PERL_TO_EXE) |
| configure_file("${CMAKE_CURRENT_SOURCE_DIR}/drmemory/postprocess.pl" |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/postleaks.pl" COPYONLY) |
| set(script_aux ${script_aux} "${PROJECT_BINARY_DIR}/${BUILD_BIN}/postleaks.pl") |
| endif (TOOL_DR_HEAPSTAT) |
| |
| # Dr. Memory and Dr. Heapstat use Dr. Memory's default suppressions |
| set(defsupp_out "${PROJECT_BINARY_DIR}/${BUILD_BIN}/suppress-default.txt") |
| if (WIN32) |
| set(defsupp_in "${CMAKE_CURRENT_SOURCE_DIR}/drmemory/suppress-default.win.txt") |
| configure_file("${defsupp_in}" "${defsupp_out}" COPYONLY) |
| else (WIN32) |
| if (APPLE) |
| set(defsupp_in "${CMAKE_CURRENT_SOURCE_DIR}/drmemory/suppress-default.mac.txt") |
| else (APPLE) |
| set(defsupp_in "${CMAKE_CURRENT_SOURCE_DIR}/drmemory/suppress-default.lin.txt") |
| endif (APPLE) |
| file(READ "${defsupp_in}" txt) |
| file(WRITE "${defsupp_out}" "${txt}") |
| endif (WIN32) |
| copy_file_to_device("${defsupp_out}") |
| |
| ########################################################################### |
| # Tests |
| |
| # We need to add_subdirectory after we know where ntdll_imports.lib is. |
| # That means we've messed with global things like include dirs already, |
| # for configure_DynamoRIO_client(), but having the extension include |
| # dirs in there should be harmless to the tests. |
| if (BUILD_TOOL_TESTS) |
| enable_testing() |
| add_subdirectory(tests) |
| endif (BUILD_TOOL_TESTS) |
| |
| ########################################################################### |
| # Create tool config files for running with "drrun -t" |
| |
| set(DRRUN_DIR "${PROJECT_BINARY_DIR}/drrun") |
| file(MAKE_DIRECTORY "${DRRUN_DIR}") |
| |
| if (X64) |
| set(BIT_SFX "64") |
| else () |
| set(BIT_SFX "32") |
| endif () |
| set(DRRUN_SFX ".drrun${BIT_SFX}") |
| if (BUILDING_SUB_PACKAGE) |
| set(DRRUN_INSTALL "tools/") |
| else () |
| set(DRRUN_INSTALL "${DR_install_dir}/tools/") |
| endif () |
| |
| function (create_drrun_file frontend file_out name) # option list follows name |
| get_target_property(frontend_path ${frontend} LOCATION${location_suffix}) |
| get_filename_component(frontend_name ${frontend_path} NAME) |
| if (ANDROID AND TOOL_DR_MEMORY) |
| set(frontend_name ${toolname}) # point at script, not launcher |
| endif () |
| if (BUILDING_SUB_PACKAGE) |
| set(DRRUN_TOP "FRONTEND_REL=${INSTALL_PREFIX}/${BUILD_BIN}/${frontend_name}") |
| else () |
| set(DRRUN_TOP "FRONTEND_REL=../${BUILD_BIN}/${frontend_name}") |
| endif () |
| set(DRRUN_FILE "${DRRUN_DIR}/${name}${DRRUN_SFX}") |
| file(WRITE ${DRRUN_FILE} "# Dr. Memory tool config file\n") |
| file(APPEND ${DRRUN_FILE} "${DRRUN_TOP}\n") |
| file(APPEND ${DRRUN_FILE} "TOOL_OP=-dr\n") |
| file(APPEND ${DRRUN_FILE} "TOOL_OP_DR_PATH\n") |
| file(APPEND ${DRRUN_FILE} "TOOL_OP_DR_BUNDLE=-dr_ops\n") |
| foreach (op ${ARGN}) |
| file(APPEND ${DRRUN_FILE} "TOOL_OP=${op}\n") |
| endforeach () |
| if (X64) |
| file(APPEND ${DRRUN_FILE} |
| "USER_NOTICE=Support for 64-bit applications under this tool is experimental. Please report issues to http://drmemory.org/issues.\n") |
| endif () |
| install(FILES "${DRRUN_FILE}" DESTINATION "${DRRUN_INSTALL}/") |
| set(${file_out} ${DRRUN_FILE} PARENT_SCOPE) |
| |
| # DRi#1509: generate a list of tools for drrun usage messages |
| if (NOT DEBUG_BUILD) # avoid dups |
| install(CODE "file(APPEND \"\${CMAKE_INSTALL_PREFIX}/tools/list${BIT_SFX}\" \"${name}\\n\")") |
| endif () |
| endfunction (create_drrun_file) |
| |
| create_drrun_file(${toolname} unused "drmemory") |
| if (NOT X64) |
| create_drrun_file(${toolname} unused "drmemory_light" "-light") |
| endif () |
| if (WIN32) |
| create_drrun_file(${toolname} unused "handle_leaks" "-handle_leaks_only") |
| endif () |
| |
| ########################################################################### |
| # Dr. Memory Framework (DRMF) |
| |
| # We decided against putting the extension inside frameworks/, so |
| # framework-shared code goes here. Things that should be global we |
| # put into functions for invocation inside extension subdirs. |
| |
| set(DRMF_BASEDIR "drmf") |
| set(DRMF_BINBASE "${LIB_ARCH}/${build_type}") |
| set(DRMF_INSTALL "${INSTALL_PREFIX}${DRMF_BASEDIR}") |
| set(DRMF_INSTALL_BIN "${DRMF_INSTALL}/${DRMF_BINBASE}") |
| set(DRMF_INSTALL_INC "${DRMF_INSTALL}/include") |
| set(framework_dir "${PROJECT_BINARY_DIR}/${DRMF_BASEDIR}") |
| set(framework_incdir "${framework_dir}/include") |
| set(framework_bindir "${framework_dir}/${DRMF_BINBASE}") |
| |
| # Versioning: we use separate versioning for DRMF from the tool versioning. |
| # This is major*100 + minor. |
| set(DRMF_VERSION_DEFAULT "1.0.${VERSION_NUMBER_PATCHLEVEL}") |
| set(DRMF_VERSION "" CACHE STRING "DRMF version number: leave empty for default") |
| if ("${DRMF_VERSION}" STREQUAL "") |
| set(DRMF_VERSION ${DRMF_VERSION_DEFAULT}) |
| endif() |
| message(STATUS "DRMF version number: ${DRMF_VERSION}") |
| string(REGEX REPLACE "^([0-9]+)\\..*" "\\1" DRMF_VERSION_MAJOR "${DRMF_VERSION}") |
| string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\..*" "\\1" DRMF_VERSION_MINOR "${DRMF_VERSION}") |
| # We use just major.minor for .so versioning (and no, SOVERSION is not sufficient |
| # here: we have to set VERSION to control the file name and import dependence). |
| string(REGEX REPLACE "^([0-9]+\\.[0-9]+)\\..*" "\\1" |
| DRMF_VERSION_MAJOR_MINOR "${DRMF_VERSION}") |
| math(EXPR DRMF_VERSION_INTEGER "${DRMF_VERSION_MAJOR}*100 + ${DRMF_VERSION_MINOR}") |
| set(DRMF_VERSION_COMPAT 9) # Oldest compatible version |
| set(DRMF_VERSION_CUR ${DRMF_VERSION_INTEGER}) # Current version |
| |
| configure_file(framework/public.h |
| ${framework_incdir}/drmemory_framework.h) |
| include_directories(${framework_incdir}) |
| |
| configure_file(framework/drmf.cmake.in |
| ${framework_dir}/DrMemoryFrameworkConfig.cmake |
| @ONLY) |
| foreach (ext drsyscall umbra drfuzz) |
| file(APPEND ${framework_dir}/DrMemoryFrameworkConfig.cmake " |
| set(DynamoRIO_EXT_${ext}_INC \${drmf_cwd}/include) |
| ") |
| endforeach (ext) |
| configure_file(framework/drmf_version.cmake.in |
| ${framework_dir}/DrMemoryFrameworkConfigVersion.cmake |
| @ONLY) |
| |
| # Export extensions for importing by clients. |
| if (X64) |
| set(exported_targets_name "DRMFTarget64") |
| else (X64) |
| set(exported_targets_name "DRMFTarget32") |
| endif (X64) |
| |
| # DRi#948: we need to map Release and RelMinSize to RelWithDebInfo |
| file(WRITE ${framework_dir}/${exported_targets_name}.cmake "") |
| set(exported_targets_append "") |
| macro(export_target) |
| if ("${CMAKE_VERSION}" VERSION_EQUAL "3.0" OR |
| "${CMAKE_VERSION}" VERSION_GREATER "3.0") |
| set(tgt_args "") |
| else () |
| # We use a prefix primarily to make it easy to test the imported targets, |
| # and to give a better "bundled extensions" feel. |
| set(tgt_args NAMESPACE drmf_) |
| endif () |
| export(TARGETS ${ARGV} ${tgt_args} FILE ${framework_dir}/${exported_targets_name}.cmake |
| APPEND) |
| set(toadd " |
| SET_PROPERTY(TARGET ${ARGV0} PROPERTY MAP_IMPORTED_CONFIG_RELEASE RelWithDebInfo) |
| SET_PROPERTY(TARGET ${ARGV0} PROPERTY MAP_IMPORTED_CONFIG_RELMINSIZE RelWithDebInfo) |
| ") |
| if (NOT DEBUG_BUILD) |
| file(APPEND ${framework_dir}/${exported_targets_name}.cmake ${toadd}) |
| endif (NOT DEBUG_BUILD) |
| # For install we want both debug and release: |
| set(exported_targets_append "${exported_targets_append}${toadd}") |
| set(exported_targets_append "${exported_targets_append}" PARENT_SCOPE) |
| endmacro(export_target) |
| |
| # Included prior to add_subdirectory() for building version.c which |
| # includes utils.h which includes drsyscall.h. |
| include_directories(drsyscall) |
| |
| add_subdirectory(drsyscall) |
| |
| # XXX: change this and include_directories above to |
| # find_package() + use_DynamoRIO_extension(drsyscall) |
| target_link_libraries(${client_target} drsyscall_int) |
| |
| if (USE_DRSYMS) |
| add_subdirectory(drsymcache) |
| include_directories(drsymcache) |
| target_link_libraries(${client_target} drsymcache_int) |
| endif (USE_DRSYMS) |
| |
| # Add Umbra |
| add_subdirectory(umbra) |
| |
| # XXX: change this to find_package() + use_DynamoRIO_extension(umbra) |
| include_directories(umbra) |
| target_link_libraries(${client_target} umbra_int) |
| |
| # Add drfuzz |
| add_subdirectory(drfuzz) |
| |
| # XXX: change this to find_package() + use_DynamoRIO_extension(drfuzz) |
| include_directories(drfuzz) |
| if (TOOL_DR_MEMORY) |
| target_link_libraries(${client_target} drfuzz_int) |
| endif (TOOL_DR_MEMORY) |
| |
| if (BUILD_TOOL_TESTS) |
| add_subdirectory(tests/framework) |
| |
| if (TOOL_DR_MEMORY) |
| # unit tests |
| add_executable(unit_tests ${srcs}) |
| set_property(TARGET unit_tests PROPERTY COMPILE_DEFINITIONS |
| "${DEFINES_NO_D};BUILD_UNIT_TESTS;RC_IS_UNITTESTS") |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # ensure race-free parallel builds |
| add_dependencies(unit_tests ${asm_utils_tgt}) |
| endif ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| if (DEFINED DynamoRIO_RPATH) |
| set(old_rpath ${DynamoRIO_RPATH}) |
| else () |
| set(old_rpath OFF) |
| endif () |
| set(DynamoRIO_RPATH ON) |
| configure_DynamoRIO_standalone(unit_tests) |
| use_DynamoRIO_extension(unit_tests drmgr_static) |
| use_DynamoRIO_extension(unit_tests drcontainers) |
| use_DynamoRIO_extension(unit_tests drmgr_static) |
| use_DynamoRIO_extension(unit_tests drx_static) |
| use_DynamoRIO_extension(unit_tests drutil_static) |
| use_DynamoRIO_extension(unit_tests drwrap_static) |
| use_DynamoRIO_extension(unit_tests drsyms_static) |
| use_DynamoRIO_extension(unit_tests drcovlib_static) |
| target_link_libraries(unit_tests drsyscall_int) |
| target_link_libraries(unit_tests umbra_int) |
| target_link_libraries(unit_tests drsymcache_int) |
| target_link_libraries(unit_tests drfuzz_int) |
| set(DynamoRIO_RPATH ${old_rpath}) |
| get_target_path_for_execution(unit_relpath unit_tests) |
| prefix_cmd_if_necessary(unit_relpath OFF ${unit_relpath}) |
| if (NOT ANDROID) # FIXME i#: not working on Android |
| add_test(unit_tests ${unit_relpath}) |
| endif () |
| copy_target_to_device(unit_tests) |
| endif (TOOL_DR_MEMORY) |
| |
| endif (BUILD_TOOL_TESTS) |
| |
| # XXX i#1497, i#1498: the drstrace front-end now uses drfrontendlib |
| # but there's a bunch of work getting the client to be cross-platform. |
| if (TOOL_DR_MEMORY AND WIN32) |
| # We only build for Dr. Memory b/c we'd need extra work to deal w/ |
| # drheapstat's bin/bin32 different subdir. |
| add_subdirectory(drstrace) |
| endif (TOOL_DR_MEMORY AND WIN32) |
| |
| # FIXME i#1987: enable support of drltrace under MacOS |
| if (NOT APPLE) |
| add_subdirectory(drltrace) |
| endif() |
| |
| add_subdirectory(framework/samples) |
| |
| ########################################################################### |
| # installation |
| |
| if (install_override) |
| if (X64) |
| set(EXP_DIR exports64) |
| else (X64) |
| set(EXP_DIR exports32) |
| endif (X64) |
| set(CMAKE_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/../${EXP_DIR}" |
| CACHE PATH "install path" FORCE) |
| endif (install_override) |
| |
| install(TARGETS ${client_target} |
| RUNTIME DESTINATION "${INSTALL_LIB}" # dll |
| LIBRARY DESTINATION "${INSTALL_LIB}" # .so |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| install(TARGETS symquery DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| if (WIN32) |
| # XXX i#926: remove winsyms once we remove postleaks.pl. |
| # Also removed its pdb below via: PATTERN "winsyms.pdb" EXCLUDE |
| install(TARGETS winsyms DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| install(FILES |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/dbghelp.dll |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/symsrv.dll |
| DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| install(FILES |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/symsrv.yes |
| DESTINATION "${INSTALL_BIN}") |
| if (USE_DRSYMS) |
| install(FILES |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/dbghelp.dll |
| DESTINATION "${INSTALL_LIB}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| endif (USE_DRSYMS) |
| if (USE_DRSYMS) |
| install(FILES |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfiglib.dll |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/drinjectlib.dll |
| # frontend now imports from DR (i#885) |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/dynamorio.dll |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/drconfig.exe |
| DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| endif (USE_DRSYMS) |
| # We want carriage returns for nice viewing in Notepad, etc.: |
| file(READ ${CMAKE_CURRENT_SOURCE_DIR}/README readme_content) |
| string(REPLACE "\n" "\r\n" readme_content ${readme_content}) |
| file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/README.txt ${readme_content}) |
| install(FILES |
| ${CMAKE_CURRENT_BINARY_DIR}/README.txt |
| DESTINATION "${INSTALL_PREFIX}.") |
| else (WIN32) |
| install(FILES |
| ${CMAKE_CURRENT_SOURCE_DIR}/README |
| DESTINATION "${INSTALL_PREFIX}.") |
| endif (WIN32) |
| install(FILES |
| ${CMAKE_CURRENT_SOURCE_DIR}/license.txt |
| DESTINATION "${INSTALL_PREFIX}.") |
| if (USE_DRSYMS) |
| install(TARGETS ${toolname} DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| else (USE_DRSYMS) |
| install(FILES |
| ${script_main} |
| DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| endif (USE_DRSYMS) |
| # We put "helper" files inside ${BIN_ARCH}/ so only top-level script is visible |
| if (NOT "${script_aux}" STREQUAL "") |
| install(FILES |
| ${script_aux} |
| DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| endif () |
| if (ANDROID AND TOOL_DR_MEMORY) |
| install(FILES |
| "${PROJECT_BINARY_DIR}/${BUILD_BIN}/${toolname}" |
| DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| endif () |
| |
| if (TOOL_DR_MEMORY) |
| install(FILES |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/suppress-default.txt |
| DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} GROUP_READ WORLD_READ) |
| if (UNIX) |
| install(FILES |
| ${PROJECT_BINARY_DIR}/${BUILD_BIN}/valgrind2drmemory.pl |
| DESTINATION "${INSTALL_PREFIX}bin" |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE) |
| endif (UNIX) |
| endif (TOOL_DR_MEMORY) |
| |
| set(install_pdb_exclude |
| # We don't want unit test pdb's, or internal tool pdb's. |
| # XXX: it would be better to exclude these in the subdirs that own them, |
| # which will be much easier once cmake supports auto-installing pdb's. |
| PATTERN verinfo.pdb EXCLUDE |
| PATTERN unit_tests.pdb EXCLUDE |
| # symfetch is a fake dll so don't imply it's more by supplying a pdb. |
| PATTERN symfetch.pdb EXCLUDE |
| PATTERN drstrace_unit_tests.pdb EXCLUDE) |
| if (X64) |
| install(CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${INSTALL_BIN}/README.txt\" \"Dr. Memory has preliminary 64-bit support that does not yet include detecting uninitialized reads. The drstrace tool and the Dr. Syscall and Umbra libraries are fully supported for 64-bit.\n\")") |
| endif (X64) |
| install(DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/ |
| DESTINATION "${INSTALL_LIB}" |
| FILE_PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE |
| FILES_MATCHING |
| PATTERN "*.debug" |
| PATTERN "*.pdb" |
| REGEX ".*.dSYM/.*DWARF/.*" # too painful to get right # of backslash for literal . |
| ${install_pdb_exclude} |
| ) |
| |
| install(DIRECTORY ${PROJECT_BINARY_DIR}/${BUILD_BIN}/ |
| DESTINATION "${INSTALL_BIN}" |
| FILE_PERMISSIONS ${owner_access} OWNER_EXECUTE |
| GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE |
| FILES_MATCHING |
| PATTERN "*.debug" |
| PATTERN "*.pdb" |
| REGEX ".*.dSYM/.*DWARF/.*" # too painful to get right # of backslash for literal . |
| ${install_pdb_exclude} |
| ) |
| |
| # create empty logs dir for release package |
| # be sure to escape ",$ since evaluated at install time not configure time |
| install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${INSTALL_PREFIX}${toolname}/logs\")") |
| # CPack seems to ignore empty dirs so add a README file |
| install(CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${INSTALL_PREFIX}${toolname}/logs/README.txt\" \"Default destination for log files.\n\")") |
| # ditto for pcaches |
| install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${INSTALL_PREFIX}${toolname}/logs/codecache\")") |
| install(CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${INSTALL_PREFIX}${toolname}/logs/codecache/README.txt\" \"Default destination for code cache files.\n\")") |
| # ditto for DR logdir |
| install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${INSTALL_PREFIX}${toolname}/logs/dynamorio\")") |
| install(CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${INSTALL_PREFIX}${toolname}/logs/codecache/README.txt\" \"Default destination for DynamoRIO log files (for diagnostics only).\n\")") |
| |
| if (UNIX) |
| if (APPLE) |
| set(LIB_SFX ".dylib") |
| else (APPLE) |
| set(LIB_SFX ".so") |
| endif (APPLE) |
| endif (UNIX) |
| |
| if (BUILDING_SUB_PACKAGE) |
| # We're being included in another package (DR's). |
| # Our rpaths assumed we had a dynamorio/ subdir, but now that's the upper dir. |
| # Easier to add a symlink than to change rpaths. |
| # XXX i#1855: this symlink makes "adb push" of our tarball's contents not work, |
| # but presumably most users will untar on the Android device. |
| # Fixing would require changing the script and the frontend binary. |
| install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink .. dynamorio WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX}/${INSTALL_PREFIX})") |
| |
| # Add a docs link in the top-level docs/ dir |
| install(CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/docs/DrMemory.html\" \"<html>\n<head>\n<meta http-equiv=\\\"refresh\\\" content=\\\"0; URL=../drmemory/drmemory/docs/html/index.html\\\">\n</head><body></body>\")") |
| |
| else (BUILDING_SUB_PACKAGE) |
| # Include DR so user doesn't have to download separately (PR 457417). |
| # We don't need docs/ or include/. |
| install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}\")") |
| |
| if (UNIX) |
| # CPACK_INSTALLED_DIRECTORIES since 2.8.3 now properly preserves symlinks |
| # (http://www.itk.org/Bug/view.php?id=10096) so we can just copy the dir. |
| install(DIRECTORY ${DynamoRIO_DIR}/../${LIB_ARCH}/${build_type} |
| DESTINATION ${INSTALL_PREFIX}${DR_install_dir}/${LIB_ARCH} |
| FILE_PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE |
| PATTERN "libdrdecode*" EXCLUDE) |
| # ext dir is currently empty but we need it to avoid drrun error (i#427) |
| install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/ext/${LIB_ARCH}/${build_type}\")") |
| # CPack seems to ignore empty dirs so add a README file |
| install(CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/ext/${LIB_ARCH}/${build_type}/README.txt\" \"Currently empty.\n\")") |
| endif (UNIX) |
| |
| # can't find way to package external individual files (can do whole dir) |
| # and we don't need entire DR docs/, include/, etc. so we do these |
| # files individually |
| if (EXISTS "${DynamoRIO_SOURCE_DIR}/License.txt") |
| set(DR_LICENSE_DIR "${DynamoRIO_SOURCE_DIR}") |
| else () |
| set(DR_LICENSE_DIR "${DynamoRIO_DIR}/..") |
| endif () |
| install(CODE "configure_file(\"${DR_LICENSE_DIR}/License.txt\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/License.txt\" COPYONLY)") |
| install(CODE "configure_file(\"${DR_LICENSE_DIR}/ACKNOWLEDGEMENTS\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/ACKNOWLEDGEMENTS\" COPYONLY)") |
| # rather whan whole README, which talks about running samples, etc.: |
| install(CODE "file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/README.txt\" \"This is a copy of the parts of DynamoRIO needed to run ${toolname_cap_spc}. See http://dynamorio.org for more information.\n\")") |
| # on Windows we don't need all the ${BIN_ARCH}/ tools, and they take up space |
| install(CODE "file(MAKE_DIRECTORY \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}\")") |
| if (UNIX) |
| if (USER_SPECIFIED_DynamoRIO_DIR) # else DR installs straight there (i#1449) |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/drrun\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/drrun\" COPYONLY)") |
| endif () |
| if (NOT APPLE) # FIXME DRi#1286: no nudge support yet on MacOS |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/nudgeunix\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/nudgeunix\" COPYONLY)") |
| endif (NOT APPLE) |
| # drconfiglib and drinjectlib are now static libs so no need to install |
| else (UNIX) |
| if (TOOL_DR_HEAPSTAT OR NOT USE_DRSYMS) |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/drconfig.exe\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/drconfig.exe\" COPYONLY)") |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/drinject.exe\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/drinject.exe\" COPYONLY)") |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/drrun.exe\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/drrun.exe\" COPYONLY)") |
| endif (TOOL_DR_HEAPSTAT OR NOT USE_DRSYMS) |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/drconfiglib.dll\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/drconfiglib.dll\" COPYONLY)") |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/drinjectlib.dll\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/drinjectlib.dll\" COPYONLY)") |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/DRcontrol.exe\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/DRcontrol.exe\" COPYONLY)") |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${BIN_ARCH}/DRview.exe\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/${BIN_ARCH}/DRview.exe\" COPYONLY)") |
| endif (UNIX) |
| |
| if (TOOL_DR_MEMORY) |
| # For the new -coverage feature, we include a copy of drcov2lcov. |
| # We keep it inside the dynamorio/ subdir so its rpath will still work. |
| # XXX: a debug build of drmem pointing at an external DR will pull in a |
| # release-build drcov2lcov whose rpath will point at a release DR yet |
| # we only copy debug DR so it will fail -- we just live with this though |
| # as a full RC package will work fine. |
| if (USER_SPECIFIED_DynamoRIO_DIR) |
| set(covdir tools) |
| else () |
| set(covdir clients) |
| endif () |
| if (UNIX) |
| # We can't use get_target_property() for USER_SPECIFIED_DynamoRIO_DIR |
| set(covhelper drcov2lcov) |
| else () |
| set(covhelper drcov2lcov.exe) |
| endif () |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${covdir}/${BIN_ARCH}/${covhelper}\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/tools/${BIN_ARCH}/${covhelper}\" COPYONLY)") |
| if (WIN32) |
| install(CODE "configure_file(\"${DynamoRIO_DIR}/../${LIB_ARCH}/${build_type}/dynamorio.dll\" \"\${CMAKE_INSTALL_PREFIX}/${DR_install_dir}/tools/${BIN_ARCH}/dynamorio.dll\" COPYONLY)") |
| endif () |
| endif () |
| endif (BUILDING_SUB_PACKAGE) |
| |
| # DRMF install rules |
| install(FILES ${framework_incdir}/drmemory_framework.h DESTINATION ${DRMF_INSTALL_INC}) |
| install(FILES ${framework_dir}/DrMemoryFrameworkConfigVersion.cmake |
| ${framework_dir}/DrMemoryFrameworkConfig.cmake |
| DESTINATION ${DRMF_INSTALL}) |
| # These cover all subdirs |
| install(DIRECTORY ${framework_bindir}/ |
| DESTINATION ${DRMF_INSTALL_BIN} |
| FILE_PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE |
| WORLD_READ WORLD_EXECUTE |
| FILES_MATCHING |
| PATTERN "*.debug" |
| PATTERN "*.pdb" |
| REGEX ".*.dSYM/.*DWARF/.*" # too painful to get right # of backslash for literal . |
| PATTERN "*_int.pdb" EXCLUDE |
| ) |
| |
| # We must append to this file to avoid cmake_install.cmake's diff from thinking |
| # the exports have changed and thus clobbering the other config's files. |
| install(CODE "file(APPEND \"${PROJECT_BINARY_DIR}/CMakeFiles/Export/cmake/${exported_targets_name}.cmake\" \"${exported_targets_append}\")") |
| # Create the exported targets file |
| # Note that we do not use the drmf_ NAMESPACE here: it's only needed for |
| # internal tests. |
| install(EXPORT ${exported_targets_name} DESTINATION ${DRMF_INSTALL}) |
| |
| # Check that we have version resources in all our binaries. |
| # We do this at install time once we have all binaries built, as it's a pain |
| # to individually add post-build commands. |
| if (WIN32) |
| get_target_property(verinfo_path verinfo LOCATION${location_suffix}) |
| install(CODE "include(\"${PROJECT_SOURCE_DIR}/make/rccheck.cmake\")") |
| install(CODE "check_version_resources(\"${PROJECT_BINARY_DIR}\" \"${verinfo_path}\")") |
| endif () |
| |
| ########################################################################### |
| # packaging |
| |
| # "make package package_source" |
| |
| if (USER_SPECIFIED_DynamoRIO_DIR) |
| set(favicon_path "${DynamoRIO_DIR}/../docs/html/favicon.ico") |
| else (USER_SPECIFIED_DynamoRIO_DIR) |
| set(favicon_path "${DynamoRIO_SOURCE_DIR}/api/docs/images/favicon.ico") |
| endif (USER_SPECIFIED_DynamoRIO_DIR) |
| |
| if (UNIX) |
| # not bothering with TZ or TBZ2 or STGZ (.sh) |
| set(CPACK_GENERATOR "TGZ") |
| set(CPACK_SOURCE_GENERATOR "TGZ") |
| # We've already split out our separate .debug files and stripped the |
| # originals in our build rules |
| set(CPACK_STRIP_FILES OFF) |
| if (VMKERNEL) |
| set(CPACK_SYSTEM_NAME "ESXi") |
| else (VMKERNEL) |
| if (APPLE) |
| set(CPACK_SYSTEM_NAME "MacOS") |
| else (APPLE) |
| set(CPACK_SYSTEM_NAME "Linux") |
| endif (APPLE) |
| endif (VMKERNEL) |
| else (UNIX) |
| # We don't require NSIS or WIX since we do "make package" as part of test suite |
| set(WIX "WIX-NOTFOUND") |
| set(NSIS "NSIS-NOTFOUND") |
| # Our WIX config requires recent features |
| if ("${CMAKE_VERSION}" VERSION_EQUAL "3.3" OR |
| "${CMAKE_VERSION}" VERSION_GREATER "3.3") |
| # WIX's candle.exe must be on the path for cpack to run it, so hints don't help |
| find_program(WIX candle DOC "WIX for creating installer") |
| endif () |
| # Prefer WIX |
| if (NOT WIX) |
| find_program(NSIS nsis HINT "$ENV{PROGRAMFILES}/NSIS" DOC |
| "NSIS for creating installer") |
| endif () |
| if (NSIS) |
| message(STATUS "NSIS found: will build NSIS-based installer") |
| set(CPACK_GENERATOR "ZIP;NSIS") |
| # Ensure we have the NSIS with an 8192 PATH limit (i#1029) |
| get_filename_component(nsis_path "${NSIS}" PATH) |
| if (NOT EXISTS "${nsis_path}/makensis.exe") |
| message(FATAL_ERROR "NSIS check needs to be updated") |
| endif () |
| # we may have already run find_program on strings up above |
| if (NOT strings) |
| find_program(strings strings) |
| endif () |
| if (strings) |
| execute_process(COMMAND ${strings} "${nsis_path}/makensis.exe" |
| RESULT_VARIABLE strings_result |
| ERROR_QUIET |
| OUTPUT_VARIABLE strings_out) |
| if (strings_result) |
| message(FATAL_ERROR "*** ${strings} failed to run ***\n") |
| endif (strings_result) |
| # The default has "NSIS_MAX_STRLEN\n1024": make sure we have 8192. |
| string(REGEX MATCH "NSIS_MAX_STRLEN\n8192" big_limit "${strings_out}") |
| if (big_limit) |
| message(STATUS "NSIS has larger 8192 path limit") |
| else () |
| message(FATAL_ERROR "Installed NSIS has a too-small path limit. See i#1029.") |
| endif () |
| endif (strings) |
| elseif (WIX) |
| message(STATUS "WIX found: will build WIX-based .msi installer") |
| # Make sure to specify BUILDING_PACKAGE. See i#1099 about absolute path. |
| set(CPACK_GENERATOR "ZIP;WIX") |
| # Variables below are set to allow for upgrade but prevent |
| # reinstalling the same version. See i#1620. |
| set(CPACK_WIX_UPGRADE_GUID 1A8D7CEE-2ABA-4462-B0D6-86F26715128E) |
| set(CPACK_WIX_PRODUCT_GUID 67675AD6-1FB0-4DE1-9ECF-84997515025E) |
| set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/make/WIX.patches.in") |
| set(CPACK_WIX_EXTRA_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/make/WIX.extra.in") |
| # This is required for the util:InternetShortcut in WIX.extra.in |
| set(CPACK_WIX_EXTENSIONS "WiXUtilExtension") |
| # This should show up in Add/Remove Programs: |
| set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "http://drmemory.org") |
| set(CPACK_WIX_PRODUCT_ICON "${favicon_path}") |
| else () |
| message(STATUS "Neither NSIS nor WIX found (please install and add to path if desired). Creating only a zip package.") |
| set(CPACK_GENERATOR "ZIP") |
| endif () |
| set(CPACK_SOURCE_GENERATOR "ZIP") |
| set(CPACK_SYSTEM_NAME "Windows") |
| if (USE_DRSYMS) |
| set(CPACK_SYSTEM_NAME "Windows") |
| else (USE_DRSYMS) |
| set(CPACK_SYSTEM_NAME "Cygwin") |
| endif (USE_DRSYMS) |
| endif (UNIX) |
| |
| set(CPACK_PACKAGE_NAME "${toolname_cap_spc}") |
| set(CPACK_PACKAGE_VENDOR "Google") |
| set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README") |
| set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${toolname_cap_spc} Memory Debugging Tool") |
| set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/license.txt") |
| set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README") |
| |
| set(CPACK_SOURCE_IGNORE_FILES "~$" "/.svn" "/.git") |
| |
| set(CPACK_PACKAGE_VERSION "${TOOL_VERSION_NUMBER}") |
| string(REGEX REPLACE |
| "^([0-9]+)\\..*" "\\1" CPACK_PACKAGE_VERSION_MAJOR "${TOOL_VERSION_NUMBER}") |
| string(REGEX REPLACE |
| "^[0-9]+\\.([0-9]+)\\..*" "\\1" CPACK_PACKAGE_VERSION_MINOR "${TOOL_VERSION_NUMBER}") |
| string(REGEX REPLACE |
| "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" CPACK_PACKAGE_VERSION_PATCH "${TOOL_VERSION_NUMBER}") |
| |
| if (WIN32 AND NOT BUILDING_SUB_PACKAGE) |
| # Include DR so user doesn't have to download separately (PR 457417). |
| # For Unix we do this file-by-file above b/c here we'd get duplicate |
| # files due to cpack not preserving symlinks (filed as |
| # http://www.itk.org/Bug/view.php?id=10096) |
| # We don't need docs/, include/, or 64-bit. |
| # We do include the debug lib (and default DR log dir) for |
| # debugging in the field: it does take space but we'd probably regret |
| # not supplying it. |
| if (NOT USER_SPECIFIED_DynamoRIO_DIR) |
| # install to drmemory exports dir |
| install(DIRECTORY "${DynamoRIO_DIR}/../${LIB_ARCH}" |
| DESTINATION "${DR_install_dir}") |
| # we don't need ext/ at all b/c we use static libs |
| else (NOT USER_SPECIFIED_DynamoRIO_DIR) |
| # don't take time and space copying: user can pass same dr to frontend, |
| # so we only copy for package target |
| if (DEBUG_BUILD) |
| set(CPACK_INSTALLED_DIRECTORIES |
| "${DynamoRIO_DIR}/../${LIB_ARCH};${DR_install_dir}/${LIB_ARCH}" |
| "${DynamoRIO_DIR}/../ext/${LIB_ARCH};${DR_install_dir}/ext/${LIB_ARCH}") |
| else (DEBUG_BUILD) |
| set(CPACK_INSTALLED_DIRECTORIES |
| "${DynamoRIO_DIR}/../${LIB_ARCH}/release;${DR_install_dir}/${LIB_ARCH}/release" |
| "${DynamoRIO_DIR}/../ext/${LIB_ARCH}/release;${DR_install_dir}/ext/${LIB_ARCH}/release") |
| endif (DEBUG_BUILD) |
| endif (NOT USER_SPECIFIED_DynamoRIO_DIR) |
| endif (WIN32 AND NOT BUILDING_SUB_PACKAGE) |
| |
| # CPack tarballs do not allow setting a different name for the base |
| # directory and the file: I tried a ton of CPack variables for "install |
| # dir" and looked at the source code. Most of the variables are for the |
| # other installers (rpm, nsis). I can hack it via |
| # CPACK_TEMPORARY_PACKAGE_FILE_NAME if I hardcode the exentsion: but maybe |
| # having the full version in the base dir is a good thing, though I'm not |
| # sure about the caps. |
| set(CPACK_PACKAGE_FILE_NAME |
| "${toolname_cap}-${CPACK_SYSTEM_NAME}-${CPACK_PACKAGE_VERSION}-${TOOL_BUILD_NUMBER}") |
| set(CPACK_SOURCE_PACKAGE_FILE_NAME |
| "${toolname_cap}-${CPACK_PACKAGE_VERSION}-${TOOL_BUILD_NUMBER}-Source") |
| |
| # NSIS settings |
| set(CPACK_PACKAGE_INSTALL_DIRECTORY "${toolname_cap_spc}") |
| set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${toolname_cap_spc}") |
| set(CPACK_PACKAGE_RELOCATABLE "true") |
| set(CPACK_NSIS_MODIFY_PATH ON) |
| if (PERL_TO_EXE OR WIN32 AND USE_DRSYMS AND TOOL_DR_MEMORY) |
| # CMake hardcodes bin/ for desktop links (CMake bug #7828) so |
| # we rearranged our dirs since we really need one. |
| set(CPACK_PACKAGE_EXECUTABLES "${toolname}" "${toolname_cap_spc} (drag your app here)") |
| set(CPACK_CREATE_DESKTOP_LINKS "${toolname}") |
| endif (PERL_TO_EXE OR WIN32 AND USE_DRSYMS AND TOOL_DR_MEMORY) |
| set(CPACK_NSIS_MENU_LINKS |
| # We automatically get an entry for ${toolname}.exe since it's in the |
| # CPACK_PACKAGE_EXECUTABLES list, even though we don't want one. |
| "bin/" "Explore ${toolname_cap_spc} (drag your app onto ${toolname}.exe)" |
| "${toolname}/docs/html/index.html" "${toolname_cap_spc} documentation" |
| "http://drmemory.org/" "${toolname_cap_spc} web page") |
| set(CPACK_NSIS_MUI_ICON "${favicon_path}") |
| # XXX: CPACK_PACKAGE_ICON: need a .bmp |
| |
| # i#1009c#4: auto-register Dr. Memory as a Visual Studio External Tool |
| if (WIN32) |
| install(TARGETS vs_external_tool DESTINATION "${INSTALL_BIN}" |
| PERMISSIONS ${owner_access} |
| OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) |
| set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\bin\\\\vs_external_tool.exe\\\" \\\"$INSTDIR\\\\bin\\\\drmemory.exe'") |
| set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "ExecWait '\\\"$INSTDIR\\\\bin\\\\vs_external_tool.exe\\\" -uninstall'") |
| endif (WIN32) |
| |
| # Let external build file override all settings, but before CPack reads them |
| set(AUX_MAKEFILE "" CACHE FILEPATH "Path to an auxiliary CMakeLists.txt file.") |
| if (AUX_MAKEFILE) |
| include("${AUX_MAKEFILE}") |
| endif (AUX_MAKEFILE) |
| |
| include(CPack) |