I'm calling Makefile from CMakeLists.txt. The CMakeLists.txt compiles a main.cpp file that prints "Hello world", and calls the Makefile. The Makefile compiles a test.cpp file that prints "Test". The code is fine. I checked it when I built the test.cpp just with the Makefile.
The problem is when I'm trying to build CMakeLists.txt. The "main" output works fine but the "test" output throws an exception:
"segmentation fault (core dumped)".
Here is the Makefile code:
all:
g++ -shared -fPIC -o test test.cpp
Here is the CMakeLists.txt code:
cmake_minimum_required(VERSION 3.5)
project(Call_Makefile_From_CMake)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(FullPath "/home/orz/ClionProjects/Call_Makefile_From_CMake")
add_custom_command(
OUTPUT ${FullPath}/Test/test
COMMAND make -f test.mk
WORKING_DIRECTORY ${FullPath}/Test
)
add_custom_target(
extern_lib
DEPENDS ${FullPath}/Test/test
)
add_executable(Call_Makefile_From_CMake main.cpp)
target_link_libraries(Call_Makefile_From_CMake ${FullPath}/Test/test)
add_dependencies(Call_Makefile_From_CMake extern_lib)
Thank's for the helpers.
I tried to solve this problem for two days and 5 minutes after i asked for help here i solved it.
I removed the
target_link_libraries(Call_Makefile_From_CMake ${FullPath}/Test/test)
line and it solved the problem. Now it works just fine.
Related
I am trying to get code coverage in my unit test project in windows system.
Description
After compiling with -fprofile-arcs -ftest-coverage, I found out the execution file is generated and works fine. However there's no any .gcno files in the folder. So I cannot output the coverage report properly by gcovr.
Software version
gcc 8.1.0/gcov 8.1.0/gcovr 5.1/python 3.10.2
Steps
Here's what I've done during the whole process. Please help me if there's something wrong.
There are only .c and .h files in one folder
Compile my project using gcc
gcc -Wall -Wno-unknown-pragmas -fcompare-debug-second -fprofile-arcs -ftest-coverage -DUTEST AllTests.c CuTest.c BZR2.c BZR2_test.c -o beta.exe
Then I got beta.exe in the folder.
After runing beta.exe, there's my test result(All tests are passed.) showing in the command line window. Besides there're .gcda files with the same filename as my .c files.
Then I run gcovr -r ., the result is showing below. I think the reson why gcovr can't show the coverage information is there's no any .gcno files generated after compiling my project. But I don't understand why and how to solve this.
------------------------------------------------------------------------------
GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File Lines Exec Cover Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL 0 0 --%
------------------------------------------------------------------------------
Thanks for your time!
Remove the -fcompare-debug-second option. It is used for debugging the compiler itself, and causes the compiler
to silence warnings, and omitting other options that would cause the compiler to produce output to files or to standard output as a side effect.
(see: https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Developer-Options.html)
Creation of gcno files is such a side effect.
General tips:
Instead of -fprofile-arcs -test-coverage you can simply use the --coverage option.
When you compile multiple source files in one go, then GCC tries to figure out file names for intermediate files, and also automatically derives some name for secondary outputs like gcno files. This used to be somewhat unintuitive, at least until reasonable behaviour was implemented in GCC 11.
To compile all of the files individually, we would use the structure:
OPTIONS="-Wall -Wno-unknown-pragmas --coverage -DUTEST"
# compile the individual compilation units
gcc -c $OPTIONS AllTests.c -o AllTests.o
gcc -c $OPTIONS BZR2.c -o BZR2.o
gcc -c $OPTIONS BZR2_test.c -o BZR2_test.o
# we should now have three gcno files
ls *.gcno
# link the final executable
gcc $OPTIONS CuTest.o BZR2.o BZR2_test.o -o beta.exe
At this point, it's typically appropriate to use a build system, for example by writing a Makefile:
CFLAGS += -Wall -Wno-unknown-pragmas --coverage -DUTEST
SOURCES = AllTests.c BZR2.c BZR2_tests.c
OBJECTS = $(SOURCES:.c=.o)
beta.exe: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $#
I have a very simple example of using gcov:
library.cpp file compiled and turned into library.a
main.cpp file compiled into executable and uses library.a
All of this done via a simple bash script:
g++ -c library.cpp -Wall -fprofile-arcs -ftest-coverage -o library.o
ar rvs library.a library.o
g++ main.cpp -Wall -fprofile-arcs -ftest-coverage library.a -o main
Now at this point I have the folllowing files (ignoring source and build script):
library.o
library.gcno
library.a
main.cpp
main
main.gcno
So far so good. Now I run my main executable, which creates:
main.gcda
library.gcda
Again all as expected. Now for the question - when I run gcov main.cpp I don't get any gcov files for library.cpp. Is that expected?
Do I really need to call gcov on every source file I may have at any point in time? Is there not a way to call the first source file i.e main.cpp and have it produce coverage stats for each piece of source main goes on to call?
I appear to get gcov files for a lot of core library code that main.cpp uses without need to call them directly with gcov (ostream.gov, locale.gcov...) just not library.gcov
Normally you'd call gcov *.gcno.
I am trying to create shared library i.e. .so from C++ code using Git Bash shell in Windows 10.
I use Makefile for compiling C++ code in Windows 10. Running make through Git bash shell.
Code compiles without any issue and creates object files without fail.
But it fails while creating .so file throwing following error. Following is part of Makefile in which target VLIB_SHARED_LIBRARY is causing this error.
VLIB_SO_DIR = .
VLIB_SHARED_LIBRARY = $(VLIB_SO_DIR)/libvxxx.so
CXX = g++
CXXFLAGS = -Wall -std=c++11 -O2 -D_7ZIP_ST -fPIC
LDFLAGS = -shared
OBJECT_FILES = a.o b.o c.o d.o .. z.o
all: init $(VLIB_SHARED_LIBRARY )
release: init $(VLIB_SHARED_LIBRARY )
$(VLIB_SHARED_LIBRARY): $(OBJECT_FILES) \n
$(CXX) $(LDFLAGS) -o $(VLIB_SHARED_LIBRARY) $(OBJECT_DIR)/*.o
process_begin: CreateProcess(C:\Program, C:/Program Files/Git/usr/bin/sh.exe -c "g++ -shared -o C:/XXXX_YYYY/bbbb/bin_linux/libyyyy.so C:/XXXX_YYYY/bbbb/bin_linux/obj/*.o", ...) failed.
make (e=193): Error 193
Same Makefile works fine in actual Linux Ubuntu OS but fails in Windows 10.
How to fix this error ?
The reason I suggested whitespace issues in my comment above is that the error message CLEARLY shows that it's a whitespace problem:
CreateProcess(C:\Program, C:/Program Files/Git/usr/bin/sh.exe ...
There is a space in this path to sh.exe, and the first argument printed here C:\Program quite clearly shows that the path has been truncated at the space.
I thought maybe your makefile was setting SHELL to some value but it doesn't appear to be. All I can suggest is either (a) remove C:\Program Files\Git\usr\bin from your %Path%, or (b) re-install Git into a path that doesn't contain whitespace so that you don't hit this problem.
I'm new to C programming. I want to compile C program using Make file. I can compile the source code file with the command:
gcc `xml2-config --cflags --libs` -o xmlexample readelementsfile.c
But when I create make file and I add the above commend into the make file I get this error:
Makefile:1: *** missing separator. Stop.
Can you tell me where I'm wrong?
You need to specify a target:
all:
gcc `xml2-config --cflags --libs` -o xmlexample readelementsfile.c
The whitespace at the start of the second line should be a Tab character.
You can also specify dependencies so that not all of your commands are run every time you build.
Related
Makefile Tutorial
I'm trying to create a cmake equivalent to the following make:
demo: main.cpp
gcc -o demo main.cpp
./demo
demo is executed whenever demo is created.
This what I came to, but demo is not executed as I want:
add_executable(demo main.cpp)
add_custom_target(run_demo demo)
This is actually equivalent to:
all: demo
demo: main.cpp
gcc -o demo main.cpp
run_demo:demo
What do I miss?
I'm not entirely sure what you want, as the Makefile snippets you posted do not do what you say they do. But judging by the comment on Kleist's answer, you want the demo to run each time it is compiled anew. You can achieve that as follows:
add_executable(demo main.cpp)
add_custom_command(TARGET demo
POST_BUILD COMMAND ${CMAKE_CURRENT_BINARY_DIR}/demo)
You need to add run_demo to the ALL target:
add_custom_target(run_demo ALL demo)