How CMake automatically detects header dependencies - cmake

I wonder how CMake automatically detects that main.cpp depends on header.h
// header.h
int f() {
return 0;
}
// main.cpp
#include "header.h"
int main() {
return f();
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(Cppref)
add_executable(main main.cpp)

When I run cmake . -B build it creates the following make target in ./build/CMakeFiles/main.dir/build.make
CMakeFiles/main.dir/main.cpp.o: CMakeFiles/main.dir/compiler_depend.ts
#$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=/home/nikolay/Cpp/Train/Cppref/build/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/main.dir/main.cpp.o"
/usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /home/nikolay/Cpp/Train/Cppref/main.cpp
Pay attention to the -MD compiler option, as
it is used to dump dependencies visible to the preprocessor.
So after the first build it will create ./build/CMakeFiles/main.dir/main.cpp.o.d with the following content
CMakeFiles/main.dir/main.cpp.o: /home/nikolay/Cpp/Train/Cppref/main.cpp \
/home/nikolay/Cpp/Train/Cppref/header.h
So whenever you change header.h, the target main.o will be rebuilt.

Related

Compiling cpputest with mingw-w64

I'm trying to compile cpputest with mingw-w64 but can't make it work and I can't find any resources on how to do that. So hopefully this question will help others in the future.
I would like to compile cpputest using mingw-w64, preferably without installing MSYS2 or other packages.
I have mingw-w64 i686-8.1.0-posix-dwarf-rt_v6-rev0 installed. I've cloned cpputest from here.
I tried following Compiling Google test with Mingw-w64 and Compiling and using CppUTest 3.8 under MSYS2/MinGW32 by calling CMake with:
cmake ^
-G "MinGW Makefiles" ^
-D CMAKE_C_COMPILER=gcc.exe ^
-D CMAKE_CXX_COMPILER=g++.exe ^
-D CMAKE_MAKE_PROGRAM=mingw32-make.exe ^
-D C++11=ON ^
.
Which yields:
-------------------------------------------------------
CppUTest Version 3.8
Current compiler options:
CC: C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/bin/gcc.exe
CXX: C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/bin/g++.exe
CppUTest CFLAGS: -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorMallocMacros.h" -Wall -Wextra -pedantic -Wshadow -Wswitch-default -Wswitch-enum -Wconversion -Wsign-conversion -Wno-padded -Wno-long-long -Wstrict-prototypes
CppUTest CXXFLAGS: -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorNewMacros.h" -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorMallocMacros.h" -Wall -Wextra -pedantic -Wshadow -Wswitch-default -Wswitch-enum -Wconversion -Wsign-conversion -Wno-padded -Wno-long-long -Woverloaded-virtual -Wno-old-style-cast -Wno-c++14-compat
CppUTest LDFLAGS:
Features configured in CppUTest:
Memory Leak Detection: ON
Compiling Extensions: ON
Support Long Long: OFF
Use CppUTest flags: ON
Using Standard C library: ON
Using Standard C++ library: ON
Using C++11 library: ON
Generating map file: OFF
Compiling with coverage: OFF
Compile and run self-tests ON
Run self-tests separately OFF
-------------------------------------------------------
Running make fails with:
>mingw32-make.exe
Scanning dependencies of target CppUTest
[ 1%] Building CXX object src/CppUTest/CMakeFiles/CppUTest.dir/CommandLineArguments.cpp.obj
In file included from C:/git/tdd/cpputest/include/CppUTest/Utest.h:34,
from C:/git/tdd/cpputest/include/CppUTest/TestHarness.h:39,
from C:\git\tdd\cpputest\src\CppUTest\CommandLineArguments.cpp:29:
C:/git/tdd/cpputest/include/CppUTest/SimpleString.h:183:31: error: 'nullptr_t' does not name a type
SimpleString StringFrom(const nullptr_t value);
^~~~~~~~~
C:/git/tdd/cpputest/include/CppUTest/SimpleString.h:183:31: note: 'nullptr_t' is defined in header '<cstddef>'; did you forget to '#include <cstddef>'?
C:/git/tdd/cpputest/include/CppUTest/SimpleString.h:42:1:
+#include <cstddef>
C:/git/tdd/cpputest/include/CppUTest/SimpleString.h:183:31:
SimpleString StringFrom(const nullptr_t value);
^~~~~~~~~
mingw32-make.exe[2]: *** [src\CppUTest\CMakeFiles\CppUTest.dir\build.make:63: src/CppUTest/CMakeFiles/CppUTest.dir/CommandLineArguments.cpp.obj] Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:886: src/CppUTest/CMakeFiles/CppUTest.dir/all] Error 2
mingw32-make.exe: *** [Makefile:140: all] Error 2
I tried the obvious solution of adding cstddef to SimpleString.h:
--- a/include/CppUTest/SimpleString.h
+++ b/include/CppUTest/SimpleString.h
## -180,6 +180,9 ## SimpleString BracketsFormattedHexString(SimpleString hexString);
* Specifically nullptr_t is not officially supported
*/
#if __cplusplus > 199711L && !defined __arm__
+
+#include <cstddef>
+
SimpleString StringFrom(const nullptr_t value);
#endif
But that still fails with the same error.
So I tried following Build error with CMake and MSYS2 mingw-w64 by installing MSYS2 and then mingw-w64, CMake and Ninja. That gives:
-------------------------------------------------------
CppUTest Version 3.8
Current compiler options:
CC: C:/msys64/mingw64/bin/cc.exe
CXX: C:/msys64/mingw64/bin/c++.exe
CppUTest CFLAGS: -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorMallocMacros.h" -Wall -Wextra -pedantic -Wshadow -Wswitch-default -Wswitch-enum -Wconversion -Wsign-conversion -Wno-padded -Wno-long-long -Wstrict-prototypes
CppUTest CXXFLAGS: -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorNewMacros.h" -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorMallocMacros.h" -Wall -Wextra -pedantic -Wshadow -Wswitch-default -Wswitch-enum -Wconversion -Wsign-conversion -Wno-padded -Wno-long-long -Woverloaded-virtual -Wno-old-style-cast
CppUTest LDFLAGS:
Features configured in CppUTest:
Memory Leak Detection: ON
Compiling Extensions: ON
Support Long Long: OFF
Use CppUTest flags: ON
Using Standard C library: ON
Using Standard C++ library: ON
Using C++11 library: OFF
Generating map file: OFF
Compiling with coverage: OFF
Compile and run self-tests ON
Run self-tests separately OFF
-------------------------------------------------------
Compiling with cmake -G Ninja . && ninja fails with:
include/CppUTest/SimpleString.h:183:31:
SimpleString StringFrom(const nullptr_t value);
^~~~~~~~~
[10/98] Building CXX object src/CppUTest/CMakeFiles/CppUTest.dir/TestMemoryAllocator.cpp.obj
FAILED: src/CppUTest/CMakeFiles/CppUTest.dir/TestMemoryAllocator.cpp.obj
C:\msys64\mingw64\bin\c++.exe -DCPPUTEST_HAVE_STRDUP=1 -DHAVE_CONFIG_H -D_TIMESPEC_DEFINED=1 -I. -Iinclude -Isrc/CppUTest/../../include -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorNewMacros.h" -include "C:/git/tdd/cpputest/include/CppUTest/MemoryLeakDetectorMallocMacros.h" -Wall -Wextra -pedantic -Wshadow -Wswitch-default -Wswitch-enum -Wconversion -Wsign-conversion -Wno-padded -Wno-long-long -Woverloaded-virtual -Wno-old-style-cast -O2 -g -DNDEBUG -MD -MT src/CppUTest/CMakeFiles/CppUTest.dir/TestMemoryAllocator.cpp.obj -MF src\CppUTest\CMakeFiles\CppUTest.dir\TestMemoryAllocator.cpp.obj.d -o src/CppUTest/CMakeFiles/CppUTest.dir/TestMemoryAllocator.cpp.obj -c src/CppUTest/TestMemoryAllocator.cpp
In file included from include/CppUTest/Utest.h:34,
from include/CppUTest/TestHarness.h:39,
from src/CppUTest/TestMemoryAllocator.cpp:28:
include/CppUTest/SimpleString.h:183:31: error: 'nullptr_t' does not name a type
SimpleString StringFrom(const nullptr_t value);
^~~~~~~~~
include/CppUTest/SimpleString.h:183:31: note: 'nullptr_t' is defined in header '<cstddef>'; did you forget to '#include <cstddef>'?
include/CppUTest/SimpleString.h:42:1:
+#include <cstddef>
include/CppUTest/SimpleString.h:183:31:
SimpleString StringFrom(const nullptr_t value);
^~~~~~~~~
ninja: build stopped: subcommand failed.
Thanks!!
Turns out this was a bug in CppUtest.
## -562,7 +562,7 ## SimpleString BracketsFormattedHexString(SimpleString hexString)
* Specifically nullptr_t is not officially supported
*/
#if __cplusplus > 199711L && !defined __arm__
- SimpleString StringFrom(const nullptr_t value)
+ SimpleString StringFrom(const std::nullptr_t value)
{
(void) value;
return "(null)";
It's fixed since Dec. 5th, 2019.
https://github.com/leonardopsantos/cpputest/commit/cb8c457dda6741ede7009103db99967b5f27c969

Why No ops registered when I try to load frozen model in Android NDK?

I want to use c++ tensorflow API through ndk and cmake, I can create the library but when I load a frozen model a lot of errors like this when I try to load graph:
E/native: op_kernel.cc:1148 OpKernel ('op: "PopulationCount"
device_type: "CPU" constraint { name: "T" allowed_values { list {
type: DT_INT32 } } }') for unknown op: PopulationCount
So I understand that my library does not support the operations.
Do I need to add another library to support these operations?
I based my Cmake script on this Cmakelist and
I used the build_android_all.sh script to build the dependencies for armeabi-v7a.
This is how my cmake script looks like:
cmake_minimum_required(VERSION 3.4.1)
include(ExternalProject)
SET(PROJECT_NAME tf_native_lib)
SET(OpenCV_FOUND true )
SET(PREBUILT_DIR ${TENSORFLOW_ROOT_DIR}/tensorflow/contrib/makefile/gen)
SET(TARGET_NSYNC_LIB ${TENSORFLOW_ROOT_DIR}/tensorflow/contrib/makefile /downloads/nsync/builds/${ANDROID_ABI}.android.c++11)
FIND_PACKAGE(OpenCV REQUIRED)
add_library( # Sets the name of the library.
${PROJECT_NAME}
SHARED
src/main/cpp/native-lib.h
src/main/cpp/native-lib.cpp
src/main/cpp/TensorflowInferenceHandler.h
src/main/cpp/TensorflowInferenceHandler.cpp
)
add_library(lib_proto STATIC IMPORTED )
set_target_properties(lib_proto PROPERTIES IMPORTED_LOCATION
${PREBUILT_DIR}/protobuf_android/${ANDROID_ABI}/lib/libprotobuf.a)
add_library(lib_nsync STATIC IMPORTED )
set_target_properties(lib_nsync PROPERTIES IMPORTED_LOCATION
${TARGET_NSYNC_LIB}/libnsync.a)
add_library(lib_tf STATIC IMPORTED )
set_target_properties(lib_tf PROPERTIES IMPORTED_LOCATION
${PREBUILT_DIR}/lib/android_${ANDROID_ABI}/libtensorflow-core.a)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DIS_SLIM_BUILD \
-std=c++11 -fno-rtti -fno-exceptions \
-O2 -Wno-narrowing -fomit-frame-pointer \
-mfpu=neon -mfloat-abi=softfp -fPIE -fPIC \
-ftemplate-depth=900 \
-DGOOGLE_PROTOBUF_NO_RTTI \
-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} \
-Wl,--allow-multiple-definition \
-Wl,--whole-archive \
-fPIE -pie -v")
# MESSAGE("tensorflow lib dir ${TENSORFLOW_LIB_DIR}")
target_link_libraries( # Specifies the target library.
${PROJECT_NAME}
${OpenCV_LIBS}
android
dl
log
m
z
jnigraphics
lib_tf
lib_proto
lib_nsync)
include_directories(
${OPENCV_INCLUDE_DIRS}
${PREBUILT_DIR}/proto
${PREBUILT_DIR}/protobuf_android/${ANDROID_ABI}/include
${PREBUILT_DIR}/nsync/public
${TENSORFLOW_ROOT_DIR}/tensorflow/contrib/makefile/downloads/eigen
${TENSORFLOW_ROOT_DIR}/bazel-tensorflow/external/nsync/public
${TENSORFLOW_ROOT_DIR}/bazel-genfiles
${TENSORFLOW_ROOT_DIR}
../../../cpp_utils)
If this is not possible, where are the sources to link the tensorflow_inference.so with my Jni Sources?
Thanks in advance.
Unai.
The PopulationCount and few other Ops are declared in tensorflow/core/ops/bitwise_ops.cc. Add that file to the end of /tensorflow/contrib/makefile/tf_op_files.txt. Then recompile the Tensorflow. That is what worked for me.

including itensor library in my cmake project in clion

so I am very new to CLion and CMake, so sorry in advance for wrong usage of terminology. I am suffering the following problem:
In my project I want to include the ITensor library which is essentially a non-CMake project. I cloned the git to my computer and build the ITensor project. Next I wanted to use it in another project linking against it with CMake:
My Code in main.cpp:
#include <iostream>
#include "itensor.h"
int main() {
std::string some_string = "Hello world";
return 0;
}
and my CMakeLists.txt looks like:
cmake_minimum_required(VERSION 3.6)
project(tutorial)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(ITENSOR_DIR PATH/TO/ITENSOR)
include_directories(ITENSOR_DIR/itensor)
set(SOURCE_FILES
main.cpp
${ITENSOR_DIR}/itensor/itensor.h
${ITENSOR_DIR}/itensor/itensor.cc)
add_executable(tutorial ${SOURCE_FILES})
Unfortunately, the project 'tutorial' does not build in CLion. Likewise, CLion cannot resolve the dependency itensor.h.
Anybody an Idea for why this is, respectively how to fix it?
After trying Thomas5631's solution the compilation ran into linking issues with lapack. I solved this by adding some flags, though I'm not sure if all of them are required.
My CMakeLists.txt:
cmake_minimum_required(VERSION 3.6)
project(my_project)
#Bring the headers into the project (full or relative path)
include_directories(itensor)
#Link the Itensor library
add_library(itensor STATIC IMPORTED)
set_property(TARGET itensor PROPERTY IMPORTED_LOCATION /home/david/my_project/itensor/lib/libitensor.a)
#Set a variable with all the new flags
set(ITENSOR_FLAGS "-DPLATFORM_lapack -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0")
set(ITENSOR_LINK_FLAGS "-DPLATFORM_lapack -L/home/david/my_project/itensor/lib -litensor -lpthread -L/usr/lib -lblas -llapack")
#Append the new flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${ITENSOR_FLAGS}")
add_executable(my_project main.cpp)
target_link_libraries(my_project itensor "${ITENSOR_LINK_FLAGS}")
Motivation: In the folder itensor/project_template there is a sample program which is simple enough to compile with make (from the terminal). The output of the compilation reveals the flags:
g++ -m64 -std=c++11 -c -I. -I/home/david/my_project/itensor -I/usr/include -O3 -DNDEBUG -Wall -DPLATFORM_lapack -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 -Wno-unused-variable -o myappname.o myappname.cc
[... some warnings ...]
g++ -m64 -std=c++11 -c -I. -I/home/david/my_project/itensor -I/usr/include -O3 -DNDEBUG -Wall -DPLATFORM_lapack -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 -Wno-unused-variable -o myclass.o myclass.cc
g++ -m64 -std=c++11 -I. -I/home/david/my_project/itensor -I/usr/include -O3 -DNDEBUG -Wall -DPLATFORM_lapack -D__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 -Wno-unused-variable myappname.o myclass.o -o myappname -L/home/david/my_project/itensor/lib -litensor -lpthread -L/usr/lib -lblas -llapack
I got around the issue with the following main.cpp:
#include <iostream>
#include "itensor/itensor.h"
int main() {
std::string some_string = "Hello world";
return 0;
}
And the following CMakeLists.txt:
project(tutorial)
cmake_minimum_required(VERSION 3.6)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#Bring the headers into the project
include_directories(/home/tom/Documents/workspace/ITensor/)
#Link the library
add_library(itensor STATIC IMPORTED)
set_property(TARGET itensor PROPERTY IMPORTED_LOCATION /home/tom/Documents/workspace/ITensor/lib/libitensor.a)
set(SOURCE_FILES main.cpp)
add_executable(tutorial ${SOURCE_FILES})
Where the path to ITensor can be either relative (using the ${PROJECT_SOURCE_DIR} variable) or absolute as I have shown.

Compile an OpenMP program with CMake on OS X

I have a very simple openmp hello world program as this:
#include <stdio.h>
#include <omp.h>
int main()
{
#pragma omp parallel
{
int id = omp_get_thread_num();
printf("hello, from %d.\n", id);
}
return 0;
}
I can compile it in my terminal with gcc-5 -fopenmp hello.c -o hello.o
But I want to code in CLion, it uses CMake to organize project, when I just click the run button, I will got an error
fatal error: 'omp.h' file not found
#include <omp.h>
I did search in google, and add something into my CMakeLists.txt file
This is my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.3)
project(openmp)
OPTION (USE_OpenMP "Use OpenMP" ON)
IF(USE_OpenMP)
FIND_PACKAGE(OpenMP)
IF(OPENMP_FOUND)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
ENDIF()
ENDIF()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fopenmp")
set(SOURCE_FILES hello.c omp.c)
add_executable(openmp ${SOURCE_FILES})
Your code is C, not C++, so instead of changing CMAKE_CXX_FLAGS, change CMAKE_C_FLAGS:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp")
And set your C compiler to gcc-5:
set(CMAKE_C_COMPILER /your/path/to/gcc-5)
To know gcc-5 path, in a terminal, type which gcc-5
See also: How to specify new gcc path for cmake

