forked from rdbo/libmem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
215 lines (186 loc) · 6.95 KB
/
CMakeLists.txt
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
cmake_minimum_required(VERSION 3.22.1)
include(ExternalProject)
project(libmem
LANGUAGES
C
CXX
ASM
)
message(STATUS
"[*] Platform: ${CMAKE_SYSTEM_NAME}"
)
option(LIBMEM_BUILD_TESTS
"Build tests"
OFF
)
option(LIBMEM_DEEP_TESTS
"Enable extra testing features for deep testing"
OFF
)
option(LIBMEM_BUILD_STATIC
"Build a static library"
OFF
)
set(LIBMEM_ARCH ${CMAKE_SYSTEM_PROCESSOR} CACHE STRING "Force a specific architecture")
message(STATUS
"[*] Architecture: ${LIBMEM_ARCH}"
)
message(STATUS
"[*] Build tests: ${LIBMEM_BUILD_TESTS}"
)
message(STATUS
"[*] Deep tests: ${LIBMEM_DEEP_TESTS}"
)
message(STATUS
"[*] Build static library: ${LIBMEM_BUILD_STATIC}"
)
message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
# External dependencies
set(EXTERNAL_DEPENDENCIES_DIR "${PROJECT_SOURCE_DIR}/external")
set(CAPSTONE_DIR "${EXTERNAL_DEPENDENCIES_DIR}/capstone")
set(CAPSTONE_INC "${CAPSTONE_DIR}/include")
set(CAPSTONE_IMPORT_DIR "${PROJECT_BINARY_DIR}/external/capstone-engine-prefix/src/capstone-engine-build")
set(KEYSTONE_DIR "${EXTERNAL_DEPENDENCIES_DIR}/keystone")
set(KEYSTONE_INC "${KEYSTONE_DIR}/include")
set(KEYSTONE_IMPORT_DIR "${PROJECT_BINARY_DIR}/external/keystone-engine-prefix/src/keystone-engine-build/llvm/lib")
set(LLVM_DIR "${EXTERNAL_DEPENDENCIES_DIR}/llvm")
set(LLVM_INC "${LLVM_DIR}/include")
add_subdirectory("${EXTERNAL_DEPENDENCIES_DIR}")
add_library(capstone STATIC IMPORTED)
set_target_properties(capstone PROPERTIES IMPORTED_LOCATION ${CAPSTONE_IMPORT_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}capstone${CMAKE_STATIC_LIBRARY_SUFFIX})
add_library(keystone STATIC IMPORTED)
set_target_properties(keystone PROPERTIES IMPORTED_LOCATION ${KEYSTONE_IMPORT_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}keystone${CMAKE_STATIC_LIBRARY_SUFFIX})
# End of external dependencies
set(LIBMEM_DIR "${PROJECT_SOURCE_DIR}")
set(LIBMEM_INC "${LIBMEM_DIR}/include")
set(INTERNAL_DIR "${LIBMEM_DIR}/internal")
set(COMMON_DIR "${LIBMEM_DIR}/src/common")
if(${CMAKE_SYSTEM_NAME} STREQUAL Windows OR ${CMAKE_SYSTEM_NAME} STREQUAL CYGWIN)
file(GLOB_RECURSE LIBMEM_SRC "${LIBMEM_DIR}/src/win/*.c" "${LIBMEM_DIR}/src/common/*.c" "${LIBMEM_DIR}/src/common/*.cpp" "${INTERNAL_DIR}/winutils/*.c" "${INTERNAL_DIR}/demangler/*.cpp")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
if(${LIBMEM_ARCH} STREQUAL x86_64)
set(LIBMEM_ARCH_SRC "${LIBMEM_DIR}/src/common/arch/x86.c" "${LIBMEM_DIR}/src/linux/ptrace/x64/*.c")
elseif(${LIBMEM_ARCH} STREQUAL i686 OR ${LIBMEM_ARCH} STREQUAL i386)
set(LIBMEM_ARCH_SRC "${LIBMEM_DIR}/src/common/arch/x86.c" "${LIBMEM_DIR}/src/linux/ptrace/x86/*.c")
endif()
file(GLOB LIBMEM_SRC ${LIBMEM_ARCH_SRC} "${LIBMEM_DIR}/src/linux/*.c" "${LIBMEM_DIR}/src/linux/ptrace/*.c" "${LIBMEM_DIR}/src/common/*.c" "${LIBMEM_DIR}/src/common/*.cpp" "${INTERNAL_DIR}/posixutils/*.c" "${INTERNAL_DIR}/elfutils/*.c" "${INTERNAL_DIR}/demangler/*.cpp")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
if(${LIBMEM_ARCH} STREQUAL x86_64 OR ${LIBMEM_ARCH} STREQUAL amd64)
set(LIBMEM_ARCH_SRC "${LIBMEM_DIR}/src/common/arch/x86.c" "${LIBMEM_DIR}/src/freebsd/ptrace/x64/*.c")
elseif(${LIBMEM_ARCH} STREQUAL i686 OR ${LIBMEM_ARCH} STREQUAL i386)
set(LIBMEM_ARCH_SRC "${LIBMEM_DIR}/src/common/arch/x86.c" "${LIBMEM_DIR}/src/freebsd/ptrace/x86/*.c")
endif()
file(GLOB LIBMEM_SRC ${LIBMEM_ARCH_SRC} "${LIBMEM_DIR}/src/freebsd/*.c" "${LIBMEM_DIR}/src/freebsd/ptrace/*.c" "${LIBMEM_DIR}/src/common/*.c" "${LIBMEM_DIR}/src/common/*.cpp" "${INTERNAL_DIR}/posixutils/*.c" "${INTERNAL_DIR}/elfutils/*.c" "${INTERNAL_DIR}/demangler/*.cpp")
endif()
set(LIBMEM_DEPS
capstone
keystone
llvm
)
if (LIBMEM_BUILD_STATIC)
add_library(libmem STATIC ${LIBMEM_SRC})
else()
add_library(libmem SHARED ${LIBMEM_SRC})
endif()
target_include_directories(libmem PRIVATE "${LIBMEM_DIR}/src" "${INTERNAL_DIR}" "${COMMON_DIR}")
include_directories(${PROJECT_SOURCE_DIR}
${LIBMEM_INC}
${CAPSTONE_INC}
${KEYSTONE_INC}
${LLVM_INC}
)
if (LIBMEM_BUILD_TESTS)
set(TESTS_DIR "${PROJECT_SOURCE_DIR}/tests")
add_subdirectory(${TESTS_DIR})
endif()
set_target_properties(libmem PROPERTIES POSITION_INDEPENDENT_CODE True INCLUDES ${LIBMEM_INC})
target_compile_definitions(libmem PUBLIC LM_EXPORT)
add_dependencies(libmem
capstone-engine
keystone-engine
)
if(${CMAKE_SYSTEM_NAME} STREQUAL Windows OR ${CMAKE_SYSTEM_NAME} STREQUAL CYGWIN)
set(LIBMEM_DEPS
${LIBMEM_DEPS}
user32
psapi
ntdll
shell32
)
target_compile_definitions(libmem PUBLIC alloca=_alloca)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Linux OR ${CMAKE_SYSTEM_NAME} STREQUAL Android)
set(LIBMEM_DEPS
${LIBMEM_DEPS}
dl
stdc++
m
)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
set(LIBMEM_DEPS
${LIBMEM_DEPS}
dl
kvm
procstat
elf
stdc++
m
)
else()
message(FATAL_ERROR "[!] Unsupported platform")
endif()
target_link_libraries(libmem ${LIBMEM_DEPS})
if(LIBMEM_BUILD_STATIC)
# Create a bundled static library containing all dependencies (to mimic the shared library behavior)
set_target_properties(libmem PROPERTIES OUTPUT_NAME "libmem_partial")
set(libmem_bundle_files "$<TARGET_FILE:libmem>")
get_target_property(libmem_link_libraries libmem LINK_LIBRARIES)
foreach(libmem_link_library IN LISTS libmem_link_libraries)
if(TARGET "${libmem_link_library}")
list(APPEND libmem_bundle_files "$<TARGET_FILE:${libmem_link_library}>")
endif()
endforeach()
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL CYGWIN)
file(WRITE "${CMAKE_BINARY_DIR}/liblibmem.ar.in" "CREATE liblibmem.a\n" )
foreach(libmem_bundle_file IN LISTS libmem_bundle_files)
file(APPEND "${CMAKE_BINARY_DIR}/liblibmem.ar.in" "ADDLIB ${libmem_bundle_file}\n")
endforeach()
file(APPEND "${CMAKE_BINARY_DIR}/liblibmem.ar.in" "SAVE\nEND\n")
file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/liblibmem.ar" INPUT "${CMAKE_BINARY_DIR}/liblibmem.ar.in")
add_custom_command(
TARGET libmem POST_BUILD
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMAND "${CMAKE_AR}" -M < "${CMAKE_BINARY_DIR}/liblibmem.ar"
COMMENT "Bundling liblibmem.a"
VERBATIM
)
elseif(MSVC)
find_program(LIB_EXECUTABLE lib)
add_custom_command(
TARGET libmem POST_BUILD
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMAND "${LIB_EXECUTABLE}" /NOLOGO /OUT:libmem.lib ${libmem_bundle_files}
COMMENT "Bundling libmem.lib"
VERBATIM
)
else()
message(WARNING "Static library bundling not supported on this platform")
endif()
endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL Windows OR ${CMAKE_SYSTEM_NAME} STREQUAL CYGWIN)
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL CYGWIN)
cmake_path(SET CMAKE_INSTALL_PREFIX "$ENV{ProgramFiles}")
else()
execute_process(COMMAND cygpath -u "$PROGRAMFILES"
OUTPUT_VARIABLE CMAKE_INSTALL_PREFIX)
endif()
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/libmem")
execute_process(COMMAND mkdir "${CMAKE_INSTALL_PREFIX}")
else()
set(CMAKE_INSTALL_PREFIX "/usr")
endif()
install(TARGETS libmem
LIBRARY DESTINATION lib)
install(TARGETS libmem
RUNTIME DESTINATION lib)
install(DIRECTORY ${LIBMEM_INC}/libmem DESTINATION include)