diff options
author | Gusts Kaksis <gusts.kaksis@sonarworks.com> | 2020-08-29 12:56:05 (GMT) |
---|---|---|
committer | Craig Scott <craig.scott@crascit.com> | 2020-08-31 21:38:48 (GMT) |
commit | 525464ed2a8857be3fac224b4afde22c8c7dadeb (patch) | |
tree | dc2f31f41a340ca3f06f1770de04950dd18268b8 /Tests/RunCMake | |
parent | dc0898205c7fcebcb5224ba3eb6dd95c05193bdd (diff) | |
download | CMake-525464ed2a8857be3fac224b4afde22c8c7dadeb.zip CMake-525464ed2a8857be3fac224b4afde22c8c7dadeb.tar.gz CMake-525464ed2a8857be3fac224b4afde22c8c7dadeb.tar.bz2 |
Xcode: Use "Link Binary With Libraries" build phase in some cases
OBJECT and STATIC libraries (framework or non-framework) do not use
this build phase. Not all items to be linked use this build phase either.
Co-Authored-By: Craig Scott <craig.scott@crascit.com>
Diffstat (limited to 'Tests/RunCMake')
12 files changed, 221 insertions, 0 deletions
diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase.cmake new file mode 100644 index 0000000..22a181f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase.cmake @@ -0,0 +1,87 @@ +enable_language(C) + +set(prototypes [[ +#include <stdio.h> +#include <zlib.h> +#include <resolv.h> +int func1(); +int func2(); +int func3(); +int func4(); +int func5(); +]]) +set(impl [[ +{ + printf("%p %p\n", compress, res_close); + return func1() + func2() + func3() + func4() + func5(); +} +]]) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/mainOuter.c + "${prototypes}\nint main(int argc, char** argv) ${impl}" +) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/funcOuter.c + "${prototypes}\nint funcOuter() ${impl}" +) + +foreach(i RANGE 1 5) + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/func${i}.c + "int func${i}() { return 32 + ${i}; }\n" + ) +endforeach() + +add_executable(app1 mainOuter.c) +add_library(static1 STATIC funcOuter.c) +add_library(shared1 SHARED funcOuter.c) +add_library(module1 MODULE funcOuter.c) +add_library(obj1 OBJECT funcOuter.c) +add_library(staticFramework1 STATIC funcOuter.c) +add_library(sharedFramework1 SHARED funcOuter.c) +set_target_properties(staticFramework1 PROPERTIES FRAMEWORK TRUE) +set_target_properties(sharedFramework1 PROPERTIES FRAMEWORK TRUE) + +add_library(static2 STATIC func1.c) +add_library(shared2 SHARED func2.c) +add_library(obj2 OBJECT func3.c) +add_library(staticFramework2 STATIC func4.c) +add_library(sharedFramework2 SHARED func5.c) +set_target_properties(staticFramework2 PROPERTIES FRAMEWORK TRUE) +set_target_properties(sharedFramework2 PROPERTIES FRAMEWORK TRUE) + +# Pick a couple of libraries that are always present in the Xcode SDK +find_library(libz z REQUIRED) +find_library(libresolv resolv REQUIRED) +add_library(imported2 UNKNOWN IMPORTED) +set_target_properties(imported2 PROPERTIES IMPORTED_LOCATION ${libz}) + +# Save these for the check script to use +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/foundLibs.cmake " +set(libz \"${libz}\") +set(libresolv \"${libresolv}\") +") + +set(mainTargets + app1 + static1 + shared1 + module1 + obj1 + staticFramework1 + sharedFramework1 +) +set(linkToThings + static2 + shared2 + obj2 + staticFramework2 + sharedFramework2 + imported2 + ${libresolv} +) + +foreach(mainTarget IN LISTS mainTargets) + foreach(linkTo IN LISTS linkToThings) + target_link_libraries(${mainTarget} PRIVATE ${linkTo}) + endforeach() +endforeach() diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_BUILT_ONLY-check.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_BUILT_ONLY-check.cmake new file mode 100644 index 0000000..2b7edf5 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_BUILT_ONLY-check.cmake @@ -0,0 +1,19 @@ +include(${RunCMake_TEST_SOURCE_DIR}/LinkBinariesBuildPhase_Funcs.cmake) +include(${RunCMake_TEST_BINARY_DIR}/foundLibs.cmake) + +# obj2 --> Embeds func3.o in the link flags, but obj2 is part of the path +# ${libz} --> This is for imported2 + +foreach(mainTarget IN ITEMS app1 shared1 module1 sharedFramework1) + checkFlags(OTHER_LDFLAGS ${mainTarget} + "obj2;${libz};${libresolv}" + "static2;shared2;staticFramework2;sharedFramework2" + ) +endforeach() + +foreach(mainTarget IN ITEMS static1 staticFramework1) + checkFlags(OTHER_LIBTOOLFLAGS ${mainTarget} + "obj2" + "static2;shared2;staticFramework2;sharedFramework2;${libz};${libresolv}" + ) +endforeach() diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_BUILT_ONLY.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_BUILT_ONLY.cmake new file mode 100644 index 0000000..f9dd643 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_BUILT_ONLY.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/LinkBinariesBuildPhase.cmake) diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_Funcs.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_Funcs.cmake new file mode 100644 index 0000000..601e52f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_Funcs.cmake @@ -0,0 +1,55 @@ +macro(returnOnError errorMsg) + if(NOT "${errorMsg}" STREQUAL "") + set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}\n${errorMsg}" PARENT_SCOPE) + return() + endif() +endmacro() + +function(getTargetFlags mainTarget projFlagsVar flagsVar errorVar) + # The flags variables in the project file might span over multiple lines + # so we can't easily read the flags directly from there. Instead, we use + # the xcodebuild -showBuildSettings option to report it on a single line. + execute_process( + COMMAND ${CMAKE_COMMAND} + --build ${RunCMake_TEST_BINARY_DIR} + --target ${mainTarget} + --config Debug + -- + -showBuildSettings + COMMAND grep ${projFlagsVar} + OUTPUT_VARIABLE flagsContents + RESULT_VARIABLE result + ) + + if(result) + set(${errorVar} "Failed to get flags for ${mainTarget}: ${result}" PARENT_SCOPE) + else() + unset(${errorVar} PARENT_SCOPE) + endif() + set(${flagsVar} "${flagsContents}" PARENT_SCOPE) +endfunction() + +function(checkFlags projFlagsVar mainTarget present absent) + getTargetFlags(${mainTarget} ${projFlagsVar} flags errorMsg) + returnOnError("${errorMsg}") + + foreach(linkTo IN LISTS present) + string(REGEX MATCH "${linkTo}" result "${flags}") + if("${result}" STREQUAL "") + string(APPEND RunCMake_TEST_FAILED + "\n${mainTarget} ${projFlagsVar} is missing ${linkTo}" + ) + endif() + endforeach() + + foreach(linkTo IN LISTS absent) + string(REGEX MATCH "${linkTo}" result "${flags}") + if(NOT "${result}" STREQUAL "") + string(APPEND RunCMake_TEST_FAILED + "\n${mainTarget} ${projFlagsVar} unexpectedly contains ${linkTo}" + ) + endif() + endforeach() + + set(RunCMake_TEST_FAILED ${RunCMake_TEST_FAILED} PARENT_SCOPE) +endfunction() diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID-result.txt b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID-stderr.txt b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID-stderr.txt new file mode 100644 index 0000000..0664304 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID-stderr.txt @@ -0,0 +1 @@ +CMake Error: Invalid value for XCODE_LINK_BUILD_PHASE_MODE: INVALID diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID.cmake new file mode 100644 index 0000000..0a20d20 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_INVALID.cmake @@ -0,0 +1,4 @@ +enable_language(CXX) + +add_executable(app main.cpp) +set_target_properties(app PROPERTIES XCODE_LINK_BUILD_PHASE_MODE INVALID) diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_KNOWN_LOCATION-check.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_KNOWN_LOCATION-check.cmake new file mode 100644 index 0000000..b0d2f7f --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_KNOWN_LOCATION-check.cmake @@ -0,0 +1,19 @@ +include(${RunCMake_TEST_SOURCE_DIR}/LinkBinariesBuildPhase_Funcs.cmake) +include(${RunCMake_TEST_BINARY_DIR}/foundLibs.cmake) + +# obj2 --> Embeds func3.o in the link flags, but obj2 is part of the path +# ${libz} --> This is for imported2 + +foreach(mainTarget IN ITEMS app1 shared1 module1 sharedFramework1) + checkFlags(OTHER_LDFLAGS ${mainTarget} + "obj2" + "static2;shared2;staticFramework2;sharedFramework2;${libz};${libresolv}" + ) +endforeach() + +foreach(mainTarget IN ITEMS static1 staticFramework1) + checkFlags(OTHER_LIBTOOLFLAGS ${mainTarget} + "obj2" + "static2;shared2;staticFramework2;sharedFramework2;${libz};${libresolv}" + ) +endforeach() diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_KNOWN_LOCATION.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_KNOWN_LOCATION.cmake new file mode 100644 index 0000000..f9dd643 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_KNOWN_LOCATION.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/LinkBinariesBuildPhase.cmake) diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_NONE-check.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_NONE-check.cmake new file mode 100644 index 0000000..3074881 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_NONE-check.cmake @@ -0,0 +1,19 @@ +include(${RunCMake_TEST_SOURCE_DIR}/LinkBinariesBuildPhase_Funcs.cmake) +include(${RunCMake_TEST_BINARY_DIR}/foundLibs.cmake) + +# obj2 --> Embeds func3.o in the link flags, but obj2 is part of the path +# ${libz} --> This is for imported2 + +foreach(mainTarget IN ITEMS app1 shared1 module1 sharedFramework1) + checkFlags(OTHER_LDFLAGS ${mainTarget} + "static2;shared2;staticFramework2;sharedFramework2;obj2;${libz};${libresolv}" + "" + ) +endforeach() + +foreach(mainTarget IN ITEMS static1 staticFramework1) + checkFlags(OTHER_LIBTOOLFLAGS ${mainTarget} + "obj2" + "static2;shared2;staticFramework2;sharedFramework2;${libz};${libresolv}" + ) +endforeach() diff --git a/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_NONE.cmake b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_NONE.cmake new file mode 100644 index 0000000..f9dd643 --- /dev/null +++ b/Tests/RunCMake/XcodeProject/LinkBinariesBuildPhase_NONE.cmake @@ -0,0 +1 @@ +include(${CMAKE_CURRENT_LIST_DIR}/LinkBinariesBuildPhase.cmake) diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake index ed300bb..70eaaeb 100644 --- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake @@ -19,6 +19,19 @@ endfunction() XcodeGenerateTopLevelProjectOnlyWithObjectLibrary() +function(LinkBinariesBuildPhase mode) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LinkBinariesBuildPhase_${mode}-build) + set(RunCMake_TEST_OPTIONS "-DCMAKE_XCODE_LINK_BUILD_PHASE_MODE=${mode}") + run_cmake(LinkBinariesBuildPhase_${mode}) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(LinkBinariesBuildPhase_${mode}-build ${CMAKE_COMMAND} --build .) +endfunction() + +LinkBinariesBuildPhase(NONE) +LinkBinariesBuildPhase(BUILT_ONLY) +LinkBinariesBuildPhase(KNOWN_LOCATION) +run_cmake(LinkBinariesBuildPhase_INVALID) + run_cmake(XcodeObjectNeedsEscape) run_cmake(XcodeObjectNeedsQuote) run_cmake(XcodeOptimizationFlags) |