Cmake test program cannot find -lgcc_s

I'm using cmake with custom GCC(with shared libraries) and during cmake compiler test I get following error:
The C compiler "/path/to/gcc/bin/gcc" is not able to compile a simple test program.
...
/path/to/gcc/x86_64-unknown-linux-gnu/bin/ld:
cannot find -lgcc_s
Here's a simple "testme.cpp" file:
#include <iostream>
int main( int argc, char * argv[] ) {
std::cout << "Hello world" << std::endl;
return 0;
}
and here's a CMakeLists.txt:
cmake_minimum_required(VERSION 2.6.2)
project(testme)
file( GLOB srcs "testme.cpp" )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -Wall -std=c++11")
set(CMAKE_LDFLAGS "${CMAKE_LDFLAGS} -L/path/to/gcc/lib/gcc/x86_64-unknown-linux-gnu/lib64")
add_executable(testme ${srcs})
to build with my custom GCC I'm exporting CXX and CC:
export CXX=/path/to/gcc/bin/g++
export CC=/path/to/gcc/bin/gcc
and then hit:
cmake .
make
and the result is that it can't find libgcc_s.so which is located in the "lib/gcc/x86_64-unknown-linux-gnu/lib64" folder.
However, when I invoke gcc like this:
/path/to/gcc/bin/g++ testme.cpp -L/path/to/gcc/lib/gcc/x86_64-unknown-linux-gnu/lib64
it compiles successfully. I've tried to add it to LD_LIBRARY_PATH but that doesn't seem to help.
So, is there a way to pass library path to CMake compiler check?
Chrono Kitsune was sort of right ... /path/to/gcc/x86_64-unknown-linux-gnu/bin/ld was build with "--enable-shared" and libraries where not in systems search path.