if(WIN32) #CMAKE_MSVC_RUNTIME_LIBRARY #Without this I guess you have to edit the cryptic #MSVC flags to change the runtime. cmake_minimum_required(VERSION 3.15.0 FATAL_ERROR) cmake_policy(SET CMP0091 NEW) else() cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) endif() ####This is a hook for developers to use. ####Please have it print out what changes it makes via the CMake's message API. include(developer.cmake OPTIONAL) #REMINDER: Widgets95Config.cmake expects capitalization. #widgets95-config.cmake does not. The current system is #based on GLUI's but it may be an improvement to change. project(Widgets95 VERSION 3.0.0 LANGUAGES CXX) set(PROJECT_VERSION 3.00) message(STATUS "Compiling Widgets95 Library Version ${PROJECT_VERSION}") message(STATUS "Using cmake version ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" ) #Defines CMAKE_INSTALL_LIBDIR, but what else? #NOTE: widgets95.pc libdir=/usr/local/lib depends on #this. It is blank without it. include(GNUInstallDirs) message(STATUS "Installing to ${CMAKE_INSTALL_PREFIX}") set(CMAKE_CXX_STANDARD_REQUIRED ON) #cmake-gui doesn't show this option. But be cautious since it may one day. set(CMAKE_CXX_STANDARD ${CMAKE_CXX_STANDARD} CACHE STRING "Must not be 98" FORCE) mark_as_advanced(CLEAR CMAKE_CXX_STANDARD) if(NOT CMAKE_CXX_STANDARD OR 98 EQUAL CMAKE_CXX_STANDARD) message("CMAKE_CXX_STANDARD is not set or 98. Set to 11") set(CMAKE_CXX_STANDARD 11) endif() ####CMake-GUI options########################## set(OpenGL_GL_PREFERENCE "GLVND" CACHE STRING "GLVND or LEGACY") #These names need to stick out when building the external-libs projects. option(Widgets95_NOGLUT "Use only Widgets95::glute and glutext namespaces" ON) option(Widgets95_BUILD_EXAMPLES "Include xcv_example to launch demo" ON) option(Widgets95_READLINE_MODIFIERS "Restore Unix's Readline key bindings" OFF) option(Widgets95_DEBUG_STDOUT "Restore (dump) debug output feature" OFF) option(Widgets95_STATIC "Build static target" OFF) option(Widgets95_SHARED "Build shared target" ON) if(Widgets95_NOGLUT) add_definitions(-DWIDGETS_95_NOGLUT) endif() if(Widgets95_BUILD_EXAMPLES) add_definitions(-DWIDGETS_95_BUILD_EXAMPLES) endif() if(Widgets95_READLINE_MODIFIERS) add_definitions(-DWIDGETS_95_READLINE_MODIFIERS) endif() if(Widgets95_DEBUG_STDOUT) add_definitions(-DWIDGETS_95_DEBUG_STDOUT) endif() ####BUILD/INSTALL############################### string(APPEND CMAKE_CXX_FLAGS_DEBUG " -D_DEBUG") string(APPEND CMAKE_CXX_FLAGS_RELEASE " -DNDEBUG") string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " -DNDEBUG") string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -DNDEBUG") if(CMAKE_COMPILER_IS_GNUCXX) add_compile_options(-frtti -fvisibility=hidden -fpermissive) endif() find_package(X11) if(NOT Widgets95_NOGLUT) find_package(GLUT REQUIRED) endif() find_package(OpenGL REQUIRED) #https://wiki.wxwidgets.org/CMake find_package(wxWidgets COMPONENTS core base gl html REQUIRED) include(${wxWidgets_USE_FILE}) set(xcv_libs ${wxWidgets_LIBRARIES} ${X11_LIBRARIES} ${OPENGL_LIBRARIES}) set(xcv_incl ${wxWidgets_INCLUDE_DIRS} ${X11_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) if(GLUT_FOUND) list(APPEND xcv_libs ${GLUT_LIBRARIES}) list(APPEND xcv_incl ${GLUT_INCLUDE_DIR}) endif() #wxGTK? #FindwxWidgets.cmake is no-frills... #message(STATUS "wxWidgets_LIBRARIES variable is \"${wxWidgets_LIBRARIES}\"") string(REGEX MATCH "gtk([2-4])" gtk "${wxWidgets_LIBRARIES}") message(STATUS "GTK: ${gtk}") if(gtk) find_package(PkgConfig REQUIRED) pkg_check_modules(GTK "gtk+-${CMAKE_MATCH_1}.0") list(APPEND xcv_libs ${GTK_LIBRARIES}) list(APPEND xcv_incl ${GTK_INCLUDE_DIRS}) endif() file(GLOB xcv_files "src/*.?pp" "src/example/xcv_*" "include/*.*") #NOTE: GLUI built an OBJECT library to avoid compiling twice but #I couldn't make it play nice with both targets under Visual Studio. #Probably the runtime setting. if(Widgets95_SHARED) list(APPEND install "widgets95") add_library(widgets95 SHARED ${xcv_files}) target_include_directories(widgets95 PUBLIC "$" "$" ${xcv_incl}) target_link_libraries(widgets95 PUBLIC ${xcv_libs}) set_target_properties(widgets95 PROPERTIES DEBUG_POSTFIX "d" VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION}) if(WIN32 OR CYGWIN) set_property(TARGET widgets95 PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") target_compile_definitions(widgets95 PUBLIC -DWIDGETS_95_DLL) endif() endif() if(Widgets95_STATIC) list(APPEND install "widgets95-s") add_library(widgets95-s STATIC ${xcv_files}) target_include_directories(widgets95-s PUBLIC "$" "$" ${xcv_incl}) target_link_libraries(widgets95-s PUBLIC ${xcv_libs}) set_target_properties(widgets95-s PROPERTIES DEBUG_POSTFIX "d") if(WIN32) set_property(TARGET widgets95-s PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") endif() endif() file(GLOB ppm2array_files "src/ppm2array/*.cpp" "src/ppm2array/*.h") add_executable(ppm2array ${ppm2array_files}) #CentOS isn't doing this automatically? if(CMAKE_COMPILER_IS_GNUCXX) target_link_libraries(ppm2array stdc++) endif() if(Widgets95_BUILD_EXAMPLES) list(APPEND install "example") file(GLOB example_files "src/example/example.*") if(CYGWIN) #Cygwin windres won't handle the UTF16-LE files VS exclusively uses! set(rc_file "src/example/windres.rc") else() set(rc_file "src/example/vstudio.rc") endif() add_executable(example ${example_files} ${rc_file}) if(Widgets95_SHARED) target_link_libraries(example widgets95 ${xcv_libs}) else() target_link_libraries(example widgets95-s ${xcv_libs}) endif() endif() ####PACKAGING############################### set(bin ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}) set(src ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}) install(TARGETS ${install} EXPORT ${PROJECT_NAME}Targets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} INCLUDES DESTINATION include/${PROJECT_NAME}) install(FILES include/widgets95.h DESTINATION include/${PROJECT_NAME} COMPONENT Devel) #This seems to be the new way to do this. Since CMake version?? #Note, the camel-case file names are part of the documentation. include(CMakePackageConfigHelpers) write_basic_package_version_file("${bin}ConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) configure_package_config_file("${PROJECT_NAME}Config.cmake.in" "${bin}Config.cmake" INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}") install(FILES "${PROJECT_NAME}Config.cmake" "${bin}ConfigVersion.cmake" DESTINATION "lib/cmake/${PROJECT_NAME}") install(EXPORT "${PROJECT_NAME}Targets" NAMESPACE ${PROJECT_NAME}:: DESTINATION "lib/cmake/${PROJECT_NAME}") #UNTESTED #OBSOLETE? pkg-config support (I think) configure_file("${src}.pc.in" "${bin}.pc" @ONLY IMMEDIATE) install(FILES ${bin}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig/ COMPONENT Devel) #### Monkey see, monkey do??? ################ #REMINDER #I've tested this. It works by just doing find_package(Widgets95) and then using #target_link_libraries(app Widget95::widgets95) for all purposes, including just #to be able to #include or link, etc. SHARED and STATIC can modify #the linkage. CMakeFiles\Export\lib\cmake\Widgets95 has Targets.cmake files, but #it seems to work with or without installing them. I think maybe it knows to use #the most recently made target. This is a more modern approach than using macros. export(EXPORT ${PROJECT_NAME}Targets FILE "${CMAKE_CURRENT_BINARY_DIR}/Widgets95/${PROJECT_NAME}Targets.cmake" NAMESPACE ${PROJECT_NAME}::)