mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-26 04:09:35 +03:00
Tests: Add cases covering nm handling for WINDOWS_EXPORT_ALL_SYMBOLS
Add `__create_def` coverage for: - missing nm tools - generator selection - single- and multi-object inputs - object paths containing spaces - mixed object and definition inputs - nm symbol classification
This commit is contained in:
@@ -4,9 +4,21 @@ project(autoexport)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin)
|
||||
add_subdirectory(sub)
|
||||
|
||||
add_library(objlib OBJECT objlib.c)
|
||||
set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
add_library(autoexport SHARED hello.cxx world.cxx foo.c $<TARGET_OBJECTS:objlib>)
|
||||
|
||||
add_library(objlib_maybe_lto OBJECT objlib_maybe_lto.c)
|
||||
set_property(TARGET objlib_maybe_lto PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
# Automatic export definition generation for LTO objects is currently only
|
||||
# supported with Clang targeting the MSVC ABI.
|
||||
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set_property(TARGET objlib_maybe_lto PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
endif()
|
||||
|
||||
add_library(autoexport SHARED hello.cxx world.cxx foo.c)
|
||||
target_link_libraries(autoexport PRIVATE objlib objlib_maybe_lto)
|
||||
|
||||
add_library(autoexport3 SHARED cppCLI.cxx)
|
||||
if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600
|
||||
AND NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
|
||||
@@ -18,11 +30,16 @@ if(MSVC)
|
||||
set_target_properties(say PROPERTIES ENABLE_EXPORTS ON)
|
||||
add_library(autoexport_for_exec SHARED hello2.c)
|
||||
target_link_libraries(autoexport_for_exec say)
|
||||
if(NOT MSVC_VERSION VERSION_LESS 1600 AND
|
||||
NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
|
||||
enable_language(ASM_MASM)
|
||||
target_sources(autoexport PRIVATE nop.asm)
|
||||
set_property(SOURCE nop.asm PROPERTY COMPILE_FLAGS /safeseh)
|
||||
|
||||
if(NOT MSVC_VERSION VERSION_LESS 1600)
|
||||
if(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
|
||||
enable_language(ASM_MARMASM)
|
||||
target_sources(autoexport PRIVATE nop_ARM64.asm)
|
||||
set_property(SOURCE nop_ARM64.asm PROPERTY VS_SETTINGS "PreprocessWithCl=false")
|
||||
else()
|
||||
enable_language(ASM_MASM)
|
||||
target_sources(autoexport PRIVATE nop_x64.asm)
|
||||
endif()
|
||||
target_compile_definitions(say PRIVATE HAS_JUSTNOP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -4,9 +4,21 @@ project(autoexport)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin)
|
||||
add_subdirectory(sub)
|
||||
|
||||
add_library(objlib OBJECT objlib.c)
|
||||
set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
add_library(autoexport SHARED hello.cxx world.cxx foo.c $<TARGET_OBJECTS:objlib>)
|
||||
|
||||
add_library(objlib_maybe_lto OBJECT objlib_maybe_lto.c)
|
||||
set_property(TARGET objlib_maybe_lto PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||
# Automatic export definition generation for LTO objects is currently only
|
||||
# supported with Clang targeting the MSVC ABI.
|
||||
if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set_property(TARGET objlib_maybe_lto PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
endif()
|
||||
|
||||
add_library(autoexport SHARED hello.cxx world.cxx foo.c)
|
||||
target_link_libraries(autoexport PRIVATE objlib objlib_maybe_lto)
|
||||
|
||||
add_library(autoexport3 SHARED cppCLI.cxx)
|
||||
if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600
|
||||
AND NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
|
||||
@@ -18,11 +30,16 @@ if(MSVC)
|
||||
set_target_properties(say PROPERTIES ENABLE_EXPORTS ON)
|
||||
add_library(autoexport_for_exec SHARED hello2.c)
|
||||
target_link_libraries(autoexport_for_exec say)
|
||||
if(NOT MSVC_VERSION VERSION_LESS 1600 AND
|
||||
NOT CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
|
||||
enable_language(ASM_MASM)
|
||||
target_sources(autoexport PRIVATE nop.asm)
|
||||
set_property(SOURCE nop.asm PROPERTY COMPILE_FLAGS /safeseh)
|
||||
|
||||
if(NOT MSVC_VERSION VERSION_LESS 1600)
|
||||
if(CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
|
||||
enable_language(ASM_MARMASM)
|
||||
target_sources(autoexport PRIVATE nop_ARM64.asm)
|
||||
set_property(SOURCE nop_ARM64.asm PROPERTY VS_SETTINGS "PreprocessWithCl=false")
|
||||
else()
|
||||
enable_language(ASM_MASM)
|
||||
target_sources(autoexport PRIVATE nop_x64.asm)
|
||||
endif()
|
||||
target_compile_definitions(say PRIVATE HAS_JUSTNOP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
AREA SOME, CODE, READONLY
|
||||
|
||||
EXPORT justnop
|
||||
justnop PROC
|
||||
ret
|
||||
ENDP
|
||||
|
||||
END
|
||||
@@ -3,10 +3,11 @@ ELSE
|
||||
.MODEL FLAT,C
|
||||
ENDIF
|
||||
|
||||
SOME SEGMENT EXECUTE READ
|
||||
.CODE
|
||||
|
||||
public justnop
|
||||
justnop:
|
||||
justnop PROC
|
||||
ret
|
||||
justnop ENDP
|
||||
|
||||
END
|
||||
@@ -0,0 +1,4 @@
|
||||
int objlib_maybe_lto(void)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
@@ -13,6 +13,7 @@ int WINAPI foo();
|
||||
// test regular C
|
||||
int bar();
|
||||
int objlib();
|
||||
int objlib_maybe_lto();
|
||||
void justnop();
|
||||
}
|
||||
|
||||
@@ -45,6 +46,9 @@ int main()
|
||||
printf("\n");
|
||||
bar();
|
||||
objlib();
|
||||
if (objlib_maybe_lto() != 8) {
|
||||
return 1;
|
||||
}
|
||||
printf("\n");
|
||||
cliFunction();
|
||||
printf("\n");
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
E_cat_binary_files/binary.obj -text
|
||||
E_cat_good_binary_cat-stdout.txt -text -whitespace
|
||||
E___create_def-nm-*-expected.def whitespace=-blank-at-eol
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
string(REGEX REPLACE [[^E___create_def-nm-]] "" subtest "${test}")
|
||||
cmake_path(APPEND RunCMake_TEST_BINARY_DIR "${subtest}.def" OUTPUT_VARIABLE actual_def)
|
||||
cmake_path(APPEND RunCMake_TEST_SOURCE_DIR "${test}-expected.def" OUTPUT_VARIABLE expected_def)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E compare_files --ignore-eol ${actual_def} ${expected_def}
|
||||
RESULT_VARIABLE compare_result)
|
||||
if(compare_result)
|
||||
set(RunCMake_TEST_FAILED "${actual_def} does not match ${expected_def}")
|
||||
endif()
|
||||
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
manual
|
||||
mixed
|
||||
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
first
|
||||
second
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,2 @@
|
||||
^cmake-nm-does-not-exist returned an error: [^
|
||||
]*
|
||||
@@ -0,0 +1,2 @@
|
||||
EXPORTS
|
||||
single
|
||||
@@ -0,0 +1,2 @@
|
||||
EXPORTS
|
||||
spaced
|
||||
@@ -0,0 +1,6 @@
|
||||
EXPORTS
|
||||
??_7Example@@6B@ DATA
|
||||
bss DATA
|
||||
common DATA
|
||||
data DATA
|
||||
text
|
||||
@@ -0,0 +1 @@
|
||||
^Ignoring symbol 'unknown' with unrecognized type '\?' in object 'symbol-types.obj'\.$
|
||||
@@ -0,0 +1,42 @@
|
||||
string(ASCII 66 67 192 222 llvm_bitcode_magic)
|
||||
string(REPEAT "x" 64 llvm_bitcode_padding)
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/bitcode.obj"
|
||||
"${llvm_bitcode_magic}${llvm_bitcode_padding}")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/nm-not-found.objs" [[
|
||||
bitcode.obj
|
||||
]])
|
||||
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/single.obj" "")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/single.objs" [[
|
||||
single.obj
|
||||
]])
|
||||
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/symbol-types.obj" "")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/symbol-types.objs" [[
|
||||
symbol-types.obj
|
||||
]])
|
||||
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/first.obj" "")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/no-symbols.obj" "")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/second.obj" "")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/multiple.objs" [[
|
||||
first.obj
|
||||
no-symbols.obj
|
||||
second.obj
|
||||
]])
|
||||
|
||||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/directory with spaces")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/directory with spaces/spaced.obj" "")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/spaces.objs" [[
|
||||
directory with spaces/spaced.obj
|
||||
]])
|
||||
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/manual.def" [[
|
||||
EXPORTS
|
||||
manual
|
||||
]])
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/mixed.obj" "")
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/mixed.objs" [[
|
||||
manual.def
|
||||
mixed.obj
|
||||
]])
|
||||
@@ -87,6 +87,26 @@ run_cmake_command(E___run_co_compile-no--- ${CMAKE_COMMAND} -E __run_co_compile
|
||||
run_cmake_command(E___run_co_compile-no-cc ${CMAKE_COMMAND} -E __run_co_compile --iwyu=iwyu-does-not-exist --)
|
||||
run_cmake_command(E___run_co_compile-tidy-remove-fixes ${CMAKE_COMMAND} -E __run_co_compile "--tidy=${CMAKE_COMMAND}\\;-E\\;true\\;--export-fixes=${RunCMake_BINARY_DIR}/tidy-fixes.yaml" -- ${CMAKE_COMMAND} -E true)
|
||||
|
||||
block()
|
||||
set(RunCMake_TEST_BINARY_DIR
|
||||
${RunCMake_BINARY_DIR}/E___create_def-build)
|
||||
run_cmake(E___create_def)
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
|
||||
# bitcode.obj contains LLVM bitcode magic followed by padding.
|
||||
run_cmake_command(E___create_def-nm-not-found ${CMAKE_COMMAND} -E __create_def nm-not-found.def nm-not-found.objs --nm=cmake-nm-does-not-exist)
|
||||
|
||||
if(CMAKE_HOST_UNIX)
|
||||
set(fake_nm ${RunCMake_SOURCE_DIR}/fake-nm.sh)
|
||||
set(RunCMake-check-file E___create_def-nm-check.cmake)
|
||||
run_cmake_command(E___create_def-nm-single ${CMAKE_COMMAND} -E __create_def single.def single.objs --nm=${fake_nm})
|
||||
run_cmake_command(E___create_def-nm-symbol-types ${CMAKE_COMMAND} -E __create_def symbol-types.def symbol-types.objs --nm=${fake_nm})
|
||||
run_cmake_command(E___create_def-nm-multiple ${CMAKE_COMMAND} -E __create_def multiple.def multiple.objs --nm=${fake_nm})
|
||||
run_cmake_command(E___create_def-nm-spaces ${CMAKE_COMMAND} -E __create_def spaces.def spaces.objs --nm=${fake_nm})
|
||||
run_cmake_command(E___create_def-nm-mixed ${CMAKE_COMMAND} -E __create_def mixed.def mixed.objs --nm=${fake_nm})
|
||||
endif()
|
||||
endblock()
|
||||
|
||||
block()
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/list-cache-build)
|
||||
run_cmake(list-cache)
|
||||
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
if test "$#" -eq 4 &&
|
||||
test "$1" = "--no-weak" &&
|
||||
test "$2" = "--defined-only" &&
|
||||
test "$3" = "--format=posix"; then
|
||||
print_file_name=0
|
||||
input=$4
|
||||
elif test "$#" -eq 5 &&
|
||||
test "$1" = "--no-weak" &&
|
||||
test "$2" = "--defined-only" &&
|
||||
test "$3" = "--format=posix" &&
|
||||
test "$4" = "--print-file-name"; then
|
||||
print_file_name=1
|
||||
input=$5
|
||||
else
|
||||
echo "unexpected nm arguments: $*" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pending_symbol=0
|
||||
|
||||
finish_symbol()
|
||||
{
|
||||
if test "${pending_symbol}" -eq 1; then
|
||||
printf ' 0 0\r\n'
|
||||
pending_symbol=0
|
||||
fi
|
||||
}
|
||||
|
||||
start_symbol()
|
||||
{
|
||||
finish_symbol
|
||||
if test "${print_file_name}" -eq 1; then
|
||||
printf '%s: %s %s' "$1" "$2" "$3"
|
||||
else
|
||||
printf '%s %s' "$2" "$3"
|
||||
fi
|
||||
pending_symbol=1
|
||||
}
|
||||
|
||||
process_object()
|
||||
{
|
||||
object=$1
|
||||
case "${object}" in
|
||||
\"*\")
|
||||
object=${object#\"}
|
||||
object=${object%\"}
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${object}" in
|
||||
*single.obj)
|
||||
start_symbol "${object}" single T
|
||||
;;
|
||||
*symbol-types.obj)
|
||||
start_symbol "${object}" absolute A
|
||||
start_symbol "${object}" bss B
|
||||
start_symbol "${object}" common C
|
||||
start_symbol "${object}" data D
|
||||
start_symbol "${object}" import I
|
||||
start_symbol "${object}" debug N
|
||||
start_symbol "${object}" readonly R
|
||||
start_symbol "${object}" '??_7Example@@6B@' R
|
||||
start_symbol "${object}" '??_R4Example@@6B@' R
|
||||
start_symbol "${object}" section S
|
||||
start_symbol "${object}" text T
|
||||
start_symbol "${object}" undefined U
|
||||
start_symbol "${object}" weak_object V
|
||||
start_symbol "${object}" weak W
|
||||
start_symbol "${object}" local_absolute a
|
||||
start_symbol "${object}" local_bss b
|
||||
start_symbol "${object}" local_common c
|
||||
start_symbol "${object}" local_data d
|
||||
start_symbol "${object}" local_import i
|
||||
start_symbol "${object}" local_debug n
|
||||
start_symbol "${object}" local_readonly r
|
||||
start_symbol "${object}" local_section s
|
||||
start_symbol "${object}" local_text t
|
||||
start_symbol "${object}" local_weak_object v
|
||||
start_symbol "${object}" local_weak w
|
||||
start_symbol "${object}" unknown '?'
|
||||
;;
|
||||
*first.obj)
|
||||
start_symbol "${object}" first T
|
||||
;;
|
||||
*no-symbols.obj)
|
||||
sleep 0.1
|
||||
printf '%s: no symbols\n' "${object}" >&2
|
||||
sleep 0.1
|
||||
finish_symbol
|
||||
;;
|
||||
*second.obj)
|
||||
start_symbol "${object}" second T
|
||||
;;
|
||||
*spaced.obj)
|
||||
start_symbol "${object}" spaced T
|
||||
;;
|
||||
*mixed.obj)
|
||||
start_symbol "${object}" mixed T
|
||||
;;
|
||||
*)
|
||||
echo "unexpected nm input: ${object}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "${input}" in
|
||||
@*)
|
||||
response=${input#@}
|
||||
while IFS= read -r object || test -n "${object}"; do
|
||||
process_object "${object}"
|
||||
done < "${response}"
|
||||
;;
|
||||
*)
|
||||
process_object "${input}"
|
||||
;;
|
||||
esac
|
||||
finish_symbol
|
||||
@@ -0,0 +1,24 @@
|
||||
set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/AutoExportNm.vcxproj")
|
||||
if(NOT EXISTS "${vcProjectFile}")
|
||||
set(RunCMake_TEST_FAILED
|
||||
"Project file ${vcProjectFile} does not exist.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(READ "${vcProjectFile}" vcProject)
|
||||
file(READ "${RunCMake_TEST_BINARY_DIR}/platform-toolset.txt"
|
||||
platformToolset)
|
||||
if(platformToolset MATCHES [[^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$]] OR
|
||||
platformToolset MATCHES [[^[Cc][Ll][Aa][Nn][Gg]([Cc][Ll]$|_[0-9])]])
|
||||
if(NOT vcProject MATCHES
|
||||
[[__create_def[^<]*--nm=C:/cmake-nm-test/tool-nm\.exe]])
|
||||
set(RunCMake_TEST_FAILED
|
||||
"__create_def does not pass CMAKE_NM in ${vcProjectFile}.")
|
||||
endif()
|
||||
else()
|
||||
if(vcProject MATCHES
|
||||
[[__create_def[^<]*--nm=C:/cmake-nm-test/tool-nm\.exe]])
|
||||
set(RunCMake_TEST_FAILED
|
||||
"__create_def passes CMAKE_NM for toolset ${platformToolset}.")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,11 @@
|
||||
enable_language(C)
|
||||
|
||||
set(CMAKE_NM "C:/cmake-nm-test/tool-nm.exe")
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/platform-toolset.txt"
|
||||
"${CMAKE_VS_PLATFORM_TOOLSET}")
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/AutoExportNm.c"
|
||||
"void auto_export_nm(void) {}\n")
|
||||
add_library(AutoExportNm SHARED
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/AutoExportNm.c")
|
||||
set_property(TARGET AutoExportNm PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
@@ -5,6 +5,7 @@ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREA
|
||||
endif()
|
||||
|
||||
run_cmake(CustomCommandGenex)
|
||||
run_cmake(AutoExportNm)
|
||||
if(NOT RunCMake_GENERATOR MATCHES "^Visual Studio 1[1-5] ")
|
||||
run_cmake(CustomCommandParallel)
|
||||
run_cmake(CustomCommandParallelDisable)
|
||||
|
||||
Reference in New Issue
Block a user