Hi,<div><br></div><div>I'm currently using a combination of the include and file directives to find and bind optional submodules to one of my projects, but its a bit of a pain to do.</div><div><br></div><div>I was wondering if there was a more cmake-y way of doing this?</div>
<div><br></div><div>Here's what I currently do:</div><div><br></div><div><div># Optional: build pthreads</div><div>cmake_minimum_required (VERSION 2.6)</div><div>project (N)</div><div><br></div><div># Collect source files</div>
<div>file(GLOB_RECURSE SOURCES src/*.c)</div><div><br></div><div># Deps: self</div><div>set(PROJECT_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include")</div><div>set(PROJECT_EXTRA_LIBRARIES "")</div><div>set(PROJECT_EXTRA_INCLUDES "")</div>
<div>set(PROJECT_EXTRA_SOURCES "")</div><div>set(PROJECT_EXTRA_TESTS "")</div><div><br></div><div># Look for optional modules</div><div>file(GLOB PROJECT_IMPL impl/*.txt)</div><div>foreach(IMPL ${PROJECT_IMPL})</div>
<div> message("Adding: ${IMPL}")</div><div> include(${IMPL})</div><div>endforeach(IMPL)</div><div><br></div><div># Add extra parts to build</div><div>set(SOURCES "${SOURCES};${PROJECT_EXTRA_SOURCES}")</div>
<div>set(PROJECT_INCLUDE_DIRS "${PROJECT_INCLUDE_DIRS};${PROJECT_EXTRA_INCLUDES}")</div><div><br></div><div># Debug mode?</div><div>set(CMAKE_BUILD_TYPE Debug)</div><div>set(CMAKE_C_FLAGS "-Wall -pedantic -Wimplicit-function-declaration -Wreturn-type -Wextra")</div>
<div><br></div><div># Code type</div><div>set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")</div><div><br></div><div># Build library</div><div>add_library(n ${SOURCES})</div><div>target_link_libraries(n ${PROJECT_EXTRA_LIBRARIES})</div>
<div>include_directories(${PROJECT_INCLUDE_DIRS})</div><div>set(PROJECT_LIBRARIES "${PROJECT_BINARY_DIR}/libn.a" ${PROJECT_EXTRA_LIBRARIES})</div></div><div><br></div><div><div># Find tests</div><div>file(GLOB_RECURSE TESTS tests/CMakeLists*)</div>
<div>set(TESTS "${TESTS};${PROJECT_EXTRA_TESTS}")</div><div><br></div><div># Load tests</div><div>if(TESTS)</div><div> enable_testing()</div><div> foreach(TEST ${TESTS})</div><div> string(REGEX REPLACE "CMakeLists.txt" "" TEST_DIR ${TEST})</div>
<div> add_subdirectory(${TEST_DIR})</div><div> endforeach(TEST)</div><div>endif(TESTS)</div></div><div><br></div><div>Inside the 'impl' directory are a set of include files, one per optional submodule, that bind additional sources and include directories:</div>
<div><br></div><div><div># Optional: build pthreads</div><div>option(BUILD_THREADS_PTHREADS "Building pthreads thread implementation" ON)</div><div>if(BUILD_THREADS_PTHREADS)</div><div><br></div><div> # Absolute path to module base</div>
<div> set(EXTRA_PATH "${PROJECT_SOURCE_DIR}/impl/pthreads")</div><div><br></div><div> # Add include directories</div><div> set(PROJECT_EXTRA_INCLUDES ${PROJECT_EXTRA_INCLUDES} ${EXTRA_PATH}/include)</div><div>
<br></div><div> # Add sources</div><div> file(GLOB_RECURSE PROJECT_EXTRA_SOURCES_LOCAL "${EXTRA_PATH}/src/*.c")</div><div> set(PROJECT_EXTRA_SOURCES "${PROJECT_EXTRA_SOURCES};${PROJECT_EXTRA_SOURCES_LOCAL}")</div>
<div><br></div><div> # Add tests</div><div> file(GLOB_RECURSE PROJECT_EXTRA_TESTS_LOCAL "${EXTRA_PATH}/tests/CMakeLists*")</div><div> set(PROJECT_EXTRA_TESTS "${PROJECT_EXTRA_TESTS};${PROJECT_EXTRA_TESTS_LOCAL}")</div>
<div><br></div><div>endif(BUILD_THREADS_PTHREADS)</div></div><div><br></div><div>I mean, this approach works perfectly for what I'm trying to do, and it has the benefit of compiling a single final library including all the submodules (instead of building like 30 shared libraries, which is highly undesirable). It's highly extensible too, since to add a new submodule you just drop a new folder into impl/</div>
<div><br></div><div>It's quite... verbose though. Manually munging all the sources into a single list, etc.</div><div><br></div><div>Has anyone else had similar experience / a better way of doing this?</div><div><br></div>
<div>(The submodules are for platform specific code; rather than having a tonnes of #ifdefs in a single code group we've split it into a common header file and separate submodules for different people to look after independently).</div>
<div><br></div><div>Cheers,</div><div>Doug.</div>