| # ********************************************************** |
| # Copyright (c) 2010-2014 Google, Inc. All rights reserved. |
| # Copyright (c) 2009-2010 VMware, Inc. All rights reserved. |
| # ********************************************************** |
| |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are met: |
| # |
| # * Redistributions of source code must retain the above copyright notice, |
| # this list of conditions and the following disclaimer. |
| # |
| # * Redistributions in binary form must reproduce the above copyright notice, |
| # this list of conditions and the following disclaimer in the documentation |
| # and/or other materials provided with the distribution. |
| # |
| # * Neither the name of VMware, Inc. nor the names of its contributors may be |
| # used to endorse or promote products derived from this software without |
| # specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| # ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE |
| # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| # DAMAGE. |
| |
| include(../make/policies.cmake NO_POLICY_SCOPE) |
| |
| ########################################################################### |
| # sources and targets |
| |
| # we have no exe's here, and we want our dll's in the lib dir |
| # (could use MODULE instead of SHARED if it would let us link) |
| set(EXECUTABLE_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") |
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") |
| set_per_config_ouput_to_match_single_config() |
| |
| set(asm_deps |
| "${PROJECT_SOURCE_DIR}/core/arch/asm_defines.asm" |
| "${PROJECT_BINARY_DIR}/configure.h") |
| add_asm_target(arch/${ARCH_NAME}/${ARCH_NAME}.asm arch_core_asm_src arch_core_asm_tgt |
| "_core" "" "${asm_deps}") |
| add_asm_target(arch/asm_shared.asm shared_core_asm_src shared_core_asm_tgt |
| "_core" "" "${asm_deps}") |
| set(arch_core_asm_src ${arch_core_asm_src} ${shared_core_asm_src}) |
| set(arch_core_asm_tgt ${arch_core_asm_tgt} ${shared_core_asm_tgt}) |
| add_asm_target(arch/${ARCH_NAME}/${ARCH_NAME}.asm arch_noncore_asm_src arch_noncore_asm_tgt |
| "_noncore" "-DNOT_DYNAMORIO_CORE_PROPER" "${asm_deps}") |
| add_asm_target(arch/asm_shared.asm shared_noncore_asm_src shared_noncore_asm_tgt |
| "_noncore" "-DNOT_DYNAMORIO_CORE_PROPER" "${asm_deps}") |
| set(arch_noncore_asm_src ${arch_noncore_asm_src} ${shared_noncore_asm_src}) |
| set(arch_noncore_asm_tgt ${arch_noncore_asm_tgt} ${shared_noncore_asm_tgt}) |
| add_asm_target(arch/pre_inject_asm.asm preinject_asm_src preinject_asm_tgt "" |
| "-DNOT_DYNAMORIO_CORE_PROPER" "${asm_deps}") |
| |
| set(CORE_SRCS |
| options.c |
| dynamo.c |
| fragment.c |
| fcache.c |
| link.c |
| dispatch.c |
| emit.c |
| utils.c |
| config.c |
| stats.c |
| heap.c |
| monitor.c |
| perfctr.c |
| vmareas.c |
| rct.c |
| hotpatch.c |
| hashtable.c |
| module_list.c |
| moduledb.c |
| perscache.c |
| nudge.c |
| synch.c |
| buildmark.c |
| loader_shared.c |
| io.c |
| native_exec.c |
| lib/instrument.c |
| translate.c |
| annotations.c |
| ) |
| |
| if (UNIX) |
| # i#46: Private string routines for libc independence. On Windows our |
| # bootstrapping loader finds these imports in ntdll. If that becomes |
| # problematic, we can find a way to compile this on Windows. |
| set (CORE_SRCS ${CORE_SRCS} string.c) |
| endif (UNIX) |
| |
| if (WIN32 AND NOT X64) |
| # PR 219380: to avoid __ftol2_sse from libc |
| # FIXME: There is no supported way to suppress a "command line" warning |
| # used to do: |
| # $(BUILD)/io.obj: FILTER_CC = 2>&1 | $(GREP) -v "D9035 : option 'QIfist'"; |
| # we just live with it for now: |
| # [ 20%] Building C object core/CMakeFiles/dynamorio.dir/io.c.obj |
| # cl : Command line warning D9035 : option 'QIfist' has been deprecated and will be removed in a future release |
| # Note that /QIfist causes casts to round instead of truncating (i#763) |
| # which we work around in our code. |
| set_source_files_properties(io.c COMPILE_FLAGS "/QIfist") |
| set_source_files_properties(utils.c COMPILE_FLAGS "/QIfist") |
| endif (WIN32 AND NOT X64) |
| |
| set(DECODER_SRCS |
| arch/opnd_shared.c |
| arch/${ARCH_NAME}/opnd.c |
| arch/instr_shared.c |
| arch/${ARCH_NAME}/instr.c |
| arch/instrlist.c |
| arch/decode_shared.c |
| arch/${ARCH_NAME}/decode.c |
| arch/encode_shared.c |
| arch/${ARCH_NAME}/encode.c |
| arch/disassemble_shared.c |
| arch/${ARCH_NAME}/disassemble.c |
| ) |
| if (X86) |
| set(DECODER_SRCS ${DECODER_SRCS} |
| arch/${ARCH_NAME}/decode_table.c |
| arch/${ARCH_NAME}/decode_fast.c) |
| else () |
| set(DECODER_SRCS ${DECODER_SRCS} |
| arch/${ARCH_NAME}/table_a32_pred.c |
| arch/${ARCH_NAME}/table_a32_unpred.c |
| arch/${ARCH_NAME}/table_a32_encode.c) |
| endif () |
| |
| set(ARCH_SRCS |
| arch/arch.c |
| arch/emit_utils_shared.c |
| arch/${ARCH_NAME}/emit_utils.c |
| ${DECODER_SRCS} |
| arch/interp.c |
| arch/proc.c |
| arch/mangle_shared.c |
| arch/${ARCH_NAME}/mangle.c |
| arch/${ARCH_NAME}/clean_call_opt.c |
| arch/steal_reg.c |
| arch/x86_code.c |
| ${arch_core_asm_src} |
| arch/${ARCH_NAME}/optimize.c |
| arch/sideline.c |
| arch/retcheck.c |
| ) |
| |
| if (X64) |
| set(ARCH_SRCS ${ARCH_SRCS} arch/${ARCH_NAME}/x86_to_x64.c) |
| endif (X64) |
| |
| # These custom commands are per-subdir so can't just place at top level |
| include(../make/CMake_events.cmake) |
| include(../make/ntdll_imports.cmake) |
| |
| # i#801: For generated headers, we need to use add_dependencies to ensure that |
| # they are generated before compiling the other sources. Listing the header as |
| # a source in the target isn't enough because it's really the source files |
| # themselves that need the header. We can't put this in CMake_events.cmake b/c |
| # we end up w/ duplicate targets then. Note that libutil/ uses these same |
| # targets but core is always enabled. |
| add_custom_target(generate_syslog DEPENDS "${SYSLOG_SRCS}") |
| if (WIN32) |
| add_custom_target(generate_events DEPENDS "${EVENTS_SRCS}") |
| endif (WIN32) |
| function (add_gen_events_deps target) |
| add_dependencies(${target} generate_syslog) |
| if (WIN32) |
| add_dependencies(${target} generate_events) |
| endif () |
| endfunction (add_gen_events_deps) |
| |
| # Just like i#801, we can't put custom targets in ntdll_imports.cmake |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # for correct parallel builds we need a target to avoid |
| # duplicate and racy VS per-project rules |
| add_custom_target(ntimp_tgt DEPENDS "${ntimp_lib}") |
| endif () |
| |
| if (UNIX) |
| set(OSNAME unix) |
| set(OS_SRCS |
| unix/os.c |
| unix/signal.c |
| unix/module.c |
| unix/pcprofile.c |
| unix/stackdump.c |
| unix/diagnost.c |
| unix/loader.c |
| ) |
| if (LINUX) |
| set(OS_SRCS ${OS_SRCS} unix/memquery_linux.c) |
| set(OS_SRCS ${OS_SRCS} unix/memquery.c) |
| set(OS_SRCS ${OS_SRCS} unix/memcache.c) |
| set(OS_SRCS ${OS_SRCS} unix/module_elf.c) |
| set(OS_SRCS ${OS_SRCS} unix/ksynch_linux.c) |
| set(OS_SRCS ${OS_SRCS} unix/tls_linux_${ARCH_NAME}.c) |
| set(OS_SRCS ${OS_SRCS} unix/signal_linux.c) |
| set(OS_SRCS ${OS_SRCS} unix/signal_linux_${ARCH_NAME}.c) |
| set(OS_SRCS ${OS_SRCS} unix/native_elf.c) |
| # XXX i#1286: should be split into nudge_linux.c and nudge_macos.c |
| set(OS_SRCS ${OS_SRCS} unix/nudgesig.c) |
| elseif (APPLE) |
| set(OS_SRCS ${OS_SRCS} unix/memquery_macos.c) |
| set(OS_SRCS ${OS_SRCS} unix/memquery.c) |
| set(OS_SRCS ${OS_SRCS} unix/module_macho.c) |
| set(OS_SRCS ${OS_SRCS} unix/ksynch_macos.c) |
| set(OS_SRCS ${OS_SRCS} unix/tls_macos.c) |
| set(OS_SRCS ${OS_SRCS} unix/signal_macos.c) |
| set(OS_SRCS ${OS_SRCS} unix/native_macho.c) |
| # XXX i#1286: implement nudge_macos.c |
| elseif (VMKERNEL) |
| set(VMKUW_DIR ${PROJECT_SOURCE_DIR}/../internal/core/linux) |
| include_directories(${VMKUW_DIR}) |
| set(OS_SRCS ${OS_SRCS} ${VMKUW_DIR}/vmkuw.c) |
| set(OS_SRCS ${OS_SRCS} unix/memquery_emulate.c) |
| set(OS_SRCS ${OS_SRCS} unix/memcache.c) |
| set(OS_SRCS ${OS_SRCS} unix/module_elf.c) |
| set(OS_SRCS ${OS_SRCS} unix/ksynch_linux.c) |
| set(OS_SRCS ${OS_SRCS} unix/signal_linux.c) |
| endif () |
| set(PRELOAD_NAME drpreload) |
| set(PRELOAD_SRCS |
| unix/preload.c |
| config.c |
| unix/os.c |
| ${arch_noncore_asm_src} |
| # i#1334: private string routines for libc independence |
| string.c |
| io.c |
| ) |
| set(INJECTOR_SRCS |
| unix/injector.c |
| config.c # to read config |
| unix/os.c # for file_t interface |
| string.c |
| io.c |
| ${arch_noncore_asm_src} # for dynamorio_syscall |
| ) |
| if (APPLE) |
| set(INJECTOR_SRCS ${INJECTOR_SRCS} unix/module_macho.c) |
| else (APPLE) |
| set(INJECTOR_SRCS ${INJECTOR_SRCS} unix/module_elf.c) |
| endif () |
| else (UNIX) |
| set(OSNAME win32) |
| set(OS_SRCS |
| win32/eventlog.c |
| win32/os.c |
| win32/syscall.c |
| win32/callback.c |
| win32/drmarker.c |
| win32/ntdll.c |
| win32/inject.c |
| win32/inject_shared.c |
| win32/module.c |
| win32/module_shared.c |
| win32/native_pe.c |
| win32/diagnost.c |
| win32/aslr.c |
| win32/loader.c |
| win32/drwinapi/drwinapi.c |
| win32/drwinapi/ntdll_redir.c |
| win32/drwinapi/kernel32_redir.c |
| win32/drwinapi/kernel32_proc.c |
| win32/drwinapi/kernel32_lib.c |
| win32/drwinapi/kernel32_mem.c |
| win32/drwinapi/kernel32_file.c |
| win32/drwinapi/kernel32_sync.c |
| win32/drwinapi/kernel32_misc.c |
| win32/drwinapi/rpcrt4_redir.c |
| win32/drwinapi/advapi32_redir.c |
| win32/resources.rc |
| ${ntimp_dep} |
| ) |
| set(PRELOAD_SRCS |
| win32/pre_inject.c |
| win32/ntdll.c |
| win32/inject_shared.c |
| win32/drmarker.c |
| ${arch_noncore_asm_src} |
| ${preinject_asm_src} |
| win32/module_shared.c |
| win32/resources.rc |
| config.c |
| win32/os.c |
| io.c |
| ) |
| set(PRELOAD_NAME drpreinject) |
| set(INJECTOR_SRCS |
| win32/injector.c |
| win32/inject.c |
| win32/ntdll.c |
| win32/inject_shared.c |
| win32/module_shared.c |
| ${arch_noncore_asm_src} |
| win32/resources.rc |
| config.c |
| win32/os.c |
| io.c |
| ${ntimp_dep} |
| ) |
| |
| add_library(drearlyhelp1 SHARED |
| win32/early_inject_helper1.c |
| win32/resources.rc |
| ) |
| add_library(drearlyhelp2 SHARED |
| win32/early_inject_helper2.c |
| win32/resources.rc |
| ) |
| endif (UNIX) |
| |
| add_library(dynamorio ${SHARED_OR_STATIC} |
| ${CORE_SRCS} ${ARCH_SRCS} ${OS_SRCS} |
| # FIXME: any other way to add a dependence? this is for export_list, |
| # where the PRE_LINK custom command doesn't support DEPENDS. |
| # Apparently just files w/ certain extensions are pulled out of here |
| # for automatic rules. |
| ${CMAKE_CURRENT_SOURCE_DIR}/lib/genapi.pl |
| # ditto: adding here for dependence |
| ${CMAKE_CURRENT_SOURCE_DIR}/CMake_ldscript.cmake |
| ) |
| set_target_properties(dynamorio PROPERTIES |
| LIBRARY_OUTPUT_DIRECTORY${location_suffix} "${DR_LIBRARY_OUTPUT_DIRECTORY}" |
| RUNTIME_OUTPUT_DIRECTORY${location_suffix} "${DR_LIBRARY_OUTPUT_DIRECTORY}" |
| ARCHIVE_OUTPUT_DIRECTORY${location_suffix} "${DR_LIBRARY_OUTPUT_DIRECTORY}") |
| add_gen_events_deps(dynamorio) |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # for parallel build correctness we need a target dependence |
| add_dependencies(dynamorio ${arch_core_asm_tgt} ntimp_tgt) |
| endif () |
| |
| if (UNIX) |
| # We always use a script for our own library bounds (PR 361594). |
| # We could build this at configure time instead of build time as |
| # it does not depend on the source files. |
| # FIXME: this is duplicated in DynamoRIOConfig.cmake |
| set(ld_script ${CMAKE_CURRENT_BINARY_DIR}/ldscript) |
| set_directory_properties(PROPERTIES |
| ADDITIONAL_MAKE_CLEAN_FILES "${ld_script}") |
| |
| function (set_preferred_base_start_and_end target) |
| if (APPLE) |
| set(ldflags "-image_base ${preferred_base}") |
| elseif (NOT LINKER_IS_GNU_GOLD) |
| set(ldflags "-Wl,${ld_script_option},\"${ld_script}\"") |
| add_custom_command(TARGET ${target} |
| PRE_LINK |
| COMMAND ${CMAKE_COMMAND} |
| # script does not inherit any vars so we must pass them all in |
| # to work around i#84 be sure to put a space after -D for 1st arg at least |
| ARGS -D outfile=${ld_script} |
| -DCMAKE_LINKER=${CMAKE_LINKER} |
| -DCMAKE_COMPILER_IS_GNUCC=${CMAKE_COMPILER_IS_GNUCC} |
| -DLD_FLAGS=${LD_FLAGS} |
| -Dset_preferred=${SET_PREFERRED_BASE} |
| -Dreplace_maxpagesize=${REPLACE_MAXPAGESIZE} |
| -Dpreferred_base=${preferred_base} |
| -P ${PROJECT_SOURCE_DIR}/core/CMake_ldscript.cmake |
| VERBATIM # recommended: p260 |
| ) |
| else () |
| set(ldflags "") |
| if (SET_PREFERRED_BASE) |
| # FIXME: This should be -Ttext-segment for bfd, but most golds want -Ttext. |
| # See http://sourceware.org/ml/binutils/2013-02/msg00194.html |
| set(ldflags "-Wl,-Ttext=${preferred_base}") |
| endif () |
| # Add our start and end symbols for library bounds. |
| set(ldflags "${ldflags} -Wl,--defsym,dynamorio_so_start=__executable_start") |
| set(ldflags "${ldflags} -Wl,--defsym,dynamorio_so_end=end") |
| endif () |
| append_property_string(TARGET ${target} LINK_FLAGS "${ldflags}") |
| endfunction (set_preferred_base_start_and_end) |
| |
| endif (UNIX) |
| |
| # rather than a separate BUILD_INCLUDES option we always build |
| # include headers if building core (or if building docs or samples as |
| # they have real dependencies) |
| if (CLIENT_INTERFACE OR APP_EXPORTS) |
| add_dependencies(dynamorio api_headers) |
| endif () |
| |
| add_library(${PRELOAD_NAME} SHARED ${PRELOAD_SRCS}) |
| # We do not issue: |
| # target_link_libraries(${PRELOAD_NAME} dynamorio) |
| # b/c preload dynamically loads dynamorio by name and does not have a |
| # static dependence. Plus, by having a static dependence we hit issues |
| # like PR 258636. We also don't set rpath b/c that only applies to executables. |
| if (UNIX) |
| # we keep in {debug,release} subdir |
| set(preload_dest "${DR_LIBRARY_OUTPUT_DIRECTORY}") |
| else (UNIX) |
| # we keep in lib{32,64} base dir |
| set(preload_dest "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") |
| endif (UNIX) |
| set_target_properties(${PRELOAD_NAME} PROPERTIES |
| LIBRARY_OUTPUT_DIRECTORY${location_suffix} "${preload_dest}" |
| RUNTIME_OUTPUT_DIRECTORY${location_suffix} "${preload_dest}" |
| ARCHIVE_OUTPUT_DIRECTORY${location_suffix} "${preload_dest}") |
| add_gen_events_deps(${PRELOAD_NAME}) |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| add_dependencies(${PRELOAD_NAME} ${arch_noncore_asm_tgt} ${preinject_asm_tgt}) |
| endif () |
| |
| # static decoding library |
| add_library(drdecode |
| ${DECODER_SRCS} |
| arch/${ARCH_NAME}/mangle.c |
| arch/decodelib.c |
| ${arch_noncore_asm_src} |
| ) |
| set_target_properties(drdecode PROPERTIES |
| COMPILE_FLAGS "-DNOT_DYNAMORIO_CORE_PROPER -DSTANDALONE_DECODER") |
| if (UNIX) |
| append_property_string(TARGET drdecode COMPILE_FLAGS "-fPIC") |
| endif (UNIX) |
| if (WIN32 AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # for parallel build correctness we need a target dependence |
| add_dependencies(drdecode ${arch_noncore_asm_tgt}) |
| endif () |
| add_gen_events_deps(drdecode) |
| |
| ########################################################################### |
| # linux build customization |
| |
| if (UNIX) |
| # FIXME case 69/1891: -z initfirst = initialize first at runtime (before libc) |
| set_target_properties(${PRELOAD_NAME} PROPERTIES |
| LINK_FLAGS "-nostartfiles") |
| |
| set(dynamorio_link_flags "") |
| |
| # Do non-lazy runtime binding |
| if (APPLE) |
| set(dynamorio_link_flags "${dynamorio_link_flags} -Xlinker -bind_at_load") |
| else (APPLE) |
| set(dynamorio_link_flags "${dynamorio_link_flags} -Xlinker -z -Xlinker now") |
| endif (APPLE) |
| |
| if (APPLE AND NOT X64) |
| # XXX i#1322: get the asm code PIC. Until then we have to suppress the |
| # error from ld about text relocs. |
| set(dynamorio_link_flags "-read_only_relocs suppress") |
| endif () |
| |
| # Bind global symbols internally to avoid interposing |
| if (APPLE) |
| # Looks like -interposable is off by default |
| else (APPLE) |
| set(dynamorio_link_flags "${dynamorio_link_flags} -Xlinker -Bsymbolic") |
| endif (APPLE) |
| |
| set(dynamorio_link_flags "${dynamorio_link_flags} -nostdlib") |
| |
| if (STATIC_LIBRARY) |
| # We build static DR as PIC in case we're linked into a .so or a PIE. |
| append_property_string(TARGET dynamorio COMPILE_FLAGS "-fPIC") |
| else () |
| # i#47: set the ELF header entry point to _start for early injection. |
| if (APPLE) |
| set(dynamorio_link_flags "${dynamorio_link_flags} -Wl,-e,_start") |
| else (APPLE) |
| set(dynamorio_link_flags "${dynamorio_link_flags} -Wl,--entry,_start") |
| endif (APPLE) |
| endif () |
| |
| if (NOT HAVE_FVISIBILITY) |
| set(export_list ${CMAKE_CURRENT_BINARY_DIR}/exportlist) |
| add_custom_command(TARGET dynamorio |
| PRE_LINK |
| COMMAND ${PERL_EXECUTABLE} |
| ARGS ${CMAKE_CURRENT_SOURCE_DIR}/lib/genapi.pl |
| # we assume ">" will work in all supported shells |
| -filter "${defines}" > ${export_list} |
| WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |
| VERBATIM # recommended: p260 |
| ) |
| set(dynamorio_link_flags |
| "${dynamorio_link_flags} -Xlinker --version-script -Xlinker ${export_list}") |
| endif (NOT HAVE_FVISIBILITY) |
| |
| if (APPLE) |
| # Needs explicit -init (regardless of name: _init, init, etc.) |
| set(dynamorio_link_flags "${dynamorio_link_flags} -init __init") |
| endif (APPLE) |
| |
| set_target_properties(dynamorio PROPERTIES |
| LINK_FLAGS "${dynamorio_link_flags}" |
| # See i#1375 comments |
| INSTALL_NAME_DIR "@rpath") |
| |
| # This appends to LINK_FLAGS, so do it after we set them above. |
| set_preferred_base_start_and_end(dynamorio) |
| # i#46: We're pretty libc independent these days, but we still support |
| # -no_private_loader when loaded by the system loader. We also have a sqrt |
| # import that we should cut. |
| target_link_libraries(dynamorio dl m) |
| |
| # We need to do extra work to hide symbols in the static library build. |
| # First we do a partial link with ld -r, which makes a single libdynamorio.o |
| # object file. Then we use objcopy --localize-hidden to hide all |
| # non-exported symbols. |
| if (STATIC_LIBRARY) |
| if (NOT EXISTS ${CMAKE_OBJCOPY}) |
| message(FATAL_ERROR "STATIC_LIBRARY requires objcopy") |
| endif () |
| get_target_property(dynamorio_dot_a dynamorio LOCATION) |
| string(REGEX REPLACE "\\.a$" ".o" dynamorio_dot_o "${dynamorio_dot_a}") |
| string(REPLACE " " ";" partial_link_flags "${CMAKE_C_FLAGS}") # Get -m32/64 |
| set (globalize_pic_thunks) |
| if (NOT X64) |
| # Localizing PIC thunks on ia32 creates references to discarded sections. |
| # XXX: Hardcoding this list of symbols is fragile. It is known to work |
| # with gcc 4.4 and 4.6. gcc 4.7 uses symbols starting with __x86. |
| set (globalize_pic_thunks ${CMAKE_OBJCOPY} |
| --globalize-symbol=__i686.get_pc_thunk.bx |
| --globalize-symbol=__i686.get_pc_thunk.cx |
| --globalize-symbol=__x86.get_pc_thunk.bx |
| --globalize-symbol=__x86.get_pc_thunk.cx |
| "${dynamorio_dot_o}" && |
| ) |
| endif () |
| add_custom_command(TARGET dynamorio POST_BUILD |
| COMMAND |
| ${CMAKE_C_COMPILER} ${partial_link_flags} -fPIC |
| -nostartfiles -nodefaultlibs -r |
| -Wl,--whole-archive "${dynamorio_dot_a}" -Wl,--no-whole-archive |
| -o "${dynamorio_dot_o}" && |
| ${CMAKE_OBJCOPY} --localize-hidden "${dynamorio_dot_o}" && |
| ${globalize_pic_thunks} |
| rm -f "${dynamorio_dot_a}" && |
| ${CMAKE_AR} cr "${dynamorio_dot_a}" "${dynamorio_dot_o}" && |
| ${CMAKE_RANLIB} "${dynamorio_dot_a}" |
| WORKING_DIRECTORY ${DR_LIBRARY_OUTPUT_DIRECTORY} |
| VERBATIM) |
| endif () |
| |
| # We use .so versioning via symlinks. |
| # We do not version the preload lib as it does not expose an API, |
| # and drconfig is Windows-only. |
| # Our releases match our API so we use major.minor as our soversion. |
| # That allows both forward and backward compatibility, but means that |
| # we need to provide symlinks for all backward compatible versions. |
| # In the future CMake is expected to add explicit support for this. |
| |
| function (generate_soversions verstart verstop) |
| while (${verstart} LESS ${verstop}) |
| math(EXPR COMPAT_MAJOR "${verstart} / 100") |
| math(EXPR COMPAT_MINOR "${verstart} % 100") |
| get_target_property(curver_base dynamorio LOCATION) |
| get_filename_component(curver_path "${curver_base}" PATH) |
| get_filename_component(curver_base "${curver_base}" NAME) |
| get_target_property(curver_sover dynamorio SOVERSION) |
| set(curver "${curver_base}.${curver_sover}") |
| string(REGEX REPLACE "so.${VERSION_MAJOR_MINOR}" |
| "so.${COMPAT_MAJOR}.${COMPAT_MINOR}" oldver "${curver}") |
| set(COMPAT_SYMLINKS ${COMPAT_SYMLINKS} ${curver_path}/${oldver}) |
| add_custom_command(TARGET dynamorio POST_BUILD |
| COMMAND ${CMAKE_COMMAND} -E create_symlink ${curver} ${oldver} |
| WORKING_DIRECTORY ${DR_LIBRARY_OUTPUT_DIRECTORY} |
| VERBATIM) |
| math(EXPR verstart "${verstart} + 1") |
| endwhile () |
| set(COMPAT_SYMLINKS ${COMPAT_SYMLINKS} PARENT_SCOPE) |
| endfunction (generate_soversions) |
| |
| string(REGEX REPLACE |
| "^([0-9]+\\.[0-9]+).*" "\\1" VERSION_MAJOR_MINOR "${VERSION_NUMBER}") |
| if (NOT APPLE) # FIXME i#1374: versioning causing problems |
| set_target_properties(dynamorio PROPERTIES |
| VERSION "${VERSION_MAJOR_MINOR}" SOVERSION "${VERSION_MAJOR_MINOR}") |
| if (NOT STATIC_LIBRARY) |
| # We assume OLDEST_COMPATIBLE_VERSION and cur ver have the same major #. |
| # If they don't we need additional calls here. |
| generate_soversions(${OLDEST_COMPATIBLE_VERSION} ${VERSION_NUMBER_INTEGER}) |
| endif () |
| endif (NOT APPLE) |
| |
| if (LINUX) # No checks for MacOS |
| # Note that we can't locate readelf inside CMake_readelf.cmake as that |
| # would disallow pointing externally at a readelf location, so we make it |
| # a proper cache variable. |
| # Note that nothing depends on CMake_readelf.cmake: that's ok, we'll check |
| # in the next clean build if we modify the script. |
| # readelf is a binutils app just like ld |
| get_filename_component(binutils_path ${CMAKE_LINKER} PATH) |
| if (APPLE) |
| set(readelf_name "greadelf") |
| else (APPLE) |
| set(readelf_name "readelf") |
| endif (APPLE) |
| find_program(READELF_EXECUTABLE ${readelf_name} HINTS "${binutils_path}" |
| DOC "path to readelf") |
| if (STATIC_LIBRARY) |
| # Skipping readelf check for STATIC_LIBRARY. |
| elseif (NOT READELF_EXECUTABLE) |
| message("${readelf_name} not found: not checking SElinux or execstack") |
| else () |
| get_target_property(lib_to_check dynamorio LOCATION) |
| add_custom_command(TARGET dynamorio |
| POST_BUILD |
| COMMAND ${CMAKE_COMMAND} |
| # to work around i#84 be sure to put a space after -D for 1st arg at least |
| ARGS -D lib=${lib_to_check} |
| -D READELF_EXECUTABLE=${READELF_EXECUTABLE} |
| -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake_readelf.cmake |
| VERBATIM # recommended: p260 |
| ) |
| get_target_property(lib_to_check ${PRELOAD_NAME} LOCATION) |
| add_custom_command(TARGET ${PRELOAD_NAME} |
| POST_BUILD |
| COMMAND ${CMAKE_COMMAND} |
| # to work around i#84 be sure to put a space after -D for 1st arg at least |
| ARGS -D lib=${lib_to_check} |
| -D READELF_EXECUTABLE=${READELF_EXECUTABLE} |
| -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake_readelf.cmake |
| VERBATIM # recommended: p260 |
| ) |
| endif () |
| endif () |
| |
| # we used to run size on libdynamorio.so for info purposes |
| |
| set_target_properties(${PRELOAD_NAME} PROPERTIES |
| COMPILE_FLAGS "-DNOT_DYNAMORIO_CORE_PROPER -DRC_IS_PRELOAD") |
| |
| if (APPLE) |
| # Linker complains about unresolved symbols. |
| # This means we can't use preload by itself -- but these days we never do that. |
| target_link_libraries(${PRELOAD_NAME} dynamorio) |
| # Needs explicit -init (regardless of name: _init, init, etc.) |
| append_property_string(TARGET ${PRELOAD_NAME} LINK_FLAGS "-init __init") |
| endif (APPLE) |
| |
| else (UNIX) |
| ########################################################################### |
| # windows build customization |
| |
| set_target_properties(dynamorio PROPERTIES |
| # Set define parameters for resources.rc. |
| # Since it's hard to pass spaces in defines (I can get a " through using |
| # \\\\\\\" but no spaces) we put strings in resources.rc and select |
| # using RC_ defines. |
| COMPILE_DEFINITIONS "RC_IS_CORE;INCLUDE_EVENTS" |
| # i#921: we do not want a __chkstk function comparing our stack to |
| # TEB.StackLimit, esp on win8 where the stack is high, so we disable |
| # compiler-inserted stack probes globally in DR itself. |
| COMPILE_FLAGS "/Gs65536") |
| |
| if ("${CMAKE_GENERATOR}" MATCHES "Ninja" AND |
| "${CMAKE_VERSION}" VERSION_LESS "2.8.9.20120822") |
| # cmake bug http://www.cmake.org/Bug/view.php?id=13486 causes rc.exe to |
| # fail b/c it's passed COMPILE_FLAGS |
| message(FATAL_ERROR "cmake at least version 2.8.9.20120822 is required for Ninja") |
| endif () |
| |
| set(NOLIBC_DLL_ENTRY /entry:DllMain) |
| |
| # Set up .def file. Since there's only one and it does not depend on the |
| # sources we can do this at configure time and not require a separate script. |
| if (X64) |
| set(DEF_SRC lib/dr_ntdll_x64.def) |
| else (X64) |
| set(DEF_SRC lib/dr_ntdll.def) |
| endif (X64) |
| set(DEF_BLD ${CMAKE_CURRENT_BINARY_DIR}/dr_ntdll.def) |
| file(READ ${DEF_SRC} string) |
| if (NOT CLIENT_INTERFACE) |
| # we're not exporting snprintf() so remove from def file */ |
| string(REGEX REPLACE |
| " snprintf" |
| "" string "${string}") |
| endif (NOT CLIENT_INTERFACE) |
| file(WRITE ${DEF_BLD} "${string}") |
| set(FORWARD_TO_NTDLL "/def:\"${DEF_BLD}\" /ignore:4197") |
| |
| # PR 219380: we export ntdll routines from dynamorio.dll by forwarding them. |
| # However, the linker tries to be smart and thinks our _snprintf forward |
| # is the same as our own snprintf: it removes the latter and issues a warning. |
| # We re-add our own snprintf by listing it in the .def file, and we suppress |
| # the warning using the secret option "/ignore". |
| set(dynamorio_link_flags /NODEFAULTLIB) |
| if (X64) |
| # Xref PR 215395, we currently require DynamoRIO to be loaded in a certain address |
| # range. To be double sure we compile it FIXED for now. |
| set(dynamorio_link_flags "${dynamorio_link_flags} /dynamicbase:no /FIXED") |
| endif (X64) |
| if (DEBUG) |
| set(LD_FLAGS "${LINK_DBG} /release /opt:ref") |
| else (DEBUG) |
| set(LD_FLAGS "${LINK_DBG} /release /opt:ref /opt:icf") |
| endif (DEBUG) |
| # XXX i#893: VS2012 won't build any target using x86.asm w/ safeseh |
| set(LD_FLAGS "${LD_FLAGS} /safeseh:no") |
| if (SET_PREFERRED_BASE) |
| set(dynamorio_link_flags "${dynamorio_link_flags} /base:${preferred_base}") |
| endif (SET_PREFERRED_BASE) |
| if (X64) |
| set(LD_FLAGS "${LD_FLAGS} /machine:X64") |
| else (X64) |
| set(LD_FLAGS "${LD_FLAGS} /machine:I386") |
| endif (X64) |
| set(dynamorio_link_flags |
| "${LD_FLAGS} ${ntimp_flags} ${dynamorio_link_flags} /dll /incremental:no") |
| set(dynamorio_link_flags |
| "${dynamorio_link_flags} ${NOLIBC_DLL_ENTRY} ${FORWARD_TO_NTDLL}") |
| # cmake does /out, /implib, and /pdb for us, but we do want map file |
| get_target_property(drout dynamorio LOCATION${location_suffix}) |
| get_filename_component(drpath ${drout} PATH) |
| get_filename_component(drname ${drout} NAME_WE) |
| set(dynamorio_link_flags |
| "${dynamorio_link_flags} /map:\"${drpath}/${drname}.map\" /mapinfo:exports") |
| # export functions in x86.asm where we can't just say __declspec(dllexport)) |
| set(dynamorio_link_flags |
| "${dynamorio_link_flags} /export:dynamo_auto_start /export:dynamorio_app_take_over") |
| if (APP_EXPORTS) |
| set(dynamorio_link_flags |
| "${dynamorio_link_flags} /export:dr_app_start /export:dr_app_take_over") |
| set(dynamorio_link_flags |
| "${dynamorio_link_flags} /export:dr_app_running_under_dynamorio") |
| endif (APP_EXPORTS) |
| if (CLIENT_INTERFACE) |
| set(dynamorio_link_flags "${dynamorio_link_flags} /export:dr_try_start") |
| set(dynamorio_link_flags "${dynamorio_link_flags} /export:dr_call_on_clean_stack") |
| if (NOT X64) |
| set(dynamorio_link_flags "${dynamorio_link_flags} /export:dr_invoke_x64_routine") |
| endif (NOT X64) |
| endif (CLIENT_INTERFACE) |
| if (WINDOWS) |
| set(dynamorio_link_flags |
| "${dynamorio_link_flags} /export:dynamorio_earliest_init_takeover") |
| endif (WINDOWS) |
| |
| if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0) |
| # i#1376: with VS2013 we end up with an import of "_except1" from msvcr*.dll, |
| # regardless of flags like QIfist, /fp:except-, /fp:fast, or /Qfast_transcendentals. |
| # Our solution is to not link with msvcrt.lib and rely on ntdll having _aulldvrm. |
| # This means that dynamorio.dll built with VS2013 won't run on 2K or NT. |
| |
| # case 4125: we link with msvcrt.lib for vc8 /O2's use of _alldvrm |
| # note that _alldvrm is in ntdll.dll on xp+; but for pre-xp uses we |
| # stick with the static linking of the impl in msvcrt.lib. |
| # We must link in custom flags and not target_link_libraries() b/c we need |
| # to be AFTER our ntdll_imports.lib. |
| set(dynamorio_link_flags "${dynamorio_link_flags} msvcrt.lib") |
| endif () |
| |
| set_target_properties(dynamorio PROPERTIES LINK_FLAGS "${dynamorio_link_flags}") |
| |
| if (DEBUG) |
| set(WIN32_C_LIB libcmtd) |
| else (DEBUG) |
| set(WIN32_C_LIB libcmt) |
| endif (DEBUG) |
| |
| if (NOT STATIC_LIBRARY) |
| # ensure there are no dependencies other than ntdll |
| find_program(DUMPBIN_EXECUTABLE dumpbin.exe DOC "path to dumpbin.exe") |
| if (DUMPBIN_EXECUTABLE) |
| add_custom_command(TARGET dynamorio POST_BUILD |
| COMMAND ${CMAKE_COMMAND} |
| ARGS -D lib=${drout} |
| -D DUMPBIN_EXECUTABLE=${DUMPBIN_EXECUTABLE} |
| -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake_checkdeps.cmake |
| VERBATIM) |
| else () |
| message(STATUS "Cannot find dumpbin so not performing dependence check") |
| endif () |
| else () |
| # i#975: if we're building static, none of those link flags above are going |
| # to make it through. But target_link_libraries will. We name a C library |
| # here to make sure things get linked in the right order to avoid duplicate |
| # definitions. See the case 4125 msvcrt comment above about why we need a C |
| # library. |
| target_link_libraries(dynamorio ${WIN32_C_LIB} ${ntimp_lib}) |
| endif () |
| |
| |
| set_target_properties(${PRELOAD_NAME} PROPERTIES |
| COMPILE_FLAGS "-DNOT_DYNAMORIO_CORE_PROPER -DRC_IS_PRELOAD") |
| set(pre_link_flags |
| # preinjector requires no C library for its unload-self method |
| # not bothering with map files |
| "${LD_FLAGS} /dll /incremental:no /base:0x14000000 /NODEFAULTLIB ${NOLIBC_DLL_ENTRY}") |
| set_target_properties(${PRELOAD_NAME} PROPERTIES LINK_FLAGS "${pre_link_flags}") |
| # case 4125: we link with msvcrt.lib for vc8 /O2's use of _alldvrm |
| target_link_libraries(${PRELOAD_NAME} ${ntimp_lib} kernel32 msvcrt dynamorio) |
| |
| |
| set_target_properties(drearlyhelp1 PROPERTIES |
| COMPILE_FLAGS "-DRC_IS_EARLY1") |
| # base = (release base - 64k) |
| set_target_properties(drearlyhelp1 PROPERTIES |
| # not bothering with map files |
| LINK_FLAGS "${LD_FLAGS} /dll /NODEFAULTLIB /base:0x70FF0000 ${NOLIBC_DLL_ENTRY}") |
| target_link_libraries(drearlyhelp1 drearlyhelp2) |
| |
| set_target_properties(drearlyhelp2 PROPERTIES |
| COMPILE_FLAGS "-DRC_IS_EARLY2") |
| # base = (helper1 base - 64k) |
| set_target_properties(drearlyhelp2 PROPERTIES |
| # not bothering with map files |
| LINK_FLAGS "${LD_FLAGS} /dll /NODEFAULTLIB /base:0x71110000 ${NOLIBC_DLL_ENTRY}") |
| |
| endif (UNIX) |
| |
| # drinjectlib |
| add_library(drinjectlib SHARED ${INJECTOR_SRCS}) |
| add_gen_events_deps(drinjectlib) |
| target_link_libraries(drinjectlib drdecode) |
| set_target_properties(drinjectlib PROPERTIES |
| # COMPILE_DEFINITONS isn't working for me: cmake bug? |
| # Set define parameters for resources.rc |
| COMPILE_FLAGS "-DNOT_DYNAMORIO_CORE_PROPER -DRC_IS_DRINJECTLIB" |
| # XXX i#1375: if we move to cmake 2.8.12 we can use its built-in |
| # rpath: until then we add @rpath ourselves. The downside is that |
| # everyone who uses this lib has to have the rpath set and can't |
| # just copy the lib to the local dir (should we document that? |
| # DynamoRIO_RPATH is on for standalone, which covers most uses of |
| # drconfiglib and drinjectlib, the only libs we do this for). |
| INSTALL_NAME_DIR "@rpath") |
| if (WIN32) |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # for parallel build correctness we need a target dependence |
| add_dependencies(drinjectlib ${arch_noncore_asm_tgt} ntimp_tgt) |
| endif () |
| set(drinjectlib_link_flags |
| # not bothering with map files |
| "${LD_FLAGS} /incremental:no /subsystem:console /NODEFAULTLIB") |
| # If we use ${ntimp_flags} in the link flags and thus prior to the |
| # target_link_libraries() list, on VS2005 and VS2008 we end up with duplicate |
| # symbols atoi and iswctype from libcmtd and ntdll. Unlike dynamorio.dll we're |
| # ok w/ libc syms so we re-order and take the static syms first. |
| set_target_properties(drinjectlib PROPERTIES LINK_FLAGS "${drinjectlib_link_flags}") |
| # I'm adding libcmt to attempt to make sure we have multithreaded C lib: |
| target_link_libraries(drinjectlib drdecode ${WIN32_C_LIB} ${ntimp_lib} |
| kernel32 advapi32 imagehlp) |
| # drinject.exe needs a copy in the bin dir |
| add_custom_command(TARGET drinjectlib POST_BUILD COMMAND ${CMAKE_COMMAND} |
| ARGS -E copy "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/drinjectlib.dll" |
| "${EXECUTABLE_OUTPUT_DIRECTORY}/" VERBATIM) |
| endif (WIN32) |
| |
| if (ANNOTATIONS) |
| set(BUILD_ANNOTATION "${BUILD_INCLUDE}/annotations") |
| set(BUILD_ANNOTATION "${BUILD_INCLUDE}/annotations" PARENT_SCOPE) |
| file(MAKE_DIRECTORY ${BUILD_ANNOTATION}) |
| if (NOT WINDOWS OR NOT X64) |
| configure_file("${PROJECT_SOURCE_DIR}/third_party/valgrind/valgrind.h" |
| "${BUILD_ANNOTATION}/valgrind.h" COPYONLY) |
| configure_file("${PROJECT_SOURCE_DIR}/third_party/valgrind/memcheck.h" |
| "${BUILD_ANNOTATION}/memcheck.h" COPYONLY) |
| endif (NOT WINDOWS OR NOT X64) |
| configure_file("${PROJECT_SOURCE_DIR}/core/lib/dr_annotations_asm.h" |
| "${BUILD_ANNOTATION}/dr_annotations_asm.h" COPYONLY) |
| configure_file("${PROJECT_SOURCE_DIR}/core/lib/dr_annotations.h" |
| "${BUILD_ANNOTATION}/dr_annotations.h" COPYONLY) |
| configure_file("${PROJECT_SOURCE_DIR}/core/lib/dr_annotations.c" |
| "${BUILD_ANNOTATION}/dr_annotations.c" COPYONLY) |
| |
| include_directories("${BUILD_ANNOTATION}") |
| endif () |
| |
| if (BUILD_TESTS) |
| add_executable(unit_tests unit_tests.c |
| ${CORE_SRCS} ${ARCH_SRCS} ${OS_SRCS}) |
| add_gen_events_deps(unit_tests) |
| if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") |
| # for parallel build correctness we need a target dependence |
| add_dependencies(unit_tests ${arch_core_asm_tgt} ntimp_tgt) |
| endif () |
| set_target_properties(unit_tests PROPERTIES |
| COMPILE_FLAGS "-DRC_IS_TEST -DSTANDALONE_UNIT_TEST" |
| RUNTIME_OUTPUT_DIRECTORY${location_suffix} "${EXECUTABLE_OUTPUT_DIRECTORY}") |
| if (UNIX) |
| # i#1228 make sure entry point of the elf binary pointing to _start. |
| # Otherwise, the entry point will point to the start of .text section, |
| # which might not be _start. |
| append_property_string(TARGET unit_tests LINK_FLAGS "-Wl,--entry,_start") |
| target_link_libraries(unit_tests c dl m pthread) |
| set_preferred_base_start_and_end(unit_tests) |
| else (UNIX) |
| # Just like drinjectlib (see above) we need libc before ntimp_lib |
| target_link_libraries(unit_tests ${WIN32_C_LIB} ${ntimp_lib}) |
| set_target_properties(unit_tests PROPERTIES |
| LINK_FLAGS "/base:${preferred_base} ${LD_FLAGS}") |
| endif (UNIX) |
| add_test(unit_tests "${EXECUTABLE_OUTPUT_DIRECTORY}/unit_tests") |
| endif (BUILD_TESTS) |
| |
| ########################################################################### |
| |
| # Do not put core/ into the include dirs as our link.h will conflict |
| # with /usr/include/link.h! |
| include_directories(BEFORE |
| ${CMAKE_CURRENT_SOURCE_DIR}/lib |
| ${CMAKE_CURRENT_SOURCE_DIR}/arch |
| ${CMAKE_CURRENT_SOURCE_DIR}/${OSNAME} |
| ${CMAKE_CURRENT_SOURCE_DIR}/arch/${ARCH_NAME} |
| ) |
| |
| # Avoid transitive linking for imported target. |
| # This is a shared library, after all, and ntdll.lib is typically not available. |
| set_target_properties(dynamorio PROPERTIES |
| # I seem to have to set these to remove the |
| # IMPORTED_LINK_INTERFACE_LIBRARIES from the resulting .cmake file. |
| LINK_INTERFACE_LIBRARIES "" |
| LINK_INTERFACE_LIBRARIES_NOCONFIG "" |
| # Setting these isn't affecting anything but doing so anyway. |
| IMPORTED_LINK_INTERFACE_LIBRARIES "" |
| IMPORTED_LINK_INTERFACE_LIBRARIES_NOCONFIG "") |
| install_exported_target(dynamorio ${INSTALL_LIB} |
| # CMake doesn't set +x on shared libraries, so we have to ask for it. |
| PERMISSIONS ${owner_access} OWNER_EXECUTE GROUP_READ GROUP_EXECUTE) |
| DR_export_target(dynamorio) |
| install_exported_target(drinjectlib ${INSTALL_LIB_BASE}) |
| DR_export_target(drinjectlib) |
| if (UNIX) |
| DR_install(TARGETS ${PRELOAD_NAME} DESTINATION ${INSTALL_LIB}) |
| DR_install(FILES ${COMPAT_SYMLINKS} DESTINATION ${INSTALL_LIB}) |
| else (UNIX) |
| # we put drinjectlib into bin for use by our tools |
| DR_install(TARGETS drinjectlib DESTINATION ${INSTALL_BIN}) |
| DR_install(TARGETS ${PRELOAD_NAME} RUNTIME DESTINATION ${INSTALL_LIB_BASE}) |
| DR_install(TARGETS drearlyhelp1 RUNTIME DESTINATION ${INSTALL_LIB_BASE}) |
| DR_install(TARGETS drearlyhelp2 RUNTIME DESTINATION ${INSTALL_LIB_BASE}) |
| endif (UNIX) |
| |
| install_exported_target(drdecode ${INSTALL_LIB}) |
| |
| # We need separate 32-bit and 64-bit versions so we put into lib dir |
| DR_install(FILES ${ntimp_lib} DESTINATION ${INSTALL_LIB_BASE}) |