summaryrefslogtreecommitdiffstats
path: root/Tests/TryCompile/CMakeLists.txt
blob: 90f878e7bc975fd4120c1396206d84d1ac0f3cdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
cmake_minimum_required (VERSION 2.6)
project(TryCompile)

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)


# try to compile a file that should compile
# also check that COPY_FILE works
try_compile(SHOULD_PASS
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
    ${TryCompile_SOURCE_DIR}/pass.c
    OUTPUT_VARIABLE TRY_OUT
    COPY_FILE ${TryCompile_BINARY_DIR}/CopyOfPass
    )

if(NOT SHOULD_PASS)
  message(SEND_ERROR "should pass failed ${TRY_OUT}")
endif(NOT SHOULD_PASS)
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")

# try to compile a file that should not compile
try_compile(SHOULD_FAIL
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
    ${TryCompile_SOURCE_DIR}/fail.c
    OUTPUT_VARIABLE TRY_OUT)
if(SHOULD_FAIL)
   message(SEND_ERROR "Should fail passed ${TRY_OUT}")
endif(SHOULD_FAIL)

# try to compile a file that should compile
try_compile(SHOULD_PASS
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
    ${TryCompile_SOURCE_DIR}/pass.c
    OUTPUT_VARIABLE TRY_OUT)
if(NOT SHOULD_PASS)
  message(SEND_ERROR "should pass failed ${TRY_OUT}")
endif(NOT SHOULD_PASS)

# try to compile a file that should not compile
try_compile(SHOULD_FAIL
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
    ${TryCompile_SOURCE_DIR}/fail.c
    OUTPUT_VARIABLE TRY_OUT)
if(SHOULD_FAIL)
   message(SEND_ERROR "Should fail passed ${TRY_OUT}")
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)
try_compile(CMAKE_ANSI_FOR_SCOPE
  ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
    ${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)

try_compile(CMAKE_ANSI_FOR_SCOPE
  ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
    ${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)

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)

message("Testing try_compile project mode")
try_compile(TEST_INNER
  ${TryCompile_BINARY_DIR}/CMakeFiles/Inner
  ${TryCompile_SOURCE_DIR}/Inner
  TryCompileInner innerexe
  OUTPUT_VARIABLE output)
TEST_ASSERT(TEST_INNER "try_compile project mode failed:\n${output}")

add_executable(TryCompile pass.c)

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

# now two tests for TRY_RUN

# try to run a file that should compile and run without error
# also check that OUTPUT_VARIABLE contains both the compile output
# and the run output
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")
# 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")

try_run(ARG_TEST_RUN ARG_TEST_COMPILE
    ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
    ${TryCompile_SOURCE_DIR}/expect_arg.c
    OUTPUT_VARIABLE TRY_OUT
    ARGS arg1 arg2)
if(NOT ARG_TEST_COMPILE)
  message(SEND_ERROR "expect_arg failed compiling: ${TRY_OUT}")
endif(NOT ARG_TEST_COMPILE)
if(NOT "${ARG_TEST_RUN}" STREQUAL "0")
  message(SEND_ERROR "expect_arg failed running with exit code ${ARG_TEST_RUN} ${TRY_OUT}")
endif(NOT "${ARG_TEST_RUN}" STREQUAL "0")

# 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
    COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
    RUN_OUTPUT_VARIABLE RUN_OUTPUT)

if(NOT SHOULD_COMPILE)
  message(STATUS " exit_with_error failed compiling: ${COMPILE_OUTPUT}")
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")

# 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")

#######################################################################
#
# 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")

foreach(lang C CXX)
  if(NOT "${CMAKE_${lang}_COMPILER_ID}" MATCHES "^(PathScale)$")
    set(${lang}_DD --)
  endif()
endforeach()

unset(C_BOGUS_FLAG CACHE)
include(CheckCCompilerFlag)
CHECK_C_COMPILER_FLAG(${C_DD}-_this_is_not_a_flag_ C_BOGUS_FLAG)
TEST_FAIL(C_BOGUS_FLAG "CHECK_C_COMPILER_FLAG() succeeded, but should have failed")

unset(CXX_BOGUS_FLAG CACHE)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${CXX_DD}-_this_is_not_a_flag_ CXX_BOGUS_FLAG)
TEST_FAIL(CXX_BOGUS_FLAG "CHECK_CXX_COMPILER_FLAG() succeeded, but should have failed")

if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
  unset(C_STRICT_PROTOTYPES CACHE)
  CHECK_C_COMPILER_FLAG("-Werror;-Wstrict-prototypes" C_STRICT_PROTOTYPES)
  TEST_ASSERT(C_STRICT_PROTOTYPES "CHECK_C_COMPILER_FLAG failed -Werror -Wstrict-prototypes")
endif()

#######################################################################
#
# also test that the check_prototype_definition macro works

include(CheckPrototypeDefinition)

check_prototype_definition(remove
  "int remove(const char *pathname)"
  "0"
  "stdio.h"
  TEST_REMOVE_PROTO)
test_assert(TEST_REMOVE_PROTO "check_prototype_definition for remove() failed")