I have an assembler file I want to compile in one run. However, the following code fails:
enable_language(ASM_NASM)
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -f bin")
add_executable(test test.s)
CMake first runs: nasm -f bin -o test.s.o test.s
And then: nasm -f bin -o test test.s.o
The last step fails as test.s.o is already a binary file.
My question is: How do I disable the first compilation step?
There seems to be a bug in nasm module for cmake. Cmake calls nasm for linking which is obviously wrong (that is why you see two calls to nasm). Hotfix is to set
set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld <FLAGS> <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
I hope you solved your problem, however I feel like I need to post here my solution just because that's the only mention of this problem and it doesn't seem to be solved by the only given answer.
Indeed, nasm can compile sources directly to .bin format (and that's really helpful for boot sectors). The problem is that Cmake doesn't seem to support single stage compilation and linking and it tries to link resulting .bin file, which is imposseible, so the execution fails no matter which linker we try to use.
The only solution that came to my mind was replacing add_executable(NAME SOURCE) with add_library(NAME OBJECT SOURCE). Object libraris are not linked, so the file produced will be exactly what we are looking for.
And here is the complete solution:
enable_language(ASM_NASM)
set(CMAKE_ASM_NASM_OBJECT_FORMAT bin)
add_compile_options("$<$<COMPILE_LANGUAGE:ASM_NASM>:-f bin>")
add_library(lib OBJECT core/boot/loader.asm)
The tricky part: the generated file will be hidden within cmake output dir. It sould be referenced with $<TARGET_OBJECTS:lib>.
Enjoy!
Related
The only online resources I have found are the CMake documentation on CMAKE_<LANG>_CPPLINT (link here) and this example (link here), but I cannot figure out how to actually use it inside a CMakeLists.txt file.
I tried the example provided, but I can't make it work. FYI, I installed cpplint as explained here.
As of now, I can run the cpplint python script inside CMakeLists.txt using this CMake command:
execute_process(COMMAND cpplint path/To/File/To/Analyse.cpp)
However, I am pretty sure that this is not the right way to do this.
Recommended way to use static analysis tools with CMake was presented in Daniel Pffeifer's "Effective Cmake" (https://www.youtube.com/watch?v=rLopVhns4Zs&=&t=77m13s).
You can either define it when calling cmake, eg.:
cmake "-DCMAKE_CXX_CPPLINT=cpplint" ..
or put it into CMakeLists.txt:
set(CMAKE_CXX_CPPLINT "cpplint")
Recommended option is the first one (we shouldn't define in a project what isn't a project requirement).
CMake will call cpplint for each file it compiles. You can pass extra arguments after semicolon (e.g. -DCMAKE_CXX_CPPLINT=cpplint;--linelength=100).
Downsides of this method:
Errors count will not get accumulated (because cpplint is invoked for each file separately).
It will not check header files (as opposed to what D. Pffeifer says in his presentation, include files are not being scanned by cpplint).
Note that you can use other static analysis tools the same way:
Clan Tidy "-DCMAKE_CXX_CLANG_TIDY=/usr/bin/clang-tidy-3.9;-checks=*"
CppCheck "-DCMAKE_CXX_CPPCHECK=/usr/bin/cppcheck;--std=c++11"
IWYU "-DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=/usr/bin/iwyu;--transitive_includes_only"
LWYU cmake -DCMAKE_LINK_WHAT_YOU_USE=TRUE
clazy
Some of them will require "compilation database" (set(CMAKE_EXPORT_COMPILE_COMMANDS ON)).
I failed to use CMAKE_<LANG>_CPPLINT to check code style.
I make it by using add_custom_target.
download cpplint.py
then download cpplint.cmake or write yourselt.
Suppose that there is a source code directory named src in your project, code those statements into your CMakeLists.txt.
aux_source_directory(${CMAKE_SOURCE_DIR}/src src)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}) #I put cpplint.cmake in $CMAKE_SOURCE_DIR
include(cpplint)
add_style_check_target(phoenix-cpplint "${src}")
Note:
you should pass the whole list, so use "${src}" instead of ${src}.
By default nothing depends on the custom target, see add_custom_target.
If there's still some problem, debug your CMakeLists.txt.
I have been struggling with the same problem.
I tried it with CMake 3.10.2 and the comment by user2449761 is still true. Using set(CMAKE_CXX_CPPLINT "cpplint") still does not check any header files.
The answer by kgbook does not work anymore, since aux_source_directory does not list the header files. You can, however, use
get_target_property(src staticcodecheck SOURCES)
That will give you all the non-system headers. The rest can be kept the same. As for running cpplint at a specific time, you might try
add_custom_command(TARGET ${TARGET}
PRE_BUILD
...
That will replace add_custom_target(${TARGET_NAME}... in his cpplint.cmake.
Hope this helps.
The following is how I am running cpplint on all files in the src directory for a project.
file(GLOB_RECURSE SRC_FILES "${PROJECT_SOURCE_DIR}/src/**/*")
add_custom_command(TARGET target PRE_BUILD COMMAND cpplint ${SRC_FILES})
This runs every time, it fails the build when there are cpplint issues, and it runs on all files in the src directory. You may also want to consider adding cpplint specific arguments to the command, such as --quiet or --extensions for example.
Edit: my question targets the early configure stage where CMake input files are still being parsed and thus have to be present before include() is being called. So the answer found here: Force CMake to generate configure_file target every build does not solve my problem since it generates files after include() statements have been interpreted.
I have a CMakeLists.txt that includes a file which is generated in the configure stage:
execute_process(COMMAND "my-generator -o generated.cmake")
include(generated.cmake)
Apart from the fact that this approach doesn't feel right (not to say elegant) I now need to re-generate that file before every build (my-generator produces output that incorporates the current time).
My assumption is that I can't use add_custom_command() or add_custom_target() because the file would be generated at compile time but needed in the configure-step.
This very old post suggests to touch the input file so I did this:
execute_process(
COMMAND "my-generator -o generated.cmake"
COMMAND cmake -E touch "${CMAKE_CURRENT_LIST_FILE}")
.. which does not produce errors but calling make multiple times won't run the configure step more than once.
What do I do wrong? Is there a better approach?
I've got my problem isolated to a very small two-sources project here: https://github.com/ennorehling/versioning/tree/v0.1
What I am trying to do is to not have a hard-coded version number in version.c, but to feed the version number into my build process from an external variable. See s/build for my build process: If $VERSION is defined, I want that to be the version number that the program prints. I achieve this by executing the command VERSION=1.2 s/build form the shell (or, if VERSION is undefined, by using the most recent tag from git).
The problem with this is that I run cmake .. -DVERSION=$VERSION every time I build, and that re-creates the Makefile, which causes a full rebuild. I would like to only rebuild version.o, since it is the only source file that depends on the version number. Building main.o (and in a real project, every other object, too) is unnecessary. I originally used add_definitions, which would add the -D compile switch to every source, and I thought set_source_files_properties was how I would be able to solve this, but since both object files are generated out of the same generated Makefile in build/CMakeFiles/version.dir/build.make, which gets touched by the cmake process. It seems that make errs on the safe side and just rebuilds everything?
Maybe I am barking up the wrong tree entirely, and just haven't found the correct CMake command for this, I don't know. Maybe there are other, proven ways to achieve what I'm trying to do? At this point, I've spent so much time on this, I'm not ashamed to ask for help.
I have found a way to work around this. The root problem here is that CMake create a Makefile for each library or executable target, and since my code only has one target, it was touching that Makefile every time. So the answer is to make a library target for version.c!
add_library(version OBJECT version.c)
add_executable(hello main.c $<TARGET_OBJECTS:version>)
this creates separate files in build/CMakeFiles/version.dir and build/CMakeFiles/hello.dir, and changes to the VERSION number only affect one of them, and the single target in it. The executable's dependencies are unchanged and don't get rebuilt, and only the linker step is executed, cutting down my build times as desired.
It's a bit clunky, but it works for me. New version of the project is here:
https://github.com/ennorehling/versioning/tree/v1.0
Edit: it turns out that Ubuntu Precise doesn't have CMake 2.8.8 yet, and the OBJECT option to add_library needs it. So instead, I have to actually create a library from that single object file and link it, like this:
add_library(version version.c)
add_executable(hello main.c)
target_link_libraries(hello version)
Not a huge deal, but a little annoying.
In your case you don't need to reconfigure every time. Once the make/build environment is written the problem can be reduced to a simple "has the file changed" problem that is checked by make itself.
So I probably would just generate the version.c inside your build script (and add this file to your .gitignore or alternatively directly generate it into the build directory):
s/build
#!/bin/sh
if [ -z "$VERSION" ]; then
VERSION=$(git describe --tags --match "v*.*")
if [ -z "$VERSION" ]; then
VERSION=1.0.0
fi
fi
echo "const char *version(void) { return \"${VERSION}\"; }" > version.c~
if cmake -E compare_files version.c~ version.c
then
cmake -E remove version.c~
else
cmake -E rename version.c~ version.c
fi
if ! [ -d build ]; then
cmake -E make_directory build
cmake -H. -Bbuild
fi
cmake --build build
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(version C)
add_executable(version version.c main.c)
version.c
const char *version(void) { return "1.0.0"; }
main.c
#include "stdio.h"
const char *version(void);
void main(void) {
puts(version());
}
This seems to be a bug in the CMake Unix Makefile generator. I tried your (original) code example using the Ninja generator, and ninja manages to avoid rebuilding main.c if you only change the version number.
I'm using CMake 2.8 in order to build an application based on MQX OS (using CodeWarrior).
The CMake project basically builds a set of static libraries (let's say LIB1 and LIB2).
I then reference these libraries in the final executable cmake rule:
target_add_executable(X ${some_sources})
target_link_libraries(X LIB1 LIB2)
My problem is that some symbols are defined in more that one library.
Thus, a link command like:
mwldarm <args> -o <output> <objects> /path/to1/libLIB1.a /path/to2/libLIB2.a
would lead to multiple definition of symbols error.
Instead, I would like CMake to generate a link command like:
mwldarm <args> -o <output> <objects> -L/path/to1 -L/path/to2 -lLIB -lLIB2
Question: How to get the following variables from CMAKE?
Libraries directories flags (ex: -L/path/to1 -L/path/to2)
Libraries link flags (ex: -lLIB -lLIB2)
I've read stuff concerning RPATH but it seems to concern shared libraries only. Am I right?
Thanks for advance.
I do appreciate.
It seems that policy CMP0003 may be what you need.
To use it add the following line near the beginning of your CMakeLists.txt:
CMAKE_POLICY( SET CMP0003 OLD )
Another possibility is to directly set the dependencies and search path, however it's not the cleanest way. Assuming you libraries are called liba.a and libb.a, then:
LINK_DIRECTORIES( ${paths_to_search_for} )
TARGET_ADD_EXECUTABLE(X ${some_sources} )
ADD_DEPENDENCIES(X LIB1 LIB2)
TARGET_LINK_LIBRARIES(X a b )
Note that in this case a and b are not cmake targets, therefore a little machinery is needed to correctly set the dependencies.
Part of the design of CMake is that it links with full paths. Why is that a problem?
Toggling the behavior with the policy is not the correct approach.
http://www.cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cd4fa896b
I think CMP0003 is used to switch on/off the function of adding searching path automatically as described in the official document
Libraries linked via full path no longer produce linker search paths.
rather than about replacing the path name with -l.
When linking a library, if the library is a target CMake known, CMake always replaces related -L and -l options with the library's path name. This may not be a problem for linking static libraries. But for a executable to link a shared library, it's may be a problem. Then I found a hacking method, code like below, to solve the problem linking a shread library using -L and `-l' rather than absolute path.
# Find out the link.txt
set(LINK_TXT "${CMAKE_BINARY_DIR}/${ToLinkLib}/CMakeFiles/${ToLinkLIb}.dir/link.txt")
# Add the searching path into link command
add_custom_command(TARGET ${YourTarget} PRE_BUILD
COMMAND sed ARGS -ie "\"s;[[:blank:]]-l; -L${LIBRARY_OUTPUT_PATH} -l;\"" ${LINK_TXT}
DEPENDS ${LINK_TXT}
COMMENT "Hacking CMake: edit __link.txt__ to use -l instead of path to link internal library ...")
# NOTE: Dont't missing the `-l'.
target_link_libraries(${YourTarget} -l${ToLinkLib})
Of course, this is just a hacking so may not be working well with all versions of CMake.
UPDATED: why linking a shared library may be a problem?
When I run a executable cross compiled for android, which linking a shared library built by the same CMake scripts, I've encounter a problem of linking failed. After I used the above hacking method to get a new version, I can run my executable with a command like below
$ LD_LIBRARY_PATH=. ./the_exe opts
I have a make file that contains this code:
all: main.o Etudiant.o
gcc -lobjc -o program main.o Etudiant.o
main.o:main.m Etudiant.h
gcc -c main.m
Etudiant.o:Etudiant.m Etudiant.h
gcc -c Etudiant.m
When I write this in the shell command:
$make
I got this:
make: **** No targets specified and no makefile found. Stop.
How do I fix this?
Mmm... makefiles. Whee.
All that whitespace at the beginning of the line. That has to be tabs. Or Make will barf up a really obscure error. Make sure those are tabs and try again.
See the button on the left side of the keyboard labeled "tab". Delete the spaces and hit that once to insert a tab character.
Try make all. IIRC (been a few years since I've had to muck with makefiles) most makes will default to all, but maybe yours isn't.
Extension doesn't matter.
Holy Heck! We are all Extra Dense(#bbum mostly so)!
"no Makefile found" means... well.. that Make didn't even see the makefile. The suggestions to rename the Makefile.m to Makefile are correct. As well, the whole tab vs. whitespace thing is certainly pertinent.
and no makefile found
If you just type make with no arguments or make all, make will look for a file called Makefile in the current directory. If it's not there, you get the error you saw. make will not look in subdirectories for Makefile nor will it accept a file called Makefile.m.
In my case, the my makefile had the name MakeFile, changing it to Makefile worked
Re:
$ Make
Make: * No targets specified and no makefile found. Stop.
I just had this error and found that the Makefile extension (none) had been converted to .bat somewhere along the line.
Just spent a few insanely frustrating moments with this error. My mistake was not all that subtle: I titled the makefile MakeFile not Makefile, so even using the -f Makefile command (forcing the makefile name) still resulted in not-found, because it was MakeFile, not Makefile.