cmake_minimum_required(VERSION 3.15) ## # Usage # ===== # # This section provides some brief instructions on how to compile, test, and # install GLPK using CMake. Although currently configured only for use on # Windows, the config can be extended to support *nix systems as well. # # Note: # # This file can be split up into smaller .cmake files if desired. It is a few # hundred lines long unfortunately in large part since the sources are all # listed explicitly instead of using globs and because of the install logic. # # Windows # ------- # # The following items are values to be determined by the user. They are used in # the build commands enclosed in brackets to distinguish them. # # Arch: Win32, x64 # Config: Debug, Release # Prefix: (desired install root) # # Building # ~~~~~~~~ # # Build static linking against C runtime dynamically + also build examples: # # cmake -S . -B build_windows_[Arch] -A [Arch] # cmake --build build_windows_[Arch] --config [Config] -j # # Build dynamic linking against C runtime statically + no examples: # # cmake -S . -B build_windows_[Arch] -A [Arch] -DBUILD_SHARED_LIBS=ON ^ # -DGLPK_USE_STATIC_CRT=ON -DGLPK_BUILD_EXAMPLES=OFF # cmake --build build_windows_[Arch] --config [Config] -j # # Build dynamic linking against C runtime dynamically + also build examples # while installing with multi-configuration install tree: # # cmake -S . -B build_windows_[Arch] -A [Arch] -DBUILD_SHARED_LIBS=ON ^ # -DGLPK_INSTALL_MULTI_CONFIG=ON # cmake --build build_windows_[Arch] --config [Config] -j # # Testing # ~~~~~~~ # # ctest --test-dir build_windows_[Arch] -C [Config] -j # # Install # ~~~~~~~ # # cmake --install build_windows_[Arch] --prefix [Prefix] --config [Config] # # If GLPK_INSTALL_MULTI_CONFIG is specified, and assuming that we are building # shared libraries, the install tree looks like this: # # install_root/ # bin/ # Debug/ # glpk.dll # glpsol.exe # Release/ # glpk.dll # glpsol.exe # include/ # glpk.h # lib/ # Debug/ # glpk.lib # glpk.pdb # Release/ # glpk.lib # # Otherwise, we have a flat install with "d" suffices, e.g. # # install_root/ # bin/ # glpk.dll # glpkd.dll # glpsol.exe # glpsold.exe # include/ # glpk.h # lib/ # glpk.lib # glpkd.lib # glpkd.pdb # # GLPK version set(GLPK_VERSION_MAJOR 5) set(GLPK_VERSION_MINOR 0) set(GLPK_VERSION ${GLPK_VERSION_MAJOR}.${GLPK_VERSION_MINOR}) project( glpk VERSION 5.0 DESCRIPTION "GNU Linear Programming Kit" HOMEPAGE_URL "https://www.gnu.org/software/glpk/" LANGUAGES C ) # select static/shared library compilation option(BUILD_SHARED_LIBS "Build GLPK library as shared" OFF) # use static C runtime library. defaulted to OFF to match the CMake default of # using MultiThreaded$<$:Debug>DLL to select dynamic C runtime. # see https://cmake.org/cmake/help/latest/prop_tgt/MSVC_RUNTIME_LIBRARY.html, # https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features option(GLPK_USE_STATIC_CRT "Link against C runtime statically" OFF) # to separate Debug and Release libraries, which also link against debug and # release C runtimes respectively (should never be mixed), add an extra layer # of namespacing to lib and bin, e.g. lib/Debug, bin/Release, etc. for MSVC, if # this is not specified, debug libraries + PDB is suffixed with "d" option(GLPK_INSTALL_MULTI_CONFIG OFF) # build example programs option(GLPK_BUILD_EXAMPLES "Build the GLPK example programs" ON) # only available for Windows currently if(NOT WIN32) message(FATAL_ERROR "CMake config is currently only usable for Windows") endif() # enable testing via ctest include(CTest) # check if multi-config or not get_property(GLPK_BUILD_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(GLPK_BUILD_MULTI_CONFIG) message(STATUS "Build generator: Multi-config") else() message(STATUS "Build generator: Single-config") endif() # static/shared library build if(BUILD_SHARED_LIBS) message(STATUS "GLPK build: Shared") else() message(STATUS "GLPK build: Static") endif() # link statically against C runtime library if requested if(WIN32) if(GLPK_USE_STATIC_CRT) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") message(STATUS "UCRT linkage: Static") # link dynamically. this is the default but we set this explicitly else() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") message(STATUS "UCRT linkage: Shared") endif() endif() # multi-config installation (only for MSVC) if(MSVC AND GLPK_INSTALL_MULTI_CONFIG) message(STATUS "Installation: Multi") else() message(STATUS "Installation: Flat") endif() # example programs if(GLPK_BUILD_EXAMPLES) message(STATUS "Build examples: No") else() message(STATUS "Build examples: Yes") endif() # examples directory absolute path set(GLPK_EXAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/examples) # check if generating 32- or 64-bit code if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(GLPK_TARGET_64 ON) set(GLPK_TARGET_32 OFF) message(STATUS "Architecture: 64-bit") elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) set(GLPK_TARGET_64 OFF) set(GLPK_TARGET_32 ON) message(STATUS "Architecture: 32-bit") else() message(FATAL_ERROR "Incompatible pointer size, must be 8 or 4 bytes") endif() # compile flags if(MSVC) # TODO: increase warning level later? e.g. /W4, /Wall add_compile_definitions(HAVE_CONFIG_H _CRT_SECURE_NO_WARNINGS) add_compile_options(/W3) else() # TODO: fill in for *nix endif() # include directories include_directories( src src/amd src/api src/bflib src/colamd src/draft src/env src/intopt src/minisat src/misc src/mpl src/npp src/proxy src/simplex src/zlib ) # add w32 or w64 as include for config.h appropriately if(GLPK_TARGET_64) include_directories(w64) set(GLPK_CONFIG_H_DIR ${CMAKE_CURRENT_SOURCE_DIR}/w64) message(STATUS "config.h from: w64") else() include_directories(w32) set(GLPK_CONFIG_H_DIR ${CMAKE_CURRENT_SOURCE_DIR}/w32) message(STATUS "config.h from: w32") endif() # build GLPK library. maybe use wildcards? add_library( glpk src/amd/amd_1.c src/amd/amd_2.c src/amd/amd_aat.c src/amd/amd_control.c src/amd/amd_defaults.c src/amd/amd_dump.c src/amd/amd_info.c src/amd/amd_order.c src/amd/amd_post_tree.c src/amd/amd_postorder.c src/amd/amd_preprocess.c src/amd/amd_valid.c src/api/advbas.c src/api/asnhall.c src/api/asnlp.c src/api/asnokalg.c src/api/ckasn.c src/api/ckcnf.c src/api/cplex.c src/api/cpp.c src/api/cpxbas.c src/api/graph.c src/api/gridgen.c src/api/intfeas1.c src/api/maxffalg.c src/api/maxflp.c src/api/mcflp.c src/api/mcfokalg.c src/api/mcfrelax.c src/api/minisat1.c src/api/mpl.c src/api/mps.c src/api/netgen.c src/api/npp.c src/api/pript.c src/api/prmip.c src/api/prob1.c src/api/prob2.c src/api/prob3.c src/api/prob4.c src/api/prob5.c src/api/prrngs.c src/api/prsol.c src/api/rdasn.c src/api/rdcc.c src/api/rdcnf.c src/api/rdipt.c src/api/rdmaxf.c src/api/rdmcf.c src/api/rdmip.c src/api/rdprob.c src/api/rdsol.c src/api/rmfgen.c src/api/strong.c src/api/topsort.c src/api/weak.c src/api/wcliqex.c src/api/wrasn.c src/api/wrcc.c src/api/wrcnf.c src/api/wript.c src/api/wrmaxf.c src/api/wrmcf.c src/api/wrmip.c src/api/wrprob.c src/api/wrsol.c src/bflib/btf.c src/bflib/btfint.c src/bflib/fhv.c src/bflib/fhvint.c src/bflib/ifu.c src/bflib/luf.c src/bflib/lufint.c src/bflib/scf.c src/bflib/scfint.c src/bflib/sgf.c src/bflib/sva.c src/colamd/colamd.c src/draft/bfd.c src/draft/bfx.c src/draft/glpapi06.c src/draft/glpapi07.c src/draft/glpapi08.c src/draft/glpapi09.c src/draft/glpapi10.c src/draft/glpapi12.c src/draft/glpapi13.c src/draft/glpios01.c src/draft/glpios02.c src/draft/glpios03.c src/draft/glpios07.c src/draft/glpios09.c src/draft/glpios11.c src/draft/glpios12.c src/draft/glpipm.c src/draft/glpmat.c src/draft/glpscl.c src/draft/glpssx01.c src/draft/glpssx02.c src/draft/lux.c src/env/alloc.c src/env/dlsup.c src/env/env.c src/env/error.c src/env/stdc.c src/env/stdout.c src/env/stream.c src/env/time.c src/env/tls.c src/intopt/cfg.c src/intopt/cfg1.c src/intopt/cfg2.c src/intopt/clqcut.c src/intopt/covgen.c src/intopt/fpump.c src/intopt/gmicut.c src/intopt/gmigen.c src/intopt/mirgen.c src/intopt/spv.c src/minisat/minisat.c src/misc/avl.c src/misc/bignum.c src/misc/dimacs.c src/misc/dmp.c src/misc/ffalg.c src/misc/fp2rat.c src/misc/fvs.c src/misc/gcd.c src/misc/hbm.c src/misc/jd.c src/misc/keller.c src/misc/ks.c src/misc/mc13d.c src/misc/mc21a.c src/misc/mt1.c src/misc/mygmp.c src/misc/okalg.c src/misc/qmd.c src/misc/relax4.c src/misc/rgr.c src/misc/rng.c src/misc/rng1.c src/misc/round2n.c src/misc/spm.c src/misc/str2int.c src/misc/str2num.c src/misc/strspx.c src/misc/strtrim.c src/misc/triang.c src/misc/wclique.c src/misc/wclique1.c src/mpl/mpl1.c src/mpl/mpl2.c src/mpl/mpl3.c src/mpl/mpl4.c src/mpl/mpl5.c src/mpl/mpl6.c src/mpl/mplsql.c src/npp/npp1.c src/npp/npp2.c src/npp/npp3.c src/npp/npp4.c src/npp/npp5.c src/npp/npp6.c src/proxy/proxy.c src/proxy/proxy1.c src/simplex/spxat.c src/simplex/spxchuzc.c src/simplex/spxchuzr.c src/simplex/spxlp.c src/simplex/spxnt.c src/simplex/spxprim.c src/simplex/spxprob.c src/simplex/spychuzc.c src/simplex/spychuzr.c src/simplex/spydual.c src/zlib/adler32.c src/zlib/compress.c src/zlib/crc32.c src/zlib/deflate.c src/zlib/gzclose.c src/zlib/gzlib.c src/zlib/gzread.c src/zlib/gzwrite.c src/zlib/inffast.c src/zlib/inflate.c src/zlib/inftrees.c src/zlib/trees.c src/zlib/uncompr.c src/zlib/zio.c src/zlib/zutil.c ) # config.h copying from config_VC. w32 and w64 are same but we choose add_custom_command( TARGET glpk PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLPK_CONFIG_H_DIR}/config_VC ${GLPK_CONFIG_H_DIR}/config.h COMMENT "Copying config_VC to config.h" VERBATIM ) # glpk.h is the public header set_target_properties(glpk PROPERTIES PUBLIC_HEADER src/glpk.h) # if not using multi-config install, suffix "d" to glpk if(MSVC AND NOT GLPK_INSTALL_MULTI_CONFIG) set_target_properties(glpk PROPERTIES OUTPUT_NAME glpk$<$:d>) endif() # build glpsol add_executable(glpsol examples/glpsol.c) target_link_libraries(glpsol PRIVATE glpk) # if not using multi-config install, suffix "d" to glpsol if(MSVC AND NOT GLPK_INSTALL_MULTI_CONFIG) set_target_properties(glpsol PROPERTIES OUTPUT_NAME glpsol$<$:d>) endif() # build examples if(GLPK_BUILD_EXAMPLES) add_executable(iptsamp examples/iptsamp.c) target_link_libraries(iptsamp PRIVATE glpk) add_executable(mplsamp1 examples/mplsamp1.c) target_link_libraries(mplsamp1 PRIVATE glpk) add_executable(mplsamp2 examples/mplsamp2.c) target_link_libraries(mplsamp2 PRIVATE glpk) # aborts since glp_netgen disabled due to licensing problems # add_executable(netgen examples/netgen.c) # target_link_libraries(netgen PRIVATE glpk) add_executable(nppsamp examples/nppsamp.c) target_link_libraries(nppsamp PRIVATE glpk) add_executable(sample examples/sample.c) target_link_libraries(sample PRIVATE glpk) add_executable(spxsamp1 examples/spxsamp1.c) target_link_libraries(spxsamp1 PRIVATE glpk) add_executable(spxsamp2 examples/spxsamp2.c) target_link_libraries(spxsamp2 PRIVATE glpk) endif() # add glpsol as ctest test add_test(NAME "glpsol_version" COMMAND glpsol --version) add_test( NAME "glpsol_murtagh" COMMAND glpsol --mps ${CMAKE_CURRENT_SOURCE_DIR}/examples/murtagh.mps --max ) # add examples as additional tests if(GLPK_BUILD_EXAMPLES) add_test(NAME iptsamp COMMAND iptsamp WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) add_test(NAME mplsamp1 COMMAND mplsamp1 WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) add_test(NAME mplsamp2 COMMAND mplsamp2 WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) # add_test(NAME netgen COMMAND netgen WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) add_test(NAME nppsamp COMMAND nppsamp WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) add_test(NAME sample COMMAND sample WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) add_test(NAME spxsamp1 COMMAND spxsamp1 WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) add_test(NAME spxsamp2 COMMAND spxsamp2 WORKING_DIRECTORY ${GLPK_EXAMPLES_DIR}) endif() # targets to install. glpk includes the glpk.h header set(GLPK_INSTALL_TARGETS glpk glpsol) # install library and glpsol when cmake --install is invoked if(MSVC) # Debug config should also install PDB files. they go to lib if libraries # are static, bin if libraries are DLL for debugging convenience if(BUILD_SHARED_LIBS) set(GLPK_PDB_INSTALL_SUBDIR bin) else() set(GLPK_PDB_INSTALL_SUBDIR lib) endif() # multi-config installation if(GLPK_INSTALL_MULTI_CONFIG) install( TARGETS ${GLPK_INSTALL_TARGETS} RUNTIME DESTINATION bin/$ LIBRARY DESTINATION lib/$ ARCHIVE DESTINATION lib/$ PUBLIC_HEADER DESTINATION include COMPONENT glpk ) # Debug config should also install PDB files. they go to lib if # libraries are static, bin if libraries are DLL if(BUILD_SHARED_LIBS) set(GLPK_PDB_INSTALL_SUBDIR bin) else() set(GLPK_PDB_INSTALL_SUBDIR lib) endif() # install PDB file for Debug config only install( FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/glpk.pdb CONFIGURATIONS Debug DESTINATION ${GLPK_PDB_INSTALL_SUBDIR}/Debug COMPONENT glpk ) # flat installation where artifacts are suffixed with "d" else() install( TARGETS ${GLPK_INSTALL_TARGETS} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib PUBLIC_HEADER DESTINATION include COMPONENT glpk ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/Debug/glpkd.pdb CONFIGURATIONS Debug DESTINATION ${GLPK_PDB_INSTALL_SUBDIR} COMPONENT glpk ) endif() # typical flat *nix installation # TODO: for *nix, need pkg-config stuff too, etc. else() install( TARGETS ${GLPK_INSTALL_TARGETS} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib PUBLIC_HEADER DESTINATION include COMPONENT glpk ) endif()