2
\$\begingroup\$

My makefile looks like this and I translated it to cmake:

CC = gcc
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
CFLAGS := $(CFLAGS) -L/usr/local/include/ -L/usr/include -pedantic -std=c99 -Wall -O3 -g -DVERSION=\"$(GIT_VERSION)\" -ledit -lncurses

LDIRS = -L/usr/local/lib -L/usr/lib
LIBS =su -lcurses
USERNAME := $(shell whoami >> username.txt)
GIT:= $(shell head -n -2 openshell.h > temp.txt ; mv temp.txt openshell.h;git describe --abbrev=4 --dirty --always --tags > VERSION; echo "\#define VERSION \"$(GIT_VERSION)\"\n\#endif" >> openshell.h)
shell: main.o
    $(CC) -o shell main.o errors.c util.c -ledit -lncurses -lcurses

main.o: main.c errors.c util.c


.PHONY: clean
clean:
    rm -f *.o

Building it today is clean:

$ make clean
rm -f *.o
dac@dac-Latitude-E7450:~/osh$ make
gcc  -L/usr/local/include/ -L/usr/include -pedantic -std=c99 -Wall -O3 -g -DVERSION=\"v0.160505-4-gd549-dirty\" -ledit -lncurses   -c -o main.o main.c
gcc -o shell main.o errors.c util.c -ledit -lncurses -lcurses
dac@dac-Latitude-E7450:~/osh$ 

cmake:

cmake_minimum_required(VERSION 2.8.12)
project(openshell)
set(CMAKE_VERBOSE_MAKEFILE on)
file(GLOB SOURCES "./*.c")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -L/usr/local/include/ -L/usr/include -std=c11 -pedantic -O3 -g -Wall -pedantic -ledit -lncurses -lcurses -ltermcap")
include_directories(/usr/local/include/ /usr/include)
link_directories(/usr/lib)
link_directories(/usr/local/ib)
add_executable(openshell ${SOURCES})
target_link_libraries(openshell edit readline)

Building with cmake results in success:

opt/clion-2016.1.1/bin/cmake/bin/cmake --build /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug --target openshell -- -j 4
/opt/clion-2016.1.1/bin/cmake/bin/cmake -H/home/dac/ClionProjects/shell2/openshell -B/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/make -f CMakeFiles/Makefile2 openshell
make[1]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
/opt/clion-2016.1.1/bin/cmake/bin/cmake -H/home/dac/ClionProjects/shell2/openshell -B/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug --check-build-system CMakeFiles/Makefile.cmake 0
/opt/clion-2016.1.1/bin/cmake/bin/cmake -E cmake_progress_start /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug/CMakeFiles 4
/usr/bin/make -f CMakeFiles/Makefile2 CMakeFiles/openshell.dir/all
make[2]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
/usr/bin/make -f CMakeFiles/openshell.dir/build.make CMakeFiles/openshell.dir/depend
make[3]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
cd /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug && /opt/clion-2016.1.1/bin/cmake/bin/cmake -E cmake_depends "Unix Makefiles" /home/dac/ClionProjects/shell2/openshell /home/dac/ClionProjects/shell2/openshell /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug/CMakeFiles/openshell.dir/DependInfo.cmake --color=
Scanning dependencies of target openshell
make[3]: Leaving directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
/usr/bin/make -f CMakeFiles/openshell.dir/build.make CMakeFiles/openshell.dir/build
make[3]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
[ 25%] Building C object CMakeFiles/openshell.dir/util.c.o
[ 50%] Building C object CMakeFiles/openshell.dir/main.c.o
/usr/bin/gcc   -I/usr/local/include  -L/usr/local/include/ -L/usr/include -std=c11 -pedantic -O3 -g -Wall -pedantic -ledit -lncurses -lcurses -ltermcap -g   -o CMakeFiles/openshell.dir/util.c.o   -c /home/dac/ClionProjects/shell2/openshell/util.c
/usr/bin/gcc   -I/usr/local/include  -L/usr/local/include/ -L/usr/include -std=c11 -pedantic -O3 -g -Wall -pedantic -ledit -lncurses -lcurses -ltermcap -g   -o CMakeFiles/openshell.dir/main.c.o   -c /home/dac/ClionProjects/shell2/openshell/main.c
/home/dac/ClionProjects/shell2/openshell/util.c: In function ‘IBQsingle’:
/home/dac/ClionProjects/shell2/openshell/util.c:656:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
/home/dac/ClionProjects/shell2/openshell/util.c: In function ‘IBQdouble’:
/home/dac/ClionProjects/shell2/openshell/util.c:679:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
/home/dac/ClionProjects/shell2/openshell/util.c: In function ‘IBQplain’:
/home/dac/ClionProjects/shell2/openshell/util.c:702:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
/home/dac/ClionProjects/shell2/openshell/main.c: In function ‘command’:
/home/dac/ClionProjects/shell2/openshell/main.c:328:15: warning: ‘ptr’ may be used uninitialized in this function [-Wmaybe-uninitialized]
             w = parse_command(w, ptr, string1, pString, array, &i2, n, quote, i, matrix, pString1,
               ^
/home/dac/ClionProjects/shell2/openshell/main.c:302:12: note: ‘ptr’ was declared here
     char **ptr;
            ^
[ 75%] Linking C executable openshell

It seems I can't have warnings if I build with cmake and that is good:

/opt/clion-2016.1.1/bin/cmake/bin/cmake --build /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug --target openshell -- -j 4
/opt/clion-2016.1.1/bin/cmake/bin/cmake -H/home/dac/ClionProjects/shell2/openshell -B/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/make -f CMakeFiles/Makefile2 openshell
make[1]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
/opt/clion-2016.1.1/bin/cmake/bin/cmake -H/home/dac/ClionProjects/shell2/openshell -B/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug --check-build-system CMakeFiles/Makefile.cmake 0
/opt/clion-2016.1.1/bin/cmake/bin/cmake -E cmake_progress_start /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug/CMakeFiles 4
/usr/bin/make -f CMakeFiles/Makefile2 CMakeFiles/openshell.dir/all
make[2]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
/usr/bin/make -f CMakeFiles/openshell.dir/build.make CMakeFiles/openshell.dir/depend
make[3]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
cd /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug && /opt/clion-2016.1.1/bin/cmake/bin/cmake -E cmake_depends "Unix Makefiles" /home/dac/ClionProjects/shell2/openshell /home/dac/ClionProjects/shell2/openshell /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug/CMakeFiles/openshell.dir/DependInfo.cmake --color=
Scanning dependencies of target openshell
make[3]: Leaving directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
/usr/bin/make -f CMakeFiles/openshell.dir/build.make CMakeFiles/openshell.dir/build
make[3]: Entering directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
[ 25%] Building C object CMakeFiles/openshell.dir/util.c.o
[ 50%] Building C object CMakeFiles/openshell.dir/main.c.o
/usr/bin/gcc   -I/usr/local/include  -L/usr/local/include/ -L/usr/include -std=c11 -pedantic -O3 -g -Wall -pedantic -ledit -lncurses -lcurses -ltermcap -g   -o CMakeFiles/openshell.dir/util.c.o   -c /home/dac/ClionProjects/shell2/openshell/util.c
/usr/bin/gcc   -I/usr/local/include  -L/usr/local/include/ -L/usr/include -std=c11 -pedantic -O3 -g -Wall -pedantic -ledit -lncurses -lcurses -ltermcap -g   -o CMakeFiles/openshell.dir/main.c.o   -c /home/dac/ClionProjects/shell2/openshell/main.c
[ 75%] Linking C executable openshell
/opt/clion-2016.1.1/bin/cmake/bin/cmake -E cmake_link_script CMakeFiles/openshell.dir/link.txt --verbose=1
/usr/bin/gcc   -L/usr/local/include/ -L/usr/include -std=c11 -pedantic -O3 -g -Wall -pedantic -ledit -lncurses -lcurses -ltermcap -g   CMakeFiles/openshell.dir/errors.c.o CMakeFiles/openshell.dir/util.c.o CMakeFiles/openshell.dir/main.c.o  -o openshell  -L/usr/local/ib -rdynamic -ledit -lreadline -Wl,-rpath,/usr/local/ib 
make[3]: Leaving directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
[100%] Built target openshell
make[2]: Leaving directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'
/opt/clion-2016.1.1/bin/cmake/bin/cmake -E cmake_progress_start /home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug/CMakeFiles 0
make[1]: Leaving directory '/home/dac/.CLion2016.1/system/cmake/generated/openshell-69ebaaf9/69ebaaf9/Debug'

I can also use my own build script that calls make and runs the Valgrind tests:

/home/dac/ClionProjects/shell2/openshell/test.sh
-- Testing our implementation of OpenShell --

- If you have any problem in passing a test read the corresponding
- source file to understand what the test is checking

==823== Memcheck, a memory error detector
==823== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==823== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==823== Command: ./shell .
==823== 
********************* PRESS ENTER TO RUN TESTS  ... make: 'shell' is up to date.
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin.
stdin is a file or a pipe

openshell-0.16430.tar.gz
openshell.h
[828]
[827]
********************* TEST WILDCARDS 
***** Press any key to listing all files in current directory...
==823== 
==823== HEAP SUMMARY:
==823==     in use at exit: 79,732 bytes in 167 blocks
==823==   total heap usage: 529 allocs, 362 frees, 228,506 bytes allocated
==823== 
==823== LEAK SUMMARY:
==823==    definitely lost: 0 bytes in 0 blocks
==823==    indirectly lost: 0 bytes in 0 blocks
==823==      possibly lost: 0 bytes in 0 blocks
==823==    still reachable: 79,732 bytes in 167 blocks
==823==         suppressed: 0 bytes in 0 blocks
==823== Reachable blocks (those to which a pointer was found) are not shown.
==823== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==823== 
==823== For counts of detected and suppressed errors, rerun with: -v
==823== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
You should see filesnames *.* below 
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin.

stdin is a file or a pipe
a.out       LICENSE                shell
CMakeLists.txt  main.c                 test.sh
CommandEntry.h  main.o                 tests.log
compile     Makefile               username.txt
do.h        openshell-0.16430.tar.gz       util.c
errors.c    openshell.h            valgrindcli.sh
errors.h    osh-0.160502-tests-1-gb55e.tar.gz  VERSION
foo.txt     README.md
git.version sh
********************* TEST ALGORITHMS ...  
***** Press any key to run the algorithms... .
You should see the output from top -b -n1|head -8|tail -1 
==837== Memcheck, a memory error detector
==837== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==837== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==837== Command: ./shell .
==837== 
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin.
stdin is a file or a pipe
0
[839]

[840]
TERM environment variable not set.
[841]
[842]
==837== 
==837== HEAP SUMMARY:
==837==     in use at exit: 79,723 bytes in 167 blocks
==837==   total heap usage: 543 allocs, 376 frees, 228,523 bytes allocated
==837== 
==837== LEAK SUMMARY:
==837==    definitely lost: 0 bytes in 0 blocks
==837==    indirectly lost: 0 bytes in 0 blocks
==837==      possibly lost: 0 bytes in 0 blocks
==837==    still reachable: 79,723 bytes in 167 blocks
==837==         suppressed: 0 bytes in 0 blocks
==837== Reachable blocks (those to which a pointer was found) are not shown.
==837== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==837== 
==837== For counts of detected and suppressed errors, rerun with: -v
==837== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
********************* TEST ALGORITHMS Part II.  ... .
You should see the output from who|awk '{print $4 ; print $3}'|sort -n|wc -l. 
==843== Memcheck, a memory error detector
==843== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==843== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==843== Command: ./shell .
==843== 
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin.
stdin is a file or a pipe
[846]
2

[847]
[848]
==843== 
==843== HEAP SUMMARY:
==843==     in use at exit: 79,743 bytes in 167 blocks
==843==   total heap usage: 544 allocs, 377 frees, 228,761 bytes allocated
==843== 
==843== LEAK SUMMARY:
==843==    definitely lost: 0 bytes in 0 blocks
==843==    indirectly lost: 0 bytes in 0 blocks
==843==      possibly lost: 0 bytes in 0 blocks
==843==    still reachable: 79,743 bytes in 167 blocks
==843==         suppressed: 0 bytes in 0 blocks
==843== Reachable blocks (those to which a pointer was found) are not shown.
==843== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==843== 
==843== For counts of detected and suppressed errors, rerun with: -v
==843== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
********************* TEST CHECKENV.  ..... .
You should see the output checkenv below 
==849== Memcheck, a memory error detector
==849== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==849== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==849== Command: ./shell .
==849== 
'PATH' is set to /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin.
stdin is a file or a pipe

[854]
[856]
WARNING: terminal is not fully functional
[857]
-  (press RETURN)

My custom build script is this one which uses make and runs the tests with Valgrind so that I can check if I get data alignment errors (segfaults) or memory leaks (less important than segfaults).

#!/bin/sh
echo "-- Testing our implementation of OpenShell --"
echo ""
echo "- If you have any problem in passing a test read the corresponding"
echo "- source file to understand what the test is checking"
echo ""
printf "********************* PRESS ENTER TO RUN TESTS  ... "
#read _
make
valgrind --leak-check=yes ./shell .<< EOF
ls -al|grep open|awk '{print \$9}'
EOF
printf "********************* TEST WILDCARDS \n***** Press any key to listing all files in current directory...\nYou should see filesnames *.* below "
read _
./shell << EOF
ls
EOF
printf "********************* TEST ALGORITHMS ...  \n***** Press any key to run the algorithms... .\nYou should see the output from top -b -n1|head -8|tail -1 "
read _
valgrind --leak-check=yes ./shell .<< EOF
top|head -8|tail -1|sort -n|wc -l
EOF

printf "********************* TEST ALGORITHMS Part II.  ... .\nYou should see the output from who|awk '{print \$4 ; print \$3}'|sort -n|wc -l. "
read _
valgrind --leak-check=yes ./shell .<< EOF
who|awk '{print \$4 ; print \$3}'|sort -n|wc -l
EOF

printf "********************* TEST CHECKENV.  ..... .\nYou should see the output checkenv below "
read _
valgrind --leak-check=yes ./shell .<< EOF
checkenv
EOF
printf "********************* TEST DONE. YOU SHOULD SEE OUTPUT FROM TEST ABOVE ... "
read _

I could use better test cases since I only took like random commands and entered them to test non-trivial input and execution.

\$\endgroup\$
  • 1
    \$\begingroup\$ You're asking for help to fix a specific bug with your cmake file, rather than for an open-ended critique. Please ask on Stack Overflow instead. \$\endgroup\$ – 200_success May 5 '16 at 21:07
  • \$\begingroup\$ @200_success Building with cmake results in success. \$\endgroup\$ – Niklas Rosencrantz May 5 '16 at 21:09
  • 1
    \$\begingroup\$ Yes, but if your question is about how to change your cmake file to get the output you want, then it's not working as intended. \$\endgroup\$ – 200_success May 5 '16 at 21:10
  • \$\begingroup\$ Everything I posted is runnable and successful and I deleted the bracket about difference between Cmake and Make. Most people won't touch that question... \$\endgroup\$ – Niklas Rosencrantz May 5 '16 at 21:12
2
\$\begingroup\$

The documentation for CMake urges you not to use glob to detect every source file. The reasoning behind it is this: if you add a file it will not detect it. You will have to rerun CMake manually every time you add or remove source files.

If that is acceptable to you, then it is okay to use globbing, just be advised that it is generally not considered a good practice.

Your makefile explicitly listed the sources.

Typically, one uses set to set a variable, then uses that variable in add_executable

set(SHELL_SOURCES
    main.c
    errors.c
    util.c
)
...
add_executable(shell ${SHELL_SOURCES})

This is a good opportunity to point out that you can add more than just source code to that list. If you use CMake to generate a project for an IDE, you will usually want to add extra files that aren't really source, like TODO.txt, or glsl shaders that are only used at runtime. You can add those files to your sources list, and any non-compiled ones will be handled properly and only added to the project file when cmake configures a project. This way, those extra files will be convenient to open, just like the source files. For the same reason, you probably want to add your header files to the list as well. It won't affect compilation, but it will make them appear in an IDE when one generates a project.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.