summaryrefslogtreecommitdiff
path: root/Tests/BuildDepends
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/BuildDepends')
-rw-r--r--Tests/BuildDepends/CMakeLists.txt225
-rw-r--r--Tests/BuildDepends/Project/CMakeLists.txt109
-rw-r--r--Tests/BuildDepends/Project/bar.cxx25
-rw-r--r--Tests/BuildDepends/Project/dep.cxx1
-rw-r--r--Tests/BuildDepends/Project/dep_custom.cxx1
-rw-r--r--Tests/BuildDepends/Project/generator.cxx24
-rw-r--r--Tests/BuildDepends/Project/linkdep.cxx4
-rw-r--r--Tests/BuildDepends/Project/zot.cxx14
-rw-r--r--Tests/BuildDepends/Project/zot_macro_dir.cxx7
-rw-r--r--Tests/BuildDepends/Project/zot_macro_tgt.cxx7
10 files changed, 417 insertions, 0 deletions
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
new file mode 100644
index 000000000..5e36d11b4
--- /dev/null
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -0,0 +1,225 @@
+# this test creates a static library and an executable
+# the source to the library is then changed
+# and the build is done on the executable and if things
+# are working the executable should relink with the new
+# value. The subdir Project contains the CMakelists.txt
+# and source files for the test project.
+cmake_minimum_required (VERSION 2.6)
+project(BuildDepends)
+
+# This entire test takes place during the initial
+# configure step. It should not run again when the
+# project is built.
+set(CMAKE_SUPPRESS_REGENERATION 1)
+
+# Xcode needs some help with the fancy dependencies in this test.
+if("${CMAKE_GENERATOR}" MATCHES "Xcode")
+ set(HELP_XCODE 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+function(help_xcode_depends)
+ if(HELP_XCODE)
+ file(GLOB_RECURSE MACRO_OBJS
+ ${BuildDepends_BINARY_DIR}/Project/zot_macro_*.o*
+ )
+ if(MACRO_OBJS)
+ message("Helping Xcode by removing objects [${MACRO_OBJS}]")
+ file(REMOVE ${MACRO_OBJS})
+ endif(MACRO_OBJS)
+ endif(HELP_XCODE)
+endfunction(help_xcode_depends)
+
+if("${CMAKE_GENERATOR}" MATCHES "Ninja")
+ set(HELP_NINJA 1) # TODO Why is this needed?
+endif()
+
+# The Intel compiler causes the MSVC linker to crash during
+# incremental linking, so avoid the /INCREMENTAL:YES flag.
+if(WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
+ set(_cmake_options "-DCMAKE_EXE_LINKER_FLAGS=")
+endif()
+
+if("${CMAKE_GENERATOR}" MATCHES "Make")
+ set(TEST_LINK_DEPENDS ${BuildDepends_BINARY_DIR}/Project/linkdep.txt)
+ file(WRITE ${TEST_LINK_DEPENDS} "1")
+endif()
+list(APPEND _cmake_options "-DTEST_LINK_DEPENDS=${TEST_LINK_DEPENDS}")
+
+list(APPEND _cmake_options "-DCMAKE_FORCE_DEPFILES=1")
+
+file(MAKE_DIRECTORY ${BuildDepends_BINARY_DIR}/Project)
+message("Creating Project/foo.cxx")
+write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
+ "const char* foo() { return \"foo\";}" )
+
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot.hxx.in
+ "static const char* zot = \"zot\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_custom.hxx.in
+ "static const char* zot_custom = \"zot_custom\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_dir.hxx
+ "static const char* zot_macro_dir = \"zot_macro_dir\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
+ "static const char* zot_macro_tgt = \"zot_macro_tgt\";\n")
+
+help_xcode_depends()
+
+message("Building project first time")
+try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ CMAKE_FLAGS ${_cmake_options}
+ OUTPUT_VARIABLE OUTPUT)
+if(HELP_XCODE)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+endif(HELP_XCODE)
+
+message("Output from first build:\n${OUTPUT}")
+if(NOT RESULT)
+ message(SEND_ERROR "Could not build test project (1)!")
+endif(NOT RESULT)
+
+set(bar ${BuildDepends_BINARY_DIR}/Project/bar${CMAKE_EXECUTABLE_SUFFIX})
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+ set(bar
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}")
+set(zot ${BuildDepends_BINARY_DIR}/Project/zot${CMAKE_EXECUTABLE_SUFFIX})
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+ set(zot
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}")
+
+message("Running ${bar} ")
+execute_process(COMMAND ${bar} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+if("${out}" STREQUAL "foo ")
+ message("Worked!")
+else("${out}" STREQUAL "foo ")
+ message(SEND_ERROR "Project did not initially build properly: ${out}")
+endif("${out}" STREQUAL "foo ")
+
+message("Running ${zot} ")
+execute_process(COMMAND ${zot} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+set(VALUE_UNCHANGED "[zot] [zot_custom] [zot_macro_dir] [zot_macro_tgt] ")
+if("${out}" STREQUAL "${VALUE_UNCHANGED}")
+ message("Worked!")
+else("${out}" STREQUAL "${VALUE_UNCHANGED}")
+ message(SEND_ERROR "Project did not initially build properly: ${out}")
+endif("${out}" STREQUAL "${VALUE_UNCHANGED}")
+
+message("Waiting 3 seconds...")
+# any additional argument will cause ${bar} to wait forever
+execute_process(COMMAND ${bar} -infinite TIMEOUT 3 OUTPUT_VARIABLE out)
+
+message("Modifying Project/foo.cxx")
+write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
+ "const char* foo() { return \"foo changed\";}" )
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot.hxx.in
+ "static const char* zot = \"zot changed\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_custom.hxx.in
+ "static const char* zot_custom = \"zot_custom changed\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_dir.hxx
+ "static const char* zot_macro_dir = \"zot_macro_dir changed\";\n")
+file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_macro_tgt.hxx
+ "static const char* zot_macro_tgt = \"zot_macro_tgt changed\";\n")
+
+if(TEST_LINK_DEPENDS)
+ file(WRITE ${TEST_LINK_DEPENDS} "2")
+endif()
+
+help_xcode_depends()
+
+message("Building project second time")
+try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ CMAKE_FLAGS ${_cmake_options}
+ OUTPUT_VARIABLE OUTPUT)
+
+# Xcode is in serious need of help here
+if(HELP_XCODE OR HELP_NINJA)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+ try_compile(RESULT
+ ${BuildDepends_BINARY_DIR}/Project
+ ${BuildDepends_SOURCE_DIR}/Project
+ testRebuild
+ OUTPUT_VARIABLE OUTPUT)
+endif()
+
+message("Output from second build:\n${OUTPUT}")
+if(NOT RESULT)
+ message(SEND_ERROR "Could not build test project (2)!")
+endif(NOT RESULT)
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/bar${CMAKE_EXECUTABLE_SUFFIX}")
+if(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}" )
+ message("found debug")
+endif(EXISTS
+ "${BuildDepends_BINARY_DIR}/Project/Debug/zot${CMAKE_EXECUTABLE_SUFFIX}")
+
+message("Running ${bar} ")
+execute_process(COMMAND ${bar} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+if("${out}" STREQUAL "foo changed ")
+ message("Worked!")
+else("${out}" STREQUAL "foo changed ")
+ message(SEND_ERROR "Project did not rebuild properly!")
+endif("${out}" STREQUAL "foo changed ")
+
+message("Running ${zot} ")
+execute_process(COMMAND ${zot} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
+string(REGEX REPLACE "[\r\n]" " " out "${out}")
+message("Run result: ${runResult} Output: \"${out}\"")
+
+set(VALUE_CHANGED
+ "[zot changed] [zot_custom changed] [zot_macro_dir changed] [zot_macro_tgt changed] "
+ )
+if("${out}" STREQUAL "${VALUE_CHANGED}")
+ message("Worked!")
+else("${out}" STREQUAL "${VALUE_CHANGED}")
+ message(SEND_ERROR "Project did not rebuild properly!")
+endif("${out}" STREQUAL "${VALUE_CHANGED}")
+
+if(TEST_LINK_DEPENDS)
+ set(linkdep ${BuildDepends_BINARY_DIR}/Project/linkdep${CMAKE_EXECUTABLE_SUFFIX})
+ if(${linkdep} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+ message("LINK_DEPENDS worked")
+ else()
+ message(SEND_ERROR "LINK_DEPENDS failed. Executable
+ ${linkdep}
+is not newer than dependency
+ ${TEST_LINK_DEPENDS}
+")
+ endif()
+endif()
diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt
new file mode 100644
index 000000000..ed8b8bf5d
--- /dev/null
+++ b/Tests/BuildDepends/Project/CMakeLists.txt
@@ -0,0 +1,109 @@
+cmake_minimum_required(VERSION 2.6)
+project(testRebuild)
+
+function(test_for_xcode4 result_var)
+ set(${result_var} 0 PARENT_SCOPE)
+ if(APPLE)
+ execute_process(COMMAND xcodebuild -version
+ OUTPUT_VARIABLE ov RESULT_VARIABLE rv
+ )
+ if("${rv}" STREQUAL "0")
+ if(ov MATCHES "^Xcode 4.[0-9].*$")
+ set(${result_var} 1 PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+if(APPLE)
+ # only use multi-arch if the sysroot exists on this machine
+ # Ninja needs -M which could not be used with multiple -arch flags
+ if(EXISTS "${CMAKE_OSX_SYSROOT}" AND NOT "${CMAKE_GENERATOR}" MATCHES "Ninja")
+ set(CMAKE_OSX_ARCHITECTURES "ppc;i386")
+ test_for_xcode4(is_xcode4)
+ if(is_xcode4)
+ # Xcode 4, use modern architectures as defaults
+ # Arch 'ppc' no longer works: tools no longer available starting with Xcode 4
+ set(CMAKE_OSX_ARCHITECTURES i386 x86_64)
+ endif()
+ endif()
+endif(APPLE)
+
+add_library(foo STATIC ${testRebuild_BINARY_DIR}/foo.cxx)
+set_target_properties(foo PROPERTIES OUTPUT_NAME "foolib")
+# Add a generated header that regenerates when the generator is
+# rebuilt.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/regen.h
+ COMMAND generator ${CMAKE_CURRENT_BINARY_DIR}/regen.h regen
+ DEPENDS generator # adds file-level dependency to re-run rule
+ )
+
+# Add a generated header that does NOT regenerate when the generator
+# is rebuilt.
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/noregen.h
+ COMMAND generator ${CMAKE_CURRENT_BINARY_DIR}/noregen.h noregen
+ )
+
+# Test that the generator rebuilds when the static library source file
+# changes. This should cause regen.h to be recreated also.
+add_executable(generator generator.cxx)
+target_link_libraries(generator foo)
+set_target_properties(generator PROPERTIES OUTPUT_NAME "gen")
+
+# Build an executable to drive the build and rebuild.
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+add_executable(bar bar.cxx
+ ${CMAKE_CURRENT_BINARY_DIR}/regen.h
+ ${CMAKE_CURRENT_BINARY_DIR}/noregen.h
+ )
+
+#-----------------------------------------------------------------------------
+IF("${CMAKE_GENERATOR}" MATCHES "Make")
+ # Test the IMPLICIT_DEPENDS feature.
+ SET(ZOT_DEPENDS IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep.cxx)
+ SET(ZOT_CUSTOM_DEP
+ IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom.cxx)
+ELSE("${CMAKE_GENERATOR}" MATCHES "Make")
+ # No IMPLICIT_DEPENDS...just depend directly.
+ SET(ZOT_DEPENDS DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in)
+ SET(ZOT_CUSTOM_DEP DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx.in)
+ENDIF("${CMAKE_GENERATOR}" MATCHES "Make")
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in
+ ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx
+ ${ZOT_DEPENDS}
+ )
+
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx.in
+ ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx
+ ${ZOT_CUSTOM_DEP}
+ )
+add_custom_target(zot_custom ALL DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx)
+
+add_executable(zot zot.cxx ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx
+ zot_macro_dir.cxx zot_macro_tgt.cxx)
+add_dependencies(zot zot_custom)
+
+# Test the #include line macro transformation rule support.
+set_property(
+ TARGET zot
+ PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM "ZOT_TGT(%)=<zot_%_tgt.hxx>"
+ )
+
+set_property(
+ DIRECTORY
+ PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM "ZOT_DIR(%)=<zot_%_dir.hxx>"
+ )
+
+if(TEST_LINK_DEPENDS)
+ add_executable(linkdep linkdep.cxx)
+ set_property(TARGET linkdep PROPERTY LINK_DEPENDS ${TEST_LINK_DEPENDS})
+endif()
diff --git a/Tests/BuildDepends/Project/bar.cxx b/Tests/BuildDepends/Project/bar.cxx
new file mode 100644
index 000000000..25d8bd21b
--- /dev/null
+++ b/Tests/BuildDepends/Project/bar.cxx
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <string.h>
+#include <regen.h>
+#include <noregen.h>
+
+int main(int argc, char** argv)
+{
+ /* Make sure the noregen header was not regenerated. */
+ if(strcmp("foo", noregen_string) != 0)
+ {
+ printf("FAILED: noregen.h was regenerated!\n");
+ return 1;
+ }
+
+ /* Print out the string that should have been regenerated. */
+ printf("%s\n", regen_string);
+ fflush(stdout);
+ // if any argument is used, wait forever
+ if (argc>1)
+ {
+ // wait that we get killed...
+ for(;;);
+ }
+ return 0;
+}
diff --git a/Tests/BuildDepends/Project/dep.cxx b/Tests/BuildDepends/Project/dep.cxx
new file mode 100644
index 000000000..6cfebe37c
--- /dev/null
+++ b/Tests/BuildDepends/Project/dep.cxx
@@ -0,0 +1 @@
+#include <zot.hxx.in>
diff --git a/Tests/BuildDepends/Project/dep_custom.cxx b/Tests/BuildDepends/Project/dep_custom.cxx
new file mode 100644
index 000000000..b6ac54847
--- /dev/null
+++ b/Tests/BuildDepends/Project/dep_custom.cxx
@@ -0,0 +1 @@
+#include <zot_custom.hxx.in>
diff --git a/Tests/BuildDepends/Project/generator.cxx b/Tests/BuildDepends/Project/generator.cxx
new file mode 100644
index 000000000..92a122de8
--- /dev/null
+++ b/Tests/BuildDepends/Project/generator.cxx
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+extern const char* foo();
+
+int main(int argc, const char* argv[])
+{
+ if(argc < 3)
+ {
+ fprintf(stderr, "Must specify output file and symbol prefix!");
+ return 1;
+ }
+ if(FILE* fout = fopen(argv[1], "w"))
+ {
+ fprintf(fout, "static const char* %s_string = \"%s\";\n", argv[2],
+ foo());
+ fclose(fout);
+ }
+ else
+ {
+ fprintf(stderr, "Could not open output file \"%s\"", argv[1]);
+ return 1;
+ }
+ return 0;
+}
diff --git a/Tests/BuildDepends/Project/linkdep.cxx b/Tests/BuildDepends/Project/linkdep.cxx
new file mode 100644
index 000000000..f8b643afb
--- /dev/null
+++ b/Tests/BuildDepends/Project/linkdep.cxx
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/BuildDepends/Project/zot.cxx b/Tests/BuildDepends/Project/zot.cxx
new file mode 100644
index 000000000..775fd3b43
--- /dev/null
+++ b/Tests/BuildDepends/Project/zot.cxx
@@ -0,0 +1,14 @@
+#include <zot.hxx>
+#include <zot_custom.hxx>
+#include <stdio.h>
+
+const char* zot_macro_dir_f();
+const char* zot_macro_tgt_f();
+
+int main()
+{
+ printf("[%s] [%s] [%s] [%s]\n", zot, zot_custom,
+ zot_macro_dir_f(), zot_macro_tgt_f());
+ fflush(stdout);
+ return 0;
+}
diff --git a/Tests/BuildDepends/Project/zot_macro_dir.cxx b/Tests/BuildDepends/Project/zot_macro_dir.cxx
new file mode 100644
index 000000000..733a4b37f
--- /dev/null
+++ b/Tests/BuildDepends/Project/zot_macro_dir.cxx
@@ -0,0 +1,7 @@
+#define ZOT_DIR(x) <zot_##x##_dir.hxx>
+#include ZOT_DIR(macro)
+
+const char* zot_macro_dir_f()
+{
+ return zot_macro_dir;
+}
diff --git a/Tests/BuildDepends/Project/zot_macro_tgt.cxx b/Tests/BuildDepends/Project/zot_macro_tgt.cxx
new file mode 100644
index 000000000..182ee16fd
--- /dev/null
+++ b/Tests/BuildDepends/Project/zot_macro_tgt.cxx
@@ -0,0 +1,7 @@
+#define ZOT_TGT(x) <zot_##x##_tgt.hxx>
+#include ZOT_TGT(macro)
+
+const char* zot_macro_tgt_f()
+{
+ return zot_macro_tgt;
+}