summaryrefslogtreecommitdiff
path: root/Tests/RunCMake/PrecompileHeaders/PchReuseFromObjLib.cmake
blob: ba504a3ef30007d2f425e62babe00b3d4c5fc133 (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
cmake_minimum_required(VERSION 3.18)

project(PchReuseFromObjLib)

set(CMAKE_PCH_WARN_INVALID OFF)

if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
  add_definitions(-DHAVE_PCH_SUPPORT)
endif()

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

file(WRITE ${CMAKE_BINARY_DIR}/CONFIG/config.hxx "/*empty*/\n")

file(WRITE ${CMAKE_BINARY_DIR}/pch.cxx [=[
void nothing()
{
}
]=])

file(WRITE ${CMAKE_BINARY_DIR}/string.hxx [=[
#include <string.h>

namespace std {
  struct string
  {
    char storage[20];

    string(const char* s) {
      strcpy(storage, s);
    }

    const char* c_str() const {
      return storage;
    }
  };
}
]=])

add_library(pch-generator OBJECT ${CMAKE_BINARY_DIR}/pch.cxx)
set_property(TARGET pch-generator PROPERTY POSITION_INDEPENDENT_CODE ON)
target_precompile_headers(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/string.hxx)

target_include_directories(pch-generator PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)

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

file(WRITE ${CMAKE_BINARY_DIR}/message.cxx [=[
#include "message.hxx"

#ifndef HAVE_PCH_SUPPORT
  #include "string.hxx"
#endif

const char* message()
{
  static std::string greeting("hi there");
  return greeting.c_str();
}
]=])

file(WRITE ${CMAKE_BINARY_DIR}/message.hxx [=[
#include "config.hxx"
#ifdef WIN32_BUILD_SHARED
  #ifdef BUILD_LIBRARY
    #define MESSAGE_EXPORT __declspec(dllexport)
  #else
    #define MESSAGE_EXPORT __declspec(dllimport)
  #endif
#else
  #define MESSAGE_EXPORT
#endif

MESSAGE_EXPORT const char* message();
]=])

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

file(WRITE ${CMAKE_BINARY_DIR}/main.cxx [=[
#include "message.hxx"
#include <string.h>

int main()
{
  return strcmp(message(), "hi there");
}
]=])

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

enable_testing()

function(add_library_and_executable type)
  add_library(message_${type} ${type} ${CMAKE_BINARY_DIR}/message.cxx)
  target_precompile_headers(message_${type} REUSE_FROM pch-generator)

  set_property(TARGET message_${type} PROPERTY POSITION_INDEPENDENT_CODE ON)
  set_property(TARGET message_${type} PROPERTY DEFINE_SYMBOL "")

  if (WIN32 AND type STREQUAL "SHARED")
    file(WRITE ${CMAKE_BINARY_DIR}/SHARED/config.hxx [=[
      #define BUILD_LIBRARY
      #define WIN32_BUILD_SHARED
    ]=])
    target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/SHARED)

    # Workaround for VS2008, the compiler fails with
    # c1xx : fatal error C1083: Cannot open source file: '_WINDLL': No such file or directory
    file(WRITE ${CMAKE_BINARY_DIR}/_WINDLL "/*empty*/\n")
  else()
    target_include_directories(message_${type} PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
  endif()

  add_executable(main_${type} ${CMAKE_BINARY_DIR}/main.cxx)
  target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR})

  if (WIN32 AND type STREQUAL "SHARED")
    file(WRITE ${CMAKE_BINARY_DIR}/main_SHARED/config.hxx "#define WIN32_BUILD_SHARED\n")
    target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR}/main_SHARED)
  else()
    target_include_directories(main_${type} PRIVATE ${CMAKE_BINARY_DIR}/CONFIG)
  endif()

  target_link_libraries(main_${type} PRIVATE message_${type})

  add_test(NAME main_${type} COMMAND main_${type})
endfunction()

foreach(type OBJECT STATIC SHARED)
  add_library_and_executable(${type})
endforeach()