The following tools can help you to build a C/C++ project on the command line[10] .
CL Use the compiler (cl.exe) to compile and link source code files into apps, libraries, and DLLs.
Link Use the linker (link.exe) to link compiled object files and libraries into apps and DLLs.
MSBuild (Visual C++) Use MSBuild (msbuild.exe) to build Visual C++ projects and Visual Studio solutions. This is equivalent to running the Build project or Build Solution command in the Visual Studio IDE.
DEVENV Use DEVENV (devenv.exe) combined with a command-line switch—for example, /Build or /Clean—to perform certain build commands without displaying the Visual Studio IDE.
NMAKE Use NMAKE (nmake.exe) to automate tasks that build Visual C++ projects by using a traditional makefile.
安装:
安装Visual Studio或Microsoft Visual C++ Build Tools。 我安装的是Visual Studio 2010 Express。
CL
cl.exe is a tool that controls the Microsoft Visual C++ (MSVC) C and C++ compilers and linker. The compilers produce Common Object File Format (COFF) object (.obj) files. The linker produces executable (.exe) files or dynamic-link libraries (DLLs).
cl编译器命令选项
C/C++ COMPILER OPTIONS
-CODE GENERATION-
/GF enable read-only string pooling /Gm[-] enable minimal rebuild
/Gy[-] separate functions for linker /GS[-] enable security checks
/GR[-] enable C++ RTTI /GX[-] enable C++ EH (same as /EHsc)
/EHs enable C++ EH (no SEH exceptions) /EHa enable C++ EH (w/ SEH exceptions)
/EHc extern "C" defaults to nothrow
/fp: choose floating-point model:
except[-] - consider floating-point exceptions when generating code
fast - "fast" floating-point model; results are less predictable
precise - "precise" floating-point model; results are predictable
strict - "strict" floating-point model (implies /fp:except)
/Qfast_transcendentals generate inline FP intrinsics even with /fp:except
/GL[-] enable link-time code generation /GA optimize for Windows Application
/Ge force stack checking for all funcs /Gs[num] control stack checking calls
/Gh enable _penter function call /GH enable _pexit function call
/GT generate fiber-safe TLS accesses /RTC1 Enable fast checks (/RTCsu)
/RTCc Convert to smaller type checks /RTCs Stack Frame runtime checking
/RTCu Uninitialized local usage checks
/clr[:option] compile for common language runtime, where option is:
pure - produce IL-only output file (no native executable code)
safe - produce IL-only verifiable output file
oldSyntax - accept the Managed Extensions syntax from Visual C++ 2002/2003
initialAppDomain - enable initial AppDomain behavior of Visual C++ 2002
noAssembly - do not produce an assembly
/Gd __cdecl calling convention /Gr __fastcall calling convention
/Gz __stdcall calling convention /GZ Enable stack checks (/RTCs)
/QIfist[-] use FIST instead of ftol()
/hotpatch ensure function padding for hotpatchable images
/arch: minimum CPU architecture requirements, one of:
SSE - enable use of instructions available with SSE enabled CPUs
SSE2 - enable use of instructions available with SSE2 enabled CPUs
AVX - enable use of Intel(R) Advanced Vector Extensions instructions
/Qimprecise_fwaits generate FWAITs only on "try" boundaries, not inside "try"
/Qsafe_fp_loads generate safe FP loads
-OUTPUT FILES-
/Fa[file] name assembly listing file /FA[scu] configure assembly listing
/Fd[file] name .PDB file /Fe name executable file
/Fm[file] name map file /Fo name object file
/Fp name precompiled header file /Fr[file] name source browser file
/FR[file] name extended .SBR file /Fi[file] name preprocessed file
/doc[file] process XML documentation comments and optionally name the .xdc file
-PREPROCESSOR-
/AI add to assembly search path /FU forced using assembly/module
/C don't strip comments /D{=|#} define macro
/E preprocess to stdout /EP preprocess to stdout, no #line
/P preprocess to file /Fx merge injected code to file
/FI name forced include file /U remove predefined macro
/u remove all predefined macros /I add to include search path
/X ignore "standard places"
-LANGUAGE-
/Zi enable debugging information /Z7 enable old-style debug info
/Zp[n] pack structs on n-byte boundary /Za disable extensions
/Ze enable extensions (default) /Zl omit default library name in .OBJ
/Zg generate function prototypes /Zs syntax check only
/vd{0|1|2} disable/enable vtordisp /vm type of pointers to members
/Zc:arg1[,arg2] C++ language conformance, where arguments can be:
forScope[-] - enforce Standard C++ for scoping rules
wchar_t[-] - wchar_t is the native type, not a typedef
auto[-] - enforce the new Standard C++ meaning for auto
trigraphs[-] - enable trigraphs (off by default)
/ZI enable Edit and Continue debug info
/openmp enable OpenMP 2.0 language extensions
-MISCELLANEOUS-
@ options response file /?, /help print this help message
/bigobj generate extended object format /c compile only, no link
/errorReport:option Report internal compiler errors to Microsoft
none - do not send report
prompt - prompt to immediately send report
queue - at next admin logon, prompt to send report (default)
send - send report automatically
/FC use full pathnames in diagnostics /H max external name length
/J default char type is unsigned
/MP[n] use up to 'n' processes for compilation
/nologo suppress copyright message /showIncludes show include file names
/Tc
2)启动cmd。 start -> app -> Microsoft Visual Studio 2010 Express -> Visual Studio Command Prompt (2010)
3)使用 cd 命令改变目录,进入源代码文件所在目录,例如d:\foo。
4)在cmd中输入命令 cl main.c,回车。
运行结果:
Setting environment for using Microsoft Visual Studio 2010 x86 tools.
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>d:
D:\>cd foo
D:\foo>cl main.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
main.obj
D:\foo>dir
Volume in drive D has no label.
Volume Serial Number is A8F3-9697
Directory of D:\foo\foo
08/31/2015 03:55 PM .
08/31/2015 03:55 PM ..
08/16/2015 09:13 AM 446 main.c
08/31/2015 03:55 PM 45,568 main.exe
08/31/2015 03:55 PM 1,452 main.obj
5 File(s) 118,150 bytes
2 Dir(s) 111,024,001,024 bytes free
D:\foo>main.exe
Hello, world.
D:\foo>
编译过程中可能出现的错误:
1) 链接错误:fatal error LNK1104: cannot open file 'kernel32.lib'
2) 链接错误:error LINK2005: "..." already defined in xxx.obj
错误处理: Adding static before the declaration of the variable or function
CL使用样例2
cl /EHsc hello.cpp
To compile a program that has multiple source code files, enter them all on the command line, like this:
cl /EHsc file1.cpp file2.cpp file3.cpp
When you supply multiple source files like this, the compiler uses the first input file to create the program name. In this case, it outputs a program called file1.exe. To change the name to program1.exe, add an /out linker option:
cl /EHsc file1.cpp file2.cpp file3.cpp /link /out:program1.exe
To catch more programming mistakes automatically, we recommend you compile by using either the /W3 or /W4 warning level option:
cl /W4 /EHsc file1.cpp file2.cpp file3.cpp /link /out:program1.exe
CL使用样例3 -- 生成汇编代码文件
cl /EHsc /FA foo.c
LINK
Link Options [3]
Option
Purpose
/ALIGN
Specifies the alignment of each section.
/ALLOWBIND
Specifies that a DLL cannot be bound.
/ALLOWISOLATION
Specifies behavior for manifest lookup.
/APPCONTAINER
Specifies whether the app must run within an appcontainer process environment.
/ASSEMBLYDEBUG
Adds the DebuggableAttribute to a managed image.
/ASSEMBLYLINKRESOURCE
Creates a link to a managed resource.
/ASSEMBLYMODULE
Specifies that a Microsoft intermediate language (MSIL) module should be imported into the assembly.
/ASSEMBLYRESOURCE
Embeds a managed resource file in an assembly.
/BASE
Sets a base address for the program.
/CGTHREADS
Sets number of cl.exe threads to use for optimization and code generation when link-time code generation is specified.
/CLRIMAGETYPE
Sets the type (IJW, pure, or safe) of a CLR image.
/CLRSUPPORTLASTERROR
Preserves the last error code of functions that are called through the P/Invoke mechanism.
/CLRTHREADATTRIBUTE
Specifies the threading attribute to apply to the entry point of your CLR program.
/CLRUNMANAGEDCODECHECK
Specifies whether the linker will apply the SuppressUnmanagedCodeSecurity attribute to linker-generated PInvoke stubs that call from managed code into native DLLs.
/DEBUG
Creates debugging information.
/DEBUGTYPE
Specifies which data to include in debugging information.
/DEF
Passes a module-definition (.def) file to the linker.
/DEFAULTLIB
Searches the specified library when external references are resolved.
/DELAY
Controls the delayed loading of DLLs.
/DELAYLOAD
Causes the delayed loading of the specified DLL.
/DELAYSIGN
Partially signs an assembly.
/DLL
Builds a DLL.
/DRIVER
Creates a kernel mode driver.
/DYNAMICBASE
Specifies whether to generate an executable image that can be randomly rebased at load time by using the address space layout randomization (ASLR) feature.
/ENTRY
Sets the starting address.
/errorReport
Reports internal linker errors to Microsoft.
/EXPORT
Exports a function.
/FIXED
Creates a program that can be loaded only at its preferred base address.
/FORCE
Forces a link to complete even with unresolved symbols or symbols defined more than once.
/FUNCTIONPADMIN
Creates an image that can be hot patched.
/GENPROFILE, /FASTGENPROFILE
Both of these options specify generation of a .pgd file by the linker to support profile-guided optimization (PGO). /GENPROFILE and /FASTGENPROFILE use different default parameters.
/GUARD
Enables Control Flow Guard protection.
/HEAP
Sets the size of the heap, in bytes.
/HIGHENTROPYVA
Specifies support for high-entropy 64-bit address space layout randomization (ASLR).
/IDLOUT
Specifies the name of the .idl file and other MIDL output files.
/IGNORE
Suppresses output of specified linker warnings.
/IGNOREIDL
Prevents the processing of attribute information into an .idl file.
/IMPLIB
Overrides the default import library name.
/INCLUDE
Forces symbol references.
/INCREMENTAL
Controls incremental linking.
/INTEGRITYCHECK
Specifies that the module requires a signature check at load time.
/KEYCONTAINER
Specifies a key container to sign an assembly.
/KEYFILE
Specifies a key or key pair to sign an assembly.
/LARGEADDRESSAWARE
Tells the compiler that the application supports addresses larger than two gigabytes
/LIBPATH
Specifies a path to search before the environmental library path.
/LTCG
Specifies link-time code generation.
/MACHINE
Specifies the target platform.
/MANIFEST
Creates a side-by-side manifest file and optionally embeds it in the binary.
/MANIFESTDEPENDENCY
Specifies a section in the manifest file.
/MANIFESTFILE
Changes the default name of the manifest file.
/MANIFESTINPUT
Specifies a manifest input file for the linker to process and embed in the binary. You can use this option multiple times to specify more than one manifest input file.
/MANIFESTUAC
Specifies whether User Account Control (UAC) information is embedded in the program manifest.
/MAP
Creates a mapfile.
/MAPINFO
Includes the specified information in the mapfile.
/MERGE
Combines sections.
/MIDL
Specifies MIDL command-line options.
/NOASSEMBLY
Suppresses the creation of a .NET Framework assembly.
/NODEFAULTLIB
Ignores all (or the specified) default libraries when external references are resolved.
/NOENTRY
Creates a resource-only DLL.
/NOLOGO
Suppresses the startup banner.
/NXCOMPAT
Marks an executable as verified to be compatible with the Windows Data Execution Prevention feature.
/OPT
Controls LINK optimizations.
/ORDER
Places COMDATs into the image in a predetermined order.
/OUT
Specifies the output file name.
/PDB
Creates a program database (PDB) file.
/PDBALTPATH
Uses an alternate location to save a PDB file.
/PDBSTRIPPED
Creates a program database (PDB) file that has no private symbols.
/PGD
Specifies a .pgd file for profile-guided optimizations.
/PROFILE
Produces an output file that can be used with the Performance Tools profiler.
/RELEASE
Sets the Checksum in the .exe header.
/SAFESEH
Specifies that the image will contain a table of safe exception handlers.
/SECTION
Overrides the attributes of a section.
/STACK
Sets the size of the stack in bytes.
/STUB
Attaches an MS-DOS stub program to a Win32 program.
/SUBSYSTEM
Tells the operating system how to run the .exe file.
/SWAPRUN
Tells the operating system to copy the linker output to a swap file before it is run.
/TLBID
Specifies the resource ID of the linker-generated type library.
/TLBOUT
Specifies the name of the .tlb file and other MIDL output files.
/TSAWARE
Creates an application that is designed specifically to run under Terminal Server.
/VERBOSE
Prints linker progress messages.
/VERSION
Assigns a version number.
/WINMD
Enables generation of a Windows Runtime Metadata file.
/WINMDFILE
Specifies the file name for the Windows Runtime Metadata (winmd) output file that's generated by the /WINMD linker option.
/WINMDKEYFILE
Specifies a key or key pair to sign a Windows Runtime Metadata file.
/WINMDKEYCONTAINER
Specifies a key container to sign a Windows Metadata file.
/WINMDDELAYSIGN
Partially signs a Windows Runtime Metadata (.winmd) file by placing the public key in the winmd file.
(The CL compiler automatically calls LINK unless you specify the /c option. CL provides some control over the linker through command-line options and arguments. The following table summarizes the features in CL that affect linking. )
Any file name extension other than .c, .cxx, .cpp, or .def
Passes a file name as input to LINK
filename.def
Passes /DEF:filename.def
/Fnumber
Passes /STACK:number
/Fdfilename
Passes /PDB:filename
/Fefilename
Passes /OUT:filename
/Fmfilename
Passes /MAP:filename
/Gy
Creates packaged functions (COMDATs); enables function-level linking
/LD
Passes /DLL
/LDd
Passes /DLL
/link
Passes remainder of command line to LINK
/MD or /MT
Places a default library name in the .obj file
/MDd or /MTd
Places a default library name in the .obj file. Defines the symbol _DEBUG
/nologo
Passes /NOLOGO
/Zd
Passes /DEBUG
/Zi or /Z7
Passes /DEBUG
/Zl
Omits default library name from .obj file
样例:
链接汇编代码
ml -nologo -c "foo.asm"
link /NOLOGO /SUBSYSTEM:CONSOLE kernel32.lib user32.lib "foo.obj"
NMAKE
C/C++ applications can be built on the command line by using nmake.exe (the Microsoft Program Maintenance Utility), which is "a command-line tool that builds projects based on commands that are contained in a description file"[9].The command-line toolset includes a compiler, linker, and other build tools, and a command file that sets the required build environment [10].
Forces a build of all evaluated targets, even if the targets are not out-of-date with respect to dependents. Does not force a build of unrelated targets.
/B
Forces a build even if the time stamps are equal. Recommended only for very fast systems with a resolution of two seconds or less.
/C
Suppresses default output, including nonfatal Nmake.exe errors or warnings, time stamps, and the Nmake.exe copyright message. Suppresses warnings issued by /K.
/D
Displays the time stamps of each evaluated target and dependent and a message when a target does not exist. Useful with /P for debugging a .mak file. Use !CMDSWITCHES to set or clear /D for part of a .mak file.
/E
Causes environment variables to override .mak file macro definitions.
/F
filename Specifies filename as a .mak file. Spaces or tabs can precede filename. Specify /F once for each .mak file. To supply a .mak file from standard input, specify a hyphen (-) for filename. To end keyboard input, press F6 or CTRL+Z.
/HELP, /?
Displays a brief summary of Nmake.exe command-line syntax.
/I
Ignores exit codes from all commands. To set or clear /I for part of a .mak file, use !CMDSWITCHES. To ignore exit codes for part of a .mak file, use a hyphen (-) command modifier or .IGNORE. Overrides /K if both are specified.
/K
Continues building unrelated dependencies, if a command returns an error. Also issues a warning and returns an exit code of 1. By default, Nmake.exe stops if any command returns a nonzero exit code. Warnings from /K are suppressed by /C. /I overrides /K if both are specified.
/N
Displays, but does not execute, commands. Preprocessing commands are executed. Does not display commands in recursive Nmake.exe calls. Useful for debugging .mak files and checking time stamps. To set or clear /N for part of a .mak file, use !CMDSWITCHES.
/NOLOGO
Suppresses the Nmake.exe copyright message.
/P
Displays information, such as macro definitions, inference rules, targets, and .SUFFIXES list, to standard output, and then runs the build. If no .mak file or command-line target exists, it displays information only. Use with /D to debug a .mak file.
/Q
Checks the time stamps of targets, but does not run the build. Returns a zero exit code if all targets are up-to-date and a nonzero exit code if any target is not up-to-date. Preprocessing commands are executed. Useful when running Nmake.exe from a batch file.
/R
Clears the .SUFFIXES list and ignores inference rules and macros that are defined in the Tools.ini file or that are predefined.
/S
Suppresses the display of executed commands. To suppress the display in part of a .mak file, use the @ command modifier or .SILENT. To set or clear /S for part of a .mak file, use !CMDSWITCHES.
/T
Updates the time stamps of command-line targets, or the first .mak file target, and executes preprocessing commands, but does not run the build.
/U
Must be used in conjunction with /N. Dumps inline Nmake.exe files so that the /N output can be used as a batch file.
/X
Sends Nmake.exe error output to filename instead of to a standard error output. Spaces or tabs can precede filename. To send standard error output, specify a hyphen (-) for filename. Does not affect output from commands to standard error output.
/Y
Disables batch-mode inference rules. When this option is selected, all batch-mode inference rules are treated as regular inference rules.
Makefile
Special characters
Special characters in NMAKE: : ; # ( ) $ ^ \ { } ! @ -
Description Blocks
A description block or inference rule specifies a block of commands to run if the dependency is out-of-date. NMAKE displays each command before running it, unless /S, .SILENT, !CMDSWITCHES, or @ is used. NMAKE looks for a matching inference rule if a description block is not followed by a commands block.
"A description block is a dependency line optionally followed by a commands blocks:"
targets ... : dependents ...
commands ...
A commands block contains one or more commands, each on its own line. No blank line can appear between the dependency or rule and the commands block. However, a line containing only spaces or tabs can appear; this line is interpreted as a null command, and no error occurs. Blank lines are permitted between command lines.
A command line begins with one or more spaces or tabs. A backslash ( \ ) followed by a newline character is interpreted as a space in the command; use a backslash at the end of a line to continue a command onto the next line. NMAKE interprets the backslash literally if any other character, including a space or tab, follows the backslash.
A command preceded by a semicolon (;) can appear on a dependency line or inference rule, whether or not a commands block follows:
To split the line, using backslash (\) after the target or dependent.
Targets
In a dependency line, specify one or more targets, using any valid filename, directory name, or pseudotarget. Separate multiple targets with one or more spaces or tabs. A target musts be at the start of the line. The target seperates from dependents by a colon (:), space or tabs are allowed.
Paths are permitted with filenames. A target cannot exceed 256 characters. If the target preceding the colon is a single character, use a separating space; otherwise, NMAKE interprets the letter-colon combination as a drive specifier
# Example Makefile for ArcEngine C++ Programming on Windows
#
# The PROGRAM macro defines the name of the program or project. It
# allows the program name to be changed by editing in only one
# location
#
PROGRAM = basic_sample
#
# Command line parameters: Edit these parameters so that you can
# easily run the sample by typing "nmake -f Makefile.Windows run".
#
# You will need to:
# (1) Describe parameters here. ex: IN_SHAPEFILE is the input shapefile
# (2) Define parameters below this comment box.
# ex: IN_SHAPEFILE = /mycomp/data/shapefile.shp
# (3) Add the parameters to the run target at the end of this file
# ex: ./$(PROGRAM) $(IN_SHAPEFILE)
#
#
# The INCLUDEDIRS macro contains a list of include directories
# to pass to the compiler so it can find necessary header files.
#
# The LIBDIRS macro contains a list of library directories
# to pass to the linker so it can find necessary libraries.
#
# The LIBS macro contains a list of libraries that the the
# executable must be linked against.
#
INCLUDEDIRS = \
/I "C:\Program Files\ArcGIS\include\CPPAPI" \
/I "C:\Program Files\ArcGIS\Com"
LIBDIRS =
LIBS =
#
# The CPPSOURCES macro contains a list of source files.
#
# The CPPOBJECTS macro converts the CPPSOURCES macro into a list
# of object files.
#
# The CPPFLAGS macro contains a list of options to be passed to
# the compiler. Adding "-g" to this line will cause the compiler
# to add debugging information to the executable.
#
# The CPP macro defines the C++ compiler.
#
# The LINKFLAGS macro contains all of the library and library
# directory information to be passed to the linker.
#
CPPSOURCES = basic_sample.cpp # list of source files
CPPOBJECTS = $(CPPSOURCES:.cpp=.obj) # expands to list of object files
CPPOPT = /EHsc /D_CRT_SECURE_NO_DEPRECATE
CPPFLAGS = -DESRI_WINDOWS $(INCLUDEDIRS) $(CPPOPT)
CPP = cl.exe
LINKFLAGS = $(LIBDIRS) $(LIBS)
#
# Default target: the first target is the default target.
# Just type "nmake -f Makefile.Windows" to build it.
#
all: $(PROGRAM)
#
# Link target: automatically builds its object dependencies before
# executing its link command.
#
$(PROGRAM): $(CPPOBJECTS)
link.exe /out:$(PROGRAM) $(CPPOBJECTS) $(LINKFLAGS)
#
# Object targets: rules that define objects, their dependencies, and
# a list of commands for compilation.
#
basic_sample.obj: basic_sample.cpp basic_sample.h
$(CPP) $(CPPFLAGS) /c basic_sample.cpp
#
# Clean target: "nmake -f Makefile.Windows clean" to remove unwanted objects and executables.
#
clean:
del $(CPPOBJECTS) $(PROGRAM)
#
# Run target: "nmake -f Makefile.Windows run" to execute the application
# You will need to add $(VARIABLE_NAME) for any command line parameters
# that you defined earlier in this file.
#
run:
$(PROGRAM)
VS nmake makefile 样例_3 [7]
# Makefile : Illustrates the effective use of precompiled
# headers in a project
# Usage: NMAKE option
# option: DEBUG=[0|1]
# (DEBUG not defined is equivalent to DEBUG=0)
#
OBJS = myapp.obj applib.obj
# List all stable header files in the STABLEHDRS macro.
STABLEHDRS = stable.h another.h
# List the final header file to be precompiled here:
BOUNDRY = stable.h
# List header files under development here:
UNSTABLEHDRS = unstable.h
# List all compiler options common to both debug and final
# versions of your code here:
CLFLAGS = /c /W3
# List all linker options common to both debug and final
# versions of your code here:
LINKFLAGS = /NOD /ONERROR:NOEXE
!IF "$(DEBUG)" == "1"
CLFLAGS = /D_DEBUG $(CLFLAGS) /Od /Zi /f
LINKFLAGS = $(LINKFLAGS) /COD
LIBS = slibce
!ELSE
CLFLAGS = $(CLFLAGS) /Oselg /Gs
LINKFLAGS = $(LINKFLAGS)
LIBS = slibce
!ENDIF
myapp.exe: $(OBJS)
link $(LINKFLAGS) @<<
$(OBJS), myapp, NUL, $(LIBS), NUL;
<<
# Compile myapp
myapp.obj : myapp.cpp $(UNSTABLEHDRS) stable.pch
$(CPP) $(CLFLAGS) /Yu$(BOUNDRY) myapp.cpp
# Compile applib
applib.obj : applib.cpp $(UNSTABLEHDRS) stable.pch
$(CPP) $(CLFLAGS) /Yu$(BOUNDRY) applib.cpp
# Compile headers
stable.pch : $(STABLEHDRS)
$(CPP) $(CLFLAGS) /Yc$(BOUNDRY) applib.cpp myapp.cpp
:>ml /coff /c /Cp h.asm
Microsoft (R) Macro Assembler Version 14.00.23506.0
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: h.asm
:>link /out:h.exe /SUBSYSTEM:CONSOLE msvcrt.lib kernel32.lib user32.lib h.obj
Microsoft (R) Incremental Linker Version 14.00.23506.0
Copyright (C) Microsoft Corporation. All rights reserved.
This article is from an interview with Zuhaib Siddique, a production engineer at HipChat, makers of group chat and IM for teams.
HipChat started in an unusual space, one you might not