Uriel
Uriel

Reputation: 31

C++ CMakeLists how to build dependencies only once?

I installed some libraries with:

sudo apt-get install libomp-dev
sudo apt-get install libarmadillo-dev
sudo apt-get install libmlpack-dev

When I try to build/execute/debug the app in eclipse it seems it builds all the dependencies again. It takes long time for a simple program. Dependencies in CMakeLists.txt:

find_package(OpenMP REQUIRED)
target_compile_options(${PROJECT_NAME} INTERFACE -fopenmp)
target_link_libraries(${PROJECT_NAME} PUBLIC OpenMP::OpenMP_CXX mlpack PUBLIC armadillo)

Program:

#include <iostream>
#include <mlpack/core.hpp>
#include <mlpack/methods/ann/layer/layer.hpp>
#include <mlpack/methods/ann/ffn.hpp>

using namespace std;
using namespace mlpack;
using namespace mlpack::ann;

int main(int argc, char **argv) {
    cout << "Hello World." << endl;
    return 0;
}

Since these dependencies are not modified, there is a way to avoid building them each time that I want to execute/debug my "hello world"? Something like: Build dependencies only once. Or: Build only if don't exist (Clean and build).

The result:

Building in: /home/ai/Documents/ai_projects/test1/build/default
cmake --build . --target all
Scanning dependencies of target Prueba_1
[ 50%] Building CXX object CMakeFiles/test1.dir/test1.cpp.o  <-- It takes 40sec
[100%] Linking CXX executable test1
[100%] Built target test1
Build complete (0 errors, 0 warnings): /home/ai/Documents/ai_projects/test1/build/default

Upvotes: 0

Views: 293

Answers (1)

Alex Reinking
Alex Reinking

Reputation: 19916

Since these dependencies are not modified, there is a way to avoid building them each time that I want to execute/debug my "hello world"? Something like: Build dependencies only once. Or: Build only if don't exist (Clean and build).

Sort of. CMake isn't actually building these libraries from scratch, so there's nothing to tell it about dependencies-wise. It's just that the headers are very large and take a long time to process.

However, you can often use precompiled headers as a workaround. Try this:

cmake_minimum_required(VERSION 3.16)

# ...

target_precompile_headers(
  ${PROJECT_NAME}
  PRIVATE
    <iostream>
    <mlpack/core.hpp>
    <mlpack/methods/ann/layer/layer.hpp>
    <mlpack/methods/ann/ffn.hpp>
)

This will precompile these headers as a separate build step and include the result via a command line flag into every source file in the ${PROJECT_NAME} target. This won't help on the first build, but when doing an incremental build, then as long as the set of includes in the precompiled header hasn't changed, you should see some benefit.

Upvotes: 1

Related Questions