diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4949496..0ec61a2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,6 +5,9 @@ on: schedule: - cron: '0 1 * * 6' +env: + BUILD_TYPE: RelWithDebInfo + jobs: build: name: ${{ matrix.os }} @@ -14,8 +17,20 @@ jobs: os: [ubuntu-latest, windows-latest, macOS-latest] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 + - name: Compile run: make + - name: Test run: make test + + - name: Configure CMake + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + + - name: Build + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + + - name: Test + working-directory: ${{github.workspace}}/build + run: ctest -C ${{env.BUILD_TYPE}} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..813cb68 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,129 @@ +cmake_minimum_required(VERSION 3.13) + +# Allow CMake 3.13+ to override options when using FetchContent/add_subdirectory. +# option honors normal variables +if (POLICY CMP0077) + cmake_policy(SET CMP0077 NEW) +endif() + +# INTERFACE_LINK_LIBRARIES defines the link interface. +if (POLICY CMP0022) + cmake_policy (SET CMP0022 NEW) +endif() + +# PICT version, build, and product info +set(PICT_VERSION_MAJOR 3 CACHE STRING "PICT major version") +set(PICT_VERSION_MINOR 7 CACHE STRING "PICT minor version") +set(PICT_VERSION_BUILD 3 CACHE STRING "PICT build version") +set(PICT_VERSION_SHORT "${PICT_VERSION_MAJOR}.${PICT_VERSION_MINOR}") +set(PICT_VERSION_FULL "${PICT_VERSION_SHORT}.${PICT_VERSION_BUILD}") + +message(STATUS "PICT version ${PICT_VERSION_FULL}") + +# Set project name and properties +project( + PICT + DESCRIPTION "Pairwise Independent Combinatorial Tool" + HOMEPAGE_URL "https://github.com/microsoft/pict" + LANGUAGES CXX + VERSION ${PICT_VERSION_FULL} +) + +# Build configuration +option(PICT_RUN_TESTS_ENABLED "Enable running tests after build" ON) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +set(PICT_BUILD_OPTIONS PictBuildOptions) +add_library(${PICT_BUILD_OPTIONS} + INTERFACE +) + +if (MSVC) + # Enable multi-threaded build with MSVC + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + target_compile_options(${PICT_BUILD_OPTIONS} + INTERFACE + /W3 + ) + + target_compile_definitions(${PICT_BUILD_OPTIONS} + INTERFACE + UNICODE + WIN32_LEAN_AND_MEAN + ) +else() + target_compile_options(${PICT_BUILD_OPTIONS} + INTERFACE + -fPIC # Position-independent code: necessary for static libraries that are linked in dynamic libraries + -pipe + -fno-omit-frame-pointer + -fvisibility=hidden # By default, hide symbols on ELF binaries + -g # add debug symbols for build pdb + ) + + # AppleClang is not accepting -flto as linker option + if(NOT APPLE) + target_link_options(${PICT_BUILD_OPTIONS} + INTERFACE + $,,LINKER:-flto$-flto-partition=none> #Enable LTO + $,,LINKER:--no-undefined> # Have Linker error out if any symbols are undefined. + ) + endif() +endif() + +target_compile_definitions(${PICT_BUILD_OPTIONS} + INTERFACE + $,_DEBUG,NDEBUG> +) + +add_subdirectory (api) +add_subdirectory (cli) +add_subdirectory (clidll) + +if(PICT_RUN_TESTS_ENABLED) + enable_testing() + add_subdirectory(test) +endif() + +if(WIN32) + add_subdirectory(api-usage) + add_subdirectory(clidll-usage) +endif() + +if(WIN32) + set(CPACK_GENERATOR ZIP NUGET) +else() + set(CPACK_GENERATOR TGZ) +endif() + +set(CPACK_SOURCE_GENERATOR "TGZ") +set(CPACK_SOURCE_IGNORE_FILES + \\.git/ + build/ + ".*~$" +) +set(CPACK_VERBATIM_VARIABLES YES) + +execute_process( + COMMAND git log --pretty=format:%H -n 1 + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +execute_process( + COMMAND git log --pretty=format:%h -n 1 + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_SHORT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +set(CPACK_SOURCE_PACKAGE_FILE_NAME + ${CMAKE_PROJECT_NAME}-${GIT_SHORT_COMMIT_HASH} +) + +include(CPack) diff --git a/README.md b/README.md index c73a814..88a204c 100644 --- a/README.md +++ b/README.md @@ -42,13 +42,14 @@ The test script produces a log: **dbg.log** or **rel.log** for the Debug and Rel >There are tests which randomize output which typically make it different on each run. These results should be masked in the baseline but currently aren't. -## Building with clang++ on Linux, OS/X, *BSD, etc. -Install clang through your package manager (most systems), Xcode (OS/X), or from the [LLVM website](http://llvm.org/releases/). -On Linux, you also need to install recent GNU's "libstdc++" or LLVM's "libc++". - -Run `make` to build the `pict` binary. - -Run `make test` to run the tests as described above (requires Perl). +## Building on Linux, OS/X, *BSD, etc. +PICT uses CMake to build on Linux. +Assuming installation of CMake and C++ toolchain, following set of commands will build and run tests in the directory `build` +``` +> cmake -DCMAKE_BUILD_TYPE=Release -S . -B build +> cmake --build build +> pushd build && ctest -v && popd +``` ## Debugging diff --git a/api-usage/CMakeLists.txt b/api-usage/CMakeLists.txt new file mode 100644 index 0000000..9cf1d37 --- /dev/null +++ b/api-usage/CMakeLists.txt @@ -0,0 +1,32 @@ +set(target_name + pict_api_usage +) + +set(pict_api_usage_output + pictapisamples +) + +set(pict_api_usage_src + ${CMAKE_CURRENT_SOURCE_DIR}/pictapi-sample.cpp +) + +add_executable(${target_name} + ${pict_api_usage_src} +) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${pict_api_usage_src} +) + +target_link_libraries(${target_name} + PRIVATE + PictBuildOptions + pict_api +) + +set_target_properties(${target_name} + PROPERTIES + FOLDER api-usage + OUTPUT_NAME ${pict_api_usage_output} +) diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt new file mode 100644 index 0000000..e618acd --- /dev/null +++ b/api/CMakeLists.txt @@ -0,0 +1,56 @@ +set(target_name + pict_api +) + +set(pict_api_output + pict +) + +set(pict_api_inc + ${CMAKE_CURRENT_SOURCE_DIR}/deriver.h + ${CMAKE_CURRENT_SOURCE_DIR}/generator.h + ${CMAKE_CURRENT_SOURCE_DIR}/pictapi.h + ${CMAKE_CURRENT_SOURCE_DIR}/resource.h + ${CMAKE_CURRENT_SOURCE_DIR}/trie.h +) + +set(pict_api_src + ${CMAKE_CURRENT_SOURCE_DIR}/combination.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/deriver.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/exclusion.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/model.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/parameter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/pictapi.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/task.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/worklist.cpp +) + +add_library(${target_name} + STATIC + ${pict_api_inc} + ${pict_api_src} +) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${pict_api_inc} + ${pict_api_src} +) + +target_include_directories(${target_name} + INTERFACE + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_link_libraries(${target_name} + PRIVATE + PictBuildOptions +) + +set_target_properties(${target_name} + PROPERTIES + FOLDER src + OUTPUT_NAME ${pict_api_output} +) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt new file mode 100644 index 0000000..e849625 --- /dev/null +++ b/cli/CMakeLists.txt @@ -0,0 +1,83 @@ +include(GNUInstallDirs) + +set(target_name + pict_cli +) + +set(pict_cli_output + pict +) + +set(pict_cli_inc + ${CMAKE_CURRENT_SOURCE_DIR}/ccommon.h + ${CMAKE_CURRENT_SOURCE_DIR}/cmdline.h + ${CMAKE_CURRENT_SOURCE_DIR}/common.h + ${CMAKE_CURRENT_SOURCE_DIR}/cparser.h + ${CMAKE_CURRENT_SOURCE_DIR}/ctokenizer.h + ${CMAKE_CURRENT_SOURCE_DIR}/gcd.h + ${CMAKE_CURRENT_SOURCE_DIR}/gcdexcl.h + ${CMAKE_CURRENT_SOURCE_DIR}/gcdmodel.h + ${CMAKE_CURRENT_SOURCE_DIR}/model.h + ${CMAKE_CURRENT_SOURCE_DIR}/resource.h + ${CMAKE_CURRENT_SOURCE_DIR}/strings.h + ${CMAKE_CURRENT_SOURCE_DIR}/ver.h +) + +set(pict_cli_src + ${CMAKE_CURRENT_SOURCE_DIR}/ccommon.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/cmdline.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/common.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/cparser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ctokenizer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/gcd.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/gcdexcl.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/gcdmodel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/model.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mparser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/pict.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/strings.cpp +) + +set(pict_cli_dll_src + ${pict_cli_src} PARENT_SCOPE +) + +set(pict_cli_rc + $<$:${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc> +) + +add_executable(${target_name} + ${pict_cli_inc} + ${pict_cli_src} + ${pict_cli_rc} +) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${pict_cli_inc} + ${pict_cli_src} +) + +target_link_libraries(${target_name} + PRIVATE + PictBuildOptions + pict_api +) + +set_target_properties(${target_name} + PROPERTIES + FOLDER src + OUTPUT_NAME ${pict_cli_output} +) + +install( + PROGRAMS $ + TYPE BIN +) + +install( + FILES + ${CMAKE_SOURCE_DIR}/doc/pict.md + ${CMAKE_SOURCE_DIR}/LICENSE.TXT + TYPE DOC +) diff --git a/clidll-usage/CMakeLists.txt b/clidll-usage/CMakeLists.txt new file mode 100644 index 0000000..94f4953 --- /dev/null +++ b/clidll-usage/CMakeLists.txt @@ -0,0 +1,32 @@ +set(target_name + pict_dll_usage +) + +set(pict_dll_usage_output + pictclidllusage +) + +set(pict_dll_usage_src + ${CMAKE_CURRENT_SOURCE_DIR}/pictclidll-sample.cpp +) + +add_executable(${target_name} + ${pict_dll_usage_src} +) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${pict_dll_usage_src} +) + +target_link_libraries(${target_name} + PRIVATE + PictBuildOptions + pict_dll +) + +set_target_properties(${target_name} + PROPERTIES + FOLDER clidll-usage + OUTPUT_NAME ${pict_dll_usage_output} +) diff --git a/clidll/CMakeLists.txt b/clidll/CMakeLists.txt new file mode 100644 index 0000000..5545659 --- /dev/null +++ b/clidll/CMakeLists.txt @@ -0,0 +1,47 @@ +set(target_name + pict_dll +) + +set(pict_dll_output + pict +) + +set(pict_dll_inc + ${CMAKE_CURRENT_SOURCE_DIR}/resource.h +) + +set(pict_dll_src + ${CMAKE_CURRENT_SOURCE_DIR}/dllmain.cpp + $<$:${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/pictclidll.def> +) + +add_library(${target_name} + SHARED + ${pict_dll_inc} + ${pict_dll_src} + ${pict_cli_dll_src} +) + +add_compile_definitions(${target_name} + PRIVATE + PICTCLIDLL_EXPORTS +) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} + FILES + ${pict_dll_inc} + ${pict_dll_src} +) + +target_link_libraries(${target_name} + PRIVATE + PictBuildOptions + pict_api +) + +set_target_properties(${target_name} + PROPERTIES + FOLDER src + OUTPUT_NAME ${pict_dll_output} +) diff --git a/clidll/dllmain.cpp b/clidll/dllmain.cpp index d8b5f32..1ea5a22 100644 --- a/clidll/dllmain.cpp +++ b/clidll/dllmain.cpp @@ -1,3 +1,4 @@ +#if defined(_WIN32) #include "windows.h" BOOL APIENTRY DllMain( HMODULE hModule, @@ -15,3 +16,4 @@ BOOL APIENTRY DllMain( HMODULE hModule, } return TRUE; } +#endif // defined(_WIN32) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..627da53 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,5 @@ +add_test( + NAME run_pict + COMMAND perl test.pl $ $,dbg,rel>.log + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +)