123iamking
123iamking

Reputation: 2703

cmake - preset settings for entries from ini file

I have a project that uses some third party libraries. So each time I setup this project with CMake, I have to set each entry (path of the third party library) on the GUI of CMake. I improve this by making CMake script guess the path by this script (learn this technique from OGRE):

# Guess the paths.
set( OGRE_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/Ogre" CACHE STRING "Path to OGRE source code (see http://www.ogre3d.org/tikiwiki/tiki-index.php?page=CMake+Quick+Start+Guide)" )

So each time I setup with CMake, it will automatic fill the entry OGRE_SOURCE. But that doesn't enough. If the Ogre source is not in the path

"${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/Ogre"

, then I have to open and edit the CMake script or I have to edit the entry on the GUI of CMake. I find that pretty inconvenient, especially when you link to a lot of third party libraries.

So I want to use another technique: preset settings for entries from file - CMake reads the presets from file PresetEntries.txt (that I make) and apply the these presets on the entries (It's a lot quicker to edit the path in text file than on the GUI of CMake).

Here my idea about this preset file: PresetEntries.txt

OGRE_SOURCE=E:/Source/ogre

I found that CMake can read a text file, but if I use this, I have to do string manipulations.

CMake has the file CMakeCache.txt to save the settings on the CMake GUI, but I want it to be simple: it should only has the preset settings that need to be pre-set.

So I wonder if CMake support this preset settings for entries from file.

Edit: So I read this question and see that CMake can set config from file, but this require to fire cmake with the -C mysettings.cmake, but I wanna it to be automatically with CMake GUI - just edit the file and hit generate button in CMake GUI. So I wanna make this question more specific: In my CMakeLists.txt should have script like this:

# Guess the paths.
#I wanna have this function from C++
#https://msdn.microsoft.com/en-us/library/windows/desktop/ms724353%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
GetPrivateProfileString("OGRE",         #lpAppName
                        "OGRE_SOURCE",  #lpKeyName
                        "${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/Ogre", #lpDefault
                        OGRE_SOURCE_VAR,#lpReturnedString
                        MAX_PATH,       #nSize, may be can reduce this variable
                        "LibPath.ini")  #lpFileName

set( OGRE_SOURCE "${OGRE_SOURCE_VAR}" CACHE STRING "Path to OGRE source code" )

In the file LibPath.ini

[OGRE]
OGRE_SOURCE = "E:/Source/ogre"

So the user can choose to either use the ini file or not.

I don't know if there any way I can use a function that similar to function GetPrivateProfileString (of C++) in CMake.

Thanks for reading

Upvotes: 1

Views: 2883

Answers (2)

123iamking
123iamking

Reputation: 2703

I can't find the function to read the ini file, so what I can do is create a simple function that read simple txt file for myself.

  1. I declare the function in 1 file for other file use it

"\CMake\Dependencies\CommonFunc.cmake"

#------------Define function Read file------------
macro( readSettingFile KEY DEFAULT_RESULT STRING_RESULT_OUT)

    unset(STRING_RESULT)
    # Read the file
    file( READ "${CMAKE_SOURCE_DIR}/LibPath.txt" LIB_PATH_STR )

    # Set the variable "Esc" to the ASCII value 27 - basically something
    # which is unlikely to conflict with anything in the file contents.
    string(ASCII 27 Esc)

    # Turn the contents into a list of strings, each ending with an Esc.
    # This allows us to preserve blank lines in the file since CMake
    # automatically prunes empty list items during a foreach loop.
    string(REGEX REPLACE "\n" "${Esc};" LIB_PATH_LINES "${LIB_PATH_STR}")

    foreach(LINE ${LIB_PATH_LINES})
        if("${LINE}" MATCHES "${KEY}")
            #remove the key, leave the content untouch
            string(REPLACE "${KEY}" "" STRING_RESULT ${LINE})
            # Swap the appended Esc character back out in favour of a line feed
            string(REGEX REPLACE "${Esc}" "" STRING_RESULT ${STRING_RESULT})
        endif()
    endforeach()

    if("${STRING_RESULT}" STREQUAL "")
        set( STRING_RESULT ${DEFAULT_RESULT} )
    endif()


    #message( STATIC "---GTA Sa-----" "[${STRING_RESULT}]" )
endmacro()

(I need the help from this answer to write this function :p)

  1. Here is how I use

For example: "\CMake\Dependencies\Ogre.cmake"

#include common functions
include( CMake/Dependencies/CommonFunc.cmake )
#---------------Guess the paths.----------------------
#----Set OGRE_SOURCE
readSettingFile(    "OGRE_SOURCE="
                    "E:/Source/ogre"
                    STRING_RESULT
                )
set( OGRE_SOURCE "${STRING_RESULT}" CACHE STRING "Path to OGRE Source" )
#----Set OGRE_BINARIES
readSettingFile(    "OGRE_BINARIES="
                    "E:/Source/_build/ogre"
                    STRING_RESULT
                )
set( OGRE_BINARIES "${STRING_RESULT}" CACHE STRING "Path to OGRE's build folder generated by CMake" )
  1. Here is the setting file

"\LibPath.txt"

OGRE_SOURCE=E:/Source/ogre
OGRE_BINARIES=E:/Source/_build/ogre

Upvotes: 1

Th. Thielemann
Th. Thielemann

Reputation: 2824

The external libraries should be included by one of the following commands

find_package(ttnlib REQUIRED HINTS /usr/local/lib/cmake)
include_directories(${ttnlib_INCLUDE_DIR})
set(EXTRA_LIBS ${EXTRA_LIBS} ${TTNLIB_LIBRARY})

or

find_library(MY_EXTERNAL_LIB name COOLSTUFF libCOOLSTUFF libCOOLSTUF.so hints /usr/local/lib) 

The search for the external packages and libraries should only be necessary for the first run of cmake.

Upvotes: 1

Related Questions