diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..34bff19 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.15) + +project(Crinkler LANGUAGES CXX RC) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +# Cache option defaults +set(DOWNLOAD_NASM OFF CACHE BOOL "Download nasm if not present.") +set(NASM_PATH "${PROJECT_BINARY_DIR}/downloads/nasm-2.15.05-win32/" CACHE PATH "Search path for nasm.") + +# Download nasm if configured in cache and not present. +find_program(NASM NAMES nasm.exe HINTS "${NASM_PATH}/nasm-2.15.05/" "${NASM_PATH}") +if(${NASM} MATCHES NASM-NOTFOUND AND DOWNLOAD_NASM) + set(NASM_URL "https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/win32/nasm-2.15.05-win32.zip") + set(NASM_ARCHIVE_FILE "${CMAKE_CURRENT_BINARY_DIR}/downloads/nasm-2.15.05-win32.zip") + find_file(NASM_ARCHIVE NAMES nasm-2.15.05-win32.zip HINTS "${CMAKE_CURRENT_BINARY_DIR}/downloads/") + if(${NASM_ARCHIVE} MATCHES NASM_ARCHIVE-NOTFOUND) + message(STATUS "Downloading nasm from ${NASM_URL}...") + file(DOWNLOAD ${NASM_URL} ${NASM_ARCHIVE_FILE} SHOW_PROGRESS) + endif() + file(ARCHIVE_EXTRACT INPUT ${NASM_ARCHIVE_FILE} DESTINATION "${NASM_PATH}") + find_program(NASM NAMES nasm.exe HINTS "${NASM_PATH}/nasm-2.15.05/") +endif() +message(STATUS "Found nasm: ${NASM}") + +# Build-type-dependent configuration +add_compile_definitions(WIN32 _WINDOWS _USRDLL COMPRESSOR_EXPORTS) +if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + add_compile_definitions(_DEBUG D3D_DEBUG_INFO) +elseif(${CMAKE_BUILD_TYPE} MATCHES "Release") + add_compile_definitions(NDEBUG _CRT_SECURE_NO_DEPRECATE) +endif() + +# Architecture-dependent configuration +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + link_directories("${PROJECT_SOURCE_DIR}/external/distorm/x64/") + set(NASM_OPTIONS -fwin64) +elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + link_directories("${PROJECT_SOURCE_DIR}/external/distorm/x86/") + set(NASM_OPTIONS -fwin32) +endif() +set(NASM_OPTIONS ${NASM_OPTIONS} -Xvc) + +# Ingredients +add_subdirectory(source/Compressor) +add_subdirectory(source/CompressorExample) +add_subdirectory(source/Crinkler) +add_subdirectory(source/ExportScraper) diff --git a/README.md b/README.md index 40ac834..0ccda9c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,16 @@ Crinkler is mainly being developed by Rune L. H. Stubbe (Mentor/TBC) and Aske Si You are welcome to integrate Crinkler into your own tools or toolchains. If you do so, preferably base your work on a commit tagged by a release version. This way, the Crinkler version identifier written into output executables (two digits at offset 2 in the file) will match the actual contents produced by Crinkler. ## Building +Build Crinkler using Visual Studio 2017 or later. -Build Crinkler using Visual Studio 2017 or later. The custom build rules for the assembly files require that `nasmw.exe` is in the executable path. +### MSBuild +The custom build rules for the assembly files require that `nasmw.exe` is in the executable path. The data compressor itself is separated out into its own library, located in the `Compressor` project. This library enables tools to estimate how big a particular piece of data would be after being compressed by Crinkler. Take a look at the `CompressorExample` project for a description of its usage. + +### CMake +If the location of `nasm.exe` is not in the `PATH` variable, CMake requires you to either specify a nasm executable path using `-DNASM_PATH=/path/to/your/nasm` or letting it download nasm automatically using `-DDOWNLOAD_NASM=ON`. + +You can select different build types by supplying `-DCMAKE_BUILD_TYPE=Release` or `-DCMAKE_BUILD_TYPE=Debug`. + +Select the target architecture by using `-A Win32` or `-A x64`. diff --git a/source/Compressor/CMakeLists.txt b/source/Compressor/CMakeLists.txt new file mode 100644 index 0000000..b323726 --- /dev/null +++ b/source/Compressor/CMakeLists.txt @@ -0,0 +1,19 @@ +set(COMPRESSOR_CXX_SOURCES + AritCode.cpp + CompressionState.cpp + CompressionStream.cpp + Compressor.cpp + CounterState.cpp + ModelList.cpp + Model.cpp + CompressionStateEvaluator.cpp +) + +set_source_files_properties(log_table.obj PROPERTIES EXTERNAL_OBJECT true GENERATED true) + +add_library(Compressor ${COMPRESSOR_CXX_SOURCES} log_table.obj) + +add_custom_command(TARGET Compressor PRE_BUILD BYPRODUCTS log_table.obj + COMMAND ${NASM} ${CMAKE_CURRENT_SOURCE_DIR}/log_table.asm ${NASM_OPTIONS} -o log_table.obj + COMMENT "Assembling log_table.asm..." +) diff --git a/source/CompressorExample/CMakeLists.txt b/source/CompressorExample/CMakeLists.txt new file mode 100644 index 0000000..8aee869 --- /dev/null +++ b/source/CompressorExample/CMakeLists.txt @@ -0,0 +1,2 @@ +add_executable(CompressorExample main.cpp) +target_link_libraries(CompressorExample Compressor) diff --git a/source/Crinkler/CMakeLists.txt b/source/Crinkler/CMakeLists.txt new file mode 100644 index 0000000..791bec9 --- /dev/null +++ b/source/Crinkler/CMakeLists.txt @@ -0,0 +1,93 @@ +set(CRINKLER_CXX_SOURCES + ExplicitHunkSorter.cpp + Export.cpp + Fix.cpp + HtmlReport.cpp + Hunk.cpp + HunkList.cpp + ImportHandler.cpp + LTCGLoader.cpp + main.cpp + Reuse.cpp + Symbol.cpp + Log.cpp + MemoryFile.cpp + MiniDump.cpp + Misc.cpp + NameMangling.cpp + StringMisc.cpp + CmdLineInterface/CmdLineInterface.cpp + CmdLineInterface/CmdParam.cpp + CmdLineInterface/CmdParamFlags.cpp + CmdLineInterface/CmdParamInt.cpp + CmdLineInterface/CmdParamMultiAssign.cpp + CmdLineInterface/CmdParamString.cpp + CmdLineInterface/CmdParamSwitch.cpp + CoffLibraryLoader.cpp + CoffObjectLoader.cpp + HunkLoader.cpp + MultiLoader.cpp + EmpiricalHunkSorter.cpp + HeuristicHunkSorter.cpp + CallTransform.cpp + Transform.cpp + CompositeProgressBar.cpp + ConsoleProgressBar.cpp + WindowProgressBar.cpp + Crinkler.cpp + + Crinkler.rc +) + +set_source_files_properties(Crinkler.rc LANGUAGE RC) + +set(CRINKLER_ASM_SOURCES + modules/calltrans.asm + modules/header20.asm + modules/header20_compatibility.asm + modules/header22_1k.asm + modules/import20.asm + modules/import20_1k.asm +) + +set(DATA_OBJECT_FILES + calltrans.obj + header20.obj + header20_compatibility.obj + header22_1k.obj + import20.obj + import20-range.obj + import20-safe.obj + import20-safe-range.obj + import20-safe-fallback.obj + import20-safe-fallback-range.obj + import20_1k.obj + runtime.obj +) +set_source_files_properties(${DATA_OBJECT_FILES} PROPERTIES EXTERNAL_OBJECT true GENERATED true) +set_source_files_properties(data.obj PROPERTIES EXTERNAL_OBJECT true GENERATED true) + +add_executable(Crinkler ${CRINKLER_CXX_SOURCES} data.obj) +target_link_libraries(Crinkler Compressor distorm Dbghelp comctl32) + +add_custom_command(TARGET Crinkler PRE_BUILD BYPRODUCTS ${DATA_OBJECT_FILES} + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/calltrans.asm" ${NASM_OPTIONS} -o calltrans.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/header20.asm" ${NASM_OPTIONS} -o header20.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/header20.asm" ${NASM_OPTIONS} -o header20.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/header20_compatibility.asm" ${NASM_OPTIONS} -o header20_compatibility.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/header22_1k.asm" ${NASM_OPTIONS} -o header22_1k.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/import20.asm" ${NASM_OPTIONS} -o import20.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/import20.asm" -dIMPORT_RANGE ${NASM_OPTIONS} -o import20-range.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/import20.asm" -dIMPORT_SAFE ${NASM_OPTIONS} -o import20-safe.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/import20.asm" -dIMPORT_SAFE -dIMPORT_RANGE ${NASM_OPTIONS} -o import20-safe-range.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/import20.asm" -dIMPORT_SAFE -dIMPORT_FALLBACK ${NASM_OPTIONS} -o import20-safe-fallback.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/import20.asm" -dIMPORT_SAFE -dIMPORT_FALLBACK -dIMPORT_RANGE ${NASM_OPTIONS} -o import20-safe-fallback-range.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/import20_1k.asm" ${NASM_OPTIONS} -o import20_1k.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/modules/runtime.asm" ${NASM_OPTIONS} -o runtime.obj + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/known_dll_exports.dat" "${CMAKE_CURRENT_BINARY_DIR}/known_dll_exports.dat" + COMMENT "Assembling ${CRINKLER_ASM_SOURCES}..." +) + +add_custom_command(TARGET Crinkler PRE_BUILD BYPRODUCTS data.obj + COMMAND ${NASM} "${CMAKE_CURRENT_SOURCE_DIR}/data.asm" -dPATH="${CMAKE_CURRENT_BINARY_DIR}/" ${NASM_OPTIONS} -o data.obj +) diff --git a/source/ExportScraper/CMakeLists.txt b/source/ExportScraper/CMakeLists.txt new file mode 100644 index 0000000..78df257 --- /dev/null +++ b/source/ExportScraper/CMakeLists.txt @@ -0,0 +1 @@ +add_executable(ExportScraper main.cpp)