CMakeLists.txt 8.64 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1
cmake_minimum_required (VERSION 2.6)
2
PROJECT(TryCompile)
3

Alexander Neundorf's avatar
   
Alexander Neundorf committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
MACRO(TEST_ASSERT value msg)
  IF (NOT ${value})
    MESSAGE (SEND_ERROR "Assertion failure:" ${msg} )
  ENDIF (NOT ${value})
ENDMACRO(TEST_ASSERT)

MACRO(TEST_FAIL value msg)
  IF (${value})
    MESSAGE (SEND_ERROR "Failing test succeeded:" ${msg} )
  ENDIF (${value})
ENDMACRO(TEST_FAIL)

MACRO(TEST_EXPECT_EXACT command expected)
  IF(NOT "x${result}" STREQUAL "x${expected}")
    MESSAGE(SEND_ERROR "${CMAKE_CURRENT_LIST_LINE}: TEST \"${command}\" failed: \"${result}\" expected: \"${expected}\"")
  ENDIF(NOT "x${result}" STREQUAL "x${expected}")
ENDMACRO(TEST_EXPECT_EXACT command expected)

MACRO(TEST_EXPECT_CONTAINS command expected)
  IF(NOT "${result}" MATCHES "${expected}")
    MESSAGE(SEND_ERROR "${CMAKE_CURRENT_LIST_LINE}: TEST \"${command}\" failed: \"${result}\" expected: \"${expected}\"")
  ENDIF(NOT "${result}" MATCHES "${expected}")
ENDMACRO(TEST_EXPECT_CONTAINS command expected)

Bill Hoffman's avatar
Bill Hoffman committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

# Write a simple test program with an include file
WRITE_FILE( ${CMAKE_BINARY_DIR}/CMakeTmp/my_include.h "#define TEST_VALUE 0\n")
WRITE_FILE( ${CMAKE_BINARY_DIR}/my_test.cxx "#include \"my_include.h\"\nint main() { return TEST_VALUE; }")

SET(INC_STRING "-I  \"${CMAKE_BINARY_DIR}/CMakeTmp\"")
# Removing the quotes fixes the Xcode 3 bug, but this
# will fail if ${CMAKE_BINARY_DIR} contains an spaces
# SET(INC_STRING "-I ${CMAKE_BINARY_DIR}/CMakeTmp")

TRY_RUN(my_test my_test_COMPILED
        ${CMAKE_BINARY_DIR}
        ${CMAKE_BINARY_DIR}/my_test.cxx
        CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${INC_STRING}
        OUTPUT_VARIABLE OUTPUT)


# Display the results of the test and write compilation errors to a log
IF(NOT my_test_COMPILED)
  MESSAGE(FATAL_ERROR "Performing Try-Run - Test Compilation Failed")
  WRITE_FILE(${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
    "Performing Try-Run my_test failed to compile with the following output:\n"
    "${OUTPUT}\n" APPEND)
ELSE(NOT my_test_COMPILED)
  IF(my_test)
    MESSAGE("The test compiled but failed at run time")
  ELSE(my_test)
    MESSAGE("The test compiled and passed")
  ENDIF(my_test)
ENDIF(NOT my_test_COMPILED)



61
# try to compile a file that should compile
Alexander Neundorf's avatar
   
Alexander Neundorf committed
62
# also check that COPY_FILE works
63
TRY_COMPILE(SHOULD_PASS
64
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp  
65
    ${TryCompile_SOURCE_DIR}/pass.c
Alexander Neundorf's avatar
   
Alexander Neundorf committed
66
67
68
69
    OUTPUT_VARIABLE TRY_OUT
    COPY_FILE ${TryCompile_BINARY_DIR}/CopyOfPass
    )

70
IF(NOT SHOULD_PASS)
71
  MESSAGE(SEND_ERROR "should pass failed ${TRY_OUT}")
72
ENDIF(NOT SHOULD_PASS)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
73
74
75
76
77
IF(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
   MESSAGE(SEND_ERROR "COPY_FILE to \"${TryCompile_BINARY_DIR}/CopyOfPass\" failed")
ELSE(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
   FILE(REMOVE "${TryCompile_BINARY_DIR}/CopyOfPass")
ENDIF(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
78
79
80

# try to compile a file that should not compile
TRY_COMPILE(SHOULD_FAIL
81
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp  
82
    ${TryCompile_SOURCE_DIR}/fail.c
83
84
    OUTPUT_VARIABLE TRY_OUT)
IF(SHOULD_FAIL)
85
   MESSAGE(SEND_ERROR "Should fail passed ${TRY_OUT}")
86
87
88
89
ENDIF(SHOULD_FAIL)

# try to compile a file that should compile
TRY_COMPILE(SHOULD_PASS
90
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp  
91
    ${TryCompile_SOURCE_DIR}/pass.c
92
93
    OUTPUT_VARIABLE TRY_OUT)
IF(NOT SHOULD_PASS)
94
  MESSAGE(SEND_ERROR "should pass failed ${TRY_OUT}")
95
96
97
98
ENDIF(NOT SHOULD_PASS)

# try to compile a file that should not compile
TRY_COMPILE(SHOULD_FAIL
99
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp 
100
    ${TryCompile_SOURCE_DIR}/fail.c
101
102
    OUTPUT_VARIABLE TRY_OUT)
IF(SHOULD_FAIL)
103
   MESSAGE(SEND_ERROR "Should fail passed ${TRY_OUT}")
104
105
106
107
108
109
110
111
112
113
114
ENDIF(SHOULD_FAIL)

IF(NOT SHOULD_FAIL)
  IF(SHOULD_PASS)
    MESSAGE("All Tests passed, ignore all previous output.")
  ELSE(SHOULD_PASS)
    MESSAGE("Test failed")
  ENDIF(SHOULD_PASS)
ELSE(NOT SHOULD_FAIL)
  MESSAGE("Test failed")
ENDIF(NOT SHOULD_FAIL)
Ken Martin's avatar
Ken Martin committed
115
TRY_COMPILE(CMAKE_ANSI_FOR_SCOPE   
116
  ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp 
117
118
119
120
121
122
123
    ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT)
IF (CMAKE_ANSI_FOR_SCOPE)
   MESSAGE("Compiler supports ansi for")
ELSE(CMAKE_ANSI_FOR_SCOPE)
   MESSAGE("Compiler does not support ansi for scope")
ENDIF(CMAKE_ANSI_FOR_SCOPE)

Ken Martin's avatar
Ken Martin committed
124
TRY_COMPILE(CMAKE_ANSI_FOR_SCOPE
125
  ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp 
126
127
128
129
130
    ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT)
IF (CMAKE_ANSI_FOR_SCOPE)
   MESSAGE("Compiler supports ansi for")
ELSE(CMAKE_ANSI_FOR_SCOPE)
   MESSAGE("Compiler does not support ansi for scope")
Alexander Neundorf's avatar
   
Alexander Neundorf committed
131
ENDIF(CMAKE_ANSI_FOR_SCOPE)        
132
133
134
135
136
137
138
139

MESSAGE("use the module now")
INCLUDE(${CMAKE_ROOT}/Modules/TestForANSIForScope.cmake)
IF (CMAKE_ANSI_FOR_SCOPE)
   MESSAGE("Compiler supports ansi for")
ELSE(CMAKE_ANSI_FOR_SCOPE)
   MESSAGE("Compiler does not support ansi for scope")
ENDIF(CMAKE_ANSI_FOR_SCOPE)
140

141
ADD_EXECUTABLE(TryCompile pass.c)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
142
143
144
145
146
147

######################################

# now two tests for TRY_RUN

# try to run a file that should compile and run without error
Alexander Neundorf's avatar
   
Alexander Neundorf committed
148
149
# also check that OUTPUT_VARIABLE contains both the compile output
# and the run output
Alexander Neundorf's avatar
   
Alexander Neundorf committed
150
151
152
153
154
155
156
157
158
159
TRY_RUN(SHOULD_RUN SHOULD_COMPILE
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp  
    ${TryCompile_SOURCE_DIR}/exit_success.c
    OUTPUT_VARIABLE TRY_OUT)
IF(NOT SHOULD_COMPILE)
  MESSAGE(SEND_ERROR "exit_success failed compiling: ${TRY_OUT}")
ENDIF(NOT SHOULD_COMPILE)
IF(NOT "${SHOULD_RUN}" STREQUAL "0")
  MESSAGE(SEND_ERROR "exit_success failed running with exit code ${SHOULD_RUN}")
ENDIF(NOT "${SHOULD_RUN}" STREQUAL "0")
Alexander Neundorf's avatar
   
Alexander Neundorf committed
160
161
162
163
164
165
166
167
168
# check the compile output for the filename
IF(NOT "${TRY_OUT}" MATCHES "exit_success")
  MESSAGE(SEND_ERROR " TRY_OUT didn't contain \"exit_success\": \"${TRY_OUT}\"")
ENDIF(NOT "${TRY_OUT}" MATCHES "exit_success")
# check the run output
IF(NOT "${TRY_OUT}" MATCHES "hello world")
  MESSAGE(SEND_ERROR " TRY_OUT didn't contain \"hello world\": \"${TRY_OUT}\"")
ENDIF(NOT "${TRY_OUT}" MATCHES "hello world")

Alexander Neundorf's avatar
   
Alexander Neundorf committed
169
170
171
172
173

# try to run a file that should compile and run, but return an error
TRY_RUN(SHOULD_EXIT_WITH_ERROR SHOULD_COMPILE
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp  
    ${TryCompile_SOURCE_DIR}/exit_with_error.c
Alexander Neundorf's avatar
   
Alexander Neundorf committed
174
175
176
    COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
    RUN_OUTPUT_VARIABLE RUN_OUTPUT)

Alexander Neundorf's avatar
   
Alexander Neundorf committed
177
IF(NOT SHOULD_COMPILE)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
178
  MESSAGE(STATUS " exit_with_error failed compiling: ${COMPILE_OUTPUT}")
Alexander Neundorf's avatar
   
Alexander Neundorf committed
179
180
181
182
183
ENDIF(NOT SHOULD_COMPILE)
IF("${SHOULD_EXIT_WITH_ERROR}" STREQUAL "0")
  MESSAGE(SEND_ERROR " exit_with_error passed with exit code ${SHOULD_EXIT_WITH_ERROR}")
ENDIF("${SHOULD_EXIT_WITH_ERROR}" STREQUAL "0")

Alexander Neundorf's avatar
   
Alexander Neundorf committed
184
185
186
187
188
189
190
191
192
193
194
195
# check the compile output, it should contain the filename
IF(NOT "${COMPILE_OUTPUT}" MATCHES "exit_with_error")
  MESSAGE(SEND_ERROR " COMPILE_OUT didn't contain \"exit_with_error\": \"${COMPILE_OUTPUT}\"")
ENDIF(NOT "${COMPILE_OUTPUT}" MATCHES "exit_with_error")
#... but not the run time output
IF("${COMPILE_OUTPUT}" MATCHES "hello world")
  MESSAGE(SEND_ERROR " COMPILE_OUT contains the run output: \"${COMPILE_OUTPUT}\"")
ENDIF("${COMPILE_OUTPUT}" MATCHES "hello world")
# check the run output, it should stdout
IF(NOT "${RUN_OUTPUT}" MATCHES "hello world")
  MESSAGE(SEND_ERROR " RUN_OUTPUT didn't contain \"hello world\": \"${RUN_OUTPUT}\"")
ENDIF(NOT "${RUN_OUTPUT}" MATCHES "hello world")
Alexander Neundorf's avatar
   
Alexander Neundorf committed
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

#######################################################################
#
# also test that the CHECK_C_SOURCE_COMPILES, CHECK_CXX_SOURCE_COMPILES
# CHECK_C_SOURCE_RUNS and CHECK_CXX_SOURCE_RUNS macros work

INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckCXXSourceCompiles)
INCLUDE(CheckCSourceRuns)
INCLUDE(CheckCXXSourceRuns)

CHECK_C_SOURCE_COMPILES("I dont build" C_BUILD_SHOULD_FAIL)
CHECK_C_SOURCE_COMPILES("int main() {return 0;}" C_BUILD_SHOULD_WORK)
CHECK_C_SOURCE_RUNS("int main() {return 1;}" C_RUN_SHOULD_FAIL)
CHECK_C_SOURCE_RUNS("int main() {return 0;}" C_RUN_SHOULD_WORK)

TEST_FAIL(C_BUILD_SHOULD_FAIL "CHECK_C_SOURCE_COMPILES() succeeded, but should have failed")
TEST_ASSERT(C_BUILD_SHOULD_WORK "CHECK_C_SOURCE_COMPILES() failed")
TEST_FAIL(C_RUN_SHOULD_FAIL "CHECK_C_SOURCE_RUNS() succeeded, but should have failed")
TEST_ASSERT(C_RUN_SHOULD_WORK "CHECK_C_SOURCE_RUNS() failed")

CHECK_CXX_SOURCE_COMPILES("I dont build" CXX_BUILD_SHOULD_FAIL)
CHECK_CXX_SOURCE_COMPILES("int main() {return 0;}" CXX_BUILD_SHOULD_WORK)
CHECK_CXX_SOURCE_RUNS("int main() {return 2;}" CXX_RUN_SHOULD_FAIL)
CHECK_CXX_SOURCE_RUNS("int main() {return 0;}" CXX_RUN_SHOULD_WORK)

TEST_FAIL(CXX_BUILD_SHOULD_FAIL "CHECK_CXX_SOURCE_COMPILES() succeeded, but should have failed")
TEST_ASSERT(CXX_BUILD_SHOULD_WORK "CHECK_CXX_SOURCE_COMPILES() failed")
TEST_FAIL(CXX_RUN_SHOULD_FAIL "CHECK_CXX_SOURCE_RUNS() succeeded, but should have failed")
TEST_ASSERT(CXX_RUN_SHOULD_WORK "CHECK_CXX_SOURCE_RUNS() failed